2010-04-13 13 views
6

Ich bin neu in Codierung .. und ich habe eine Frage darüber, warum es Student gibt; nach der Klammer .. ist es ein Format, dem wir folgen müssen.Redundante Benennung in C/C++ typedefs/structs

+1

zu erhalten Das ist C, nicht C++. Sind Sie sicher, dass Sie sich auf die richtige Sprache beziehen? –

+5

C oder C++, kein Unterschied in diesem Beispiel. Suchen Sie nach Typedef auf Google oder in Ihren Büchern. –

+6

@gbrandt: Ja, aber es gibt keinen Grund, eine Struktur in C++ zu deklarieren. –

Antwort

0

Student ist der Name des neuen Typs, den typedef erstellt hat. StudentRec ist der Name der Struktur, die definiert wird.

13

Dies erstellt einen Typnamen "Student", um die Struktur zu bedeuten. Die Verwendung von typedef für diesen Zweck ist in C++ nicht erforderlich. Es könnte wie folgt definiert werden:

struct Student { 
    char lastname[NAMELEN]; 
    char firstname[NAMELEN]; 
    long int ID; 
    int finalmark; 
}; 
+1

In den meisten Fällen ist es unnötig, aber es gibt geringfügige Unterschiede zwischen der Definition der Struktur und der Typdefinition. Die Bezeichner befinden sich in verschiedenen Namensräumen (nicht im Sinne des Schlüsselwortes 'namespace' in C++). http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions/1675446#1675446 –

17

Sie sind zwei Dinge verwirrend. In C können Sie eine Struktur wie folgt definieren:

struct foo { 
    int a, b; 
}; 

Dann, eines zu verwenden, müssen Sie dies tun:

struct foo myFoo; 

Das ist wirklich wortreich, so sie hatte diese geniale Idee typedef der Verwendung zu machen ein neuer Typ. Ich kann so etwas tun:

typedef int myInt; 

und dann verwenden:

myInt x; 

Also, was Sie tun, ist zu erklären, dass es eine neue Art ist, Schüler, die auf eine Struktur äquivalent ist StudentRec . Vereinbarungsgemäß nutzen viele Menschen den gleichen Namen für die typedef wie für die Struktur - es ist legal:

typedef struct foo { int a, b; } foo; 
0

All dies gilt für C++. In C++ bevorzugen:

struct Foo 
{ 
    . . . 
}; 

Der Rest nur C gilt.

Technisch struct Foo {}; ist für die meisten Zwecke ausreichend. Es ist jedoch ein wenig wortreich zu verwenden, da struct jedes Mal wiederholt werden muss, wenn Typ Foo verwendet wird.

struct Foo {} 

void func(struct Foo* foo); 

Ein typedef macht dies einfacher.

typedef struct Foo { } Foo; 
void func(Foo* foo); 

Wenn dabei ein Motto, es ist auch möglich, diese Syntax zu verwenden:

struct Foo { }; 
typedef struct Foo Foo; 
void func(Foo* foo); 

Dies kann weiter mit verkürzt werden

typedef struct { } Foo; 
void func(Foo* foo); 

Dies ist eine anonyme struct und dann die Schaffung geben es ist der Name Foo. Sie sehen dies am häufigsten mit enum s.

Es gibt einen Grund, warum das anfängliche redundante Foo normalerweise dort gelassen wird. Es ist nur eine Möglichkeit, eine selbstreferenzierende Struktur wie eine verknüpfte Liste zu erstellen.

typedef struct Node 
{ 
    Node* next; 
} Node; 

Wenn die anfänglichen Node wo ommited gäbe es keine Möglichkeit, einen Zeiger auf die Struktur zu erklären. Technisch ist das auch so, aber jetzt müssen Sie sich 2 Namen ausdenken, anstatt nur einen.

typedef struct node_ 
{ 
    node_* next; 
} Node; 

Warum Gebrauch:

typedef struct Foo { } Foo; 

Für Einheitlichkeit. Dieser Deklarationsstil deckt alle Ihre Bases ab, so dass Sie nie darüber nachdenken müssen, wenn Sie eine Struktur deklarieren.

4

In C gibt es verschiedene Namespaces für Struct-Namen und Typnamen (wie int) {der Typ-Namespace wird gemeinsam mit dem Namespace für Variablen und Funktionen verwendet, beachten Sie also}. Wenn Sie eine neue Struktur definieren, fügen Sie dem Struktur-Namespace automatisch seinen Namen hinzu, aber wenn Sie eine Variable dieses Typs deklarieren, müssen Sie ihrem Namen struct vorangestellt haben, damit der Compiler im Struktur-Namespace nachsehen kann, was genau er ist dass diese Variable sein soll.

Mithilfe des Schlüsselworts typedef können Sie dem Typnamespace einen Namen für die Variable hinzufügen, sodass Sie das Schlüsselwort struct nicht in Ihren Deklarationen verwenden müssen.

Das Beispiel, das Sie gaben, kombinierte die Deklaration typedef mit der Strukturdefinition, verwendete jedoch unterschiedliche Namen für die Struktur im Typnamespace und im Namespace der Struktur. Sie können dies aus zwei Gründen tun. Erstens, das Voranstellen einer Anweisung, die genau wie eine Variablendeklaration mit typedef aussieht, definiert einen Typnamen anstelle einer Variablen mit dem angegebenen Namen. Zweitens können Sie Variablen eines Strukturtyps deklarieren, indem Sie ihre Namen unmittelbar nach der Strukturdeklaration und dem Semikolon einfügen. Ihr Beispiel kombiniert diese.

Es gibt auch andere Rechtsformen dieses in C. Zum Beispiel:

/* This declares a variable foo whose type has no name but is a struct that contains one int named x */ 
struct { 
    int x; 
} foo; 

/* This adds bar to the type namespace without adding an entry to the struct namespace. */ 
typedef struct { 
    int y; 
} bar; 

/* This adds the name baz to the struct namespace and declares a variable named b of this type */ 
struct baz { 
    int z; 
} b; 

/* This adds the name ralf to the type namespace which also refers to this type */ 
typedef struct baz ralf; 

C++ andere Namespace-Struktur hat, die ich bin sicher, dass Sie bemerkt haben, da sie den Namespace Schlüsselwort haben. In diesem Fall ist C++ jedoch einfacher als C. Das Definieren einer Struktur (oder einer Klasse oder Union oder Enumeration) fügt automatisch den Namen hinzu, den Sie (falls vorhanden) zum Namensraum verwendet haben, dem typedef Namen hinzufügt. Das vereinfacht die Dinge größtenteils sehr, aber es gibt ein paar Fehler. Diese haben meistens damit zu tun, die Abwärtskompatibilität zu C beizubehalten. Meistens hat diese Kompatibilität damit zu tun, zu bemerken, wenn jemand typedefs struct foo foo; und es nicht als Fehler behandelt, etwas mit einem bereits verwendeten Namen zu benennen.

Ein weiteres Problem kommt mit dieser Art von ziemlich häufig C-Code auf:

struct shoe { 
    int size; 
} shoe; 

Dies ist üblich in C insbesondere dann, wenn nur einer von einer Struktur vorhanden sein muss. In C wäre dies einfach, da es keine Kollision zwischen den Namen der struct shoe und der Variablen shoe geben würde. In C++ funktioniert dies immer noch, um Abwärtskompatibilität mit C.