2010-04-13 16 views
6
#include <stdio.h> 
#include <string.h> 

const int NAMELEN=30; 

const int MAXCLASSSIZE=10; 

typedef struct StudentRec { 
    char lastname[NAMELEN]; 
    char firstname[NAMELEN]; 
    long int ID; 
    int finalmark; 
}Student; 

Sono nuovo alla codifica e ho una domanda sul motivo per cui esiste uno Studente; dopo la parentesi .. è un formato che dobbiamo seguire.Denominazione ridondante in typedef/structs C/C++

+1

Ecco C, C++ non è. Sei sicuro di fare riferimento alla lingua giusta? –

+5

C o C++, nessuna differenza in questo esempio. Cerca typedef su google o nei tuoi libri. –

+6

@gbrandt: Sì, ma non c'è motivo di dichiarare una struttura in questo modo in C++. –

risposta

0

Studente è il nome del nuovo tipo creato dal typedef. StudentRec è il nome della struttura che definisce.

13

Questo sta creando un nome tipografico "Studente" per indicare la struttura. L'utilizzo di typedef per questo scopo non è necessario in C++. Potrebbe essere definito in questo modo:

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

Nella maggior parte dei casi non è necessario, ma ci sono lievi differenze tra la definizione della struttura e la digitazione. Gli identificatori risiedono in diversi spazi dei nomi (non nel senso della parola chiave 'namespace' in C++). http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions/1675446#1675446 –

17

si confondono due cose. In C è possibile definire una struttura come questa:

struct foo { 
    int a, b; 
}; 

quindi di utilizzare quello che si deve fare questo:

struct foo myFoo; 

Questo è davvero prolisso, così hanno dovuto questa brillante idea di utilizzare typedef per rendere un nuovo tipo Posso fare qualcosa di simile:

typedef int myInt; 

e poi usarlo:

myInt x; 

Quindi quello che stai facendo sta dichiarando che non v'è un nuovo tipo, Student, che equivale a una struct StudentRec . Per convenzione, molte persone usano lo stesso nome per il typedef come per lo struct - è legale:

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

Niente di tutto questo vale per C++. In C++ preferiscono:

struct Foo 
{ 
    . . . 
}; 

Il resto si applica solo ai C.

Tecnicamente struct Foo {}; è sufficiente per la maggior parte degli scopi. Tuttavia è un po 'prolisso da utilizzare come struct deve essere ripetuto ogni volta che si usa il tipo Foo.

struct Foo {} 

void func(struct Foo* foo); 

Un typedef rende questo più semplice.

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

Questo può essere ulteriormente accorciato con:

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

Quando si effettua un uno di linea è anche possibile utilizzare la seguente sintassi:

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

Questa è la creazione di un anonimo struct e poi dare è il nome Foo. Lo vedi più spesso con enum s.

typedef enum { } Bar; 

C'è una ragione per cui il licenziamento ridondante iniziale viene di solito lasciato lì. È solo un modo per creare una struttura autoreferenziale, come una lista collegata.

typedef struct Node 
{ 
    Node* next; 
} Node; 

Se l'iniziale Node dove ommited non ci sarebbe alcun modo per dichiarare un puntatore alla struttura. Tecnicamente vale anche questo, ma ora devi inventare 2 nomi, invece di uno solo.

typedef struct node_ 
{ 
    node_* next; 
} Node; 

Allora, perché l'uso:

typedef struct Foo { } Foo; 

Per uniformità. Questo stile di dichiarazione copre tutte le basi, quindi non devi mai pensarci quando dichiari una struttura.

4

In C ci sono diversi spazi dei nomi per nomi di struct e nomi di tipo (come int) {il namespace di tipo è condiviso con la variabile e lo spazio dei nomi di funzione, quindi sii consapevole di ciò}. Quando si definisce una nuova struttura, si aggiunge automaticamente il nome allo spazio dei nomi struct, ma quando si dichiara una variabile di quel tipo è necessario precedere il suo nome con struct in modo che il compilatore sappia cercare nello spazio dei nomi struct per vedere che cos'è esattamente che vuoi che questa variabile sia.

Utilizzando la parola chiave typedef è possibile aggiungere un nome per la variabile allo spazio dei nomi tipo in modo da non dover utilizzare la parola chiave struct nelle dichiarazioni.

L'esempio che ha dato combinato la dichiarazione typedef con la definizione struct, ma abbiamo usato nomi diversi per la struct nel tipo namespace e lo spazio dei nomi struct. Sei in grado di farlo per due motivi. Innanzitutto, il prefisso di un'istruzione che assomiglia esattamente a una dichiarazione di variabile con typedef definisce un typename invece di una variabile con il nome specificato. In secondo luogo, è possibile dichiarare le variabili di un tipo di struct includendo i loro nomi immediatamente dopo la struct declaration e il punto e virgola. Il tuo esempio li ha combinati.

Ci sono altre forme giuridiche di questo in C. Per esempio:

/* 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++ ha diversa struttura dello spazio dei nomi, che sono sicuro che avete notato dal momento che ha la parola chiave namespace. In questo caso però C++ è più semplice di C. La definizione di una struct (o di una classe o unione o enum) aggiunge automaticamente il nome che hai usato (se esiste) allo spazio dei nomi a cui typedef aggiunge i nomi. Questo semplifica notevolmente le cose, per la maggior parte, ma ci sono alcuni trucchi. Questi hanno per lo più a che fare con conservando la compatibilità con C. Per lo più questa compatibilità ha a che fare con accorga quando qualcuno typedefs struct foo foo; e non trattarlo come un errore di cercare di nominare qualcosa con un nome già utilizzato.

Un altro problema si presenta con questo tipo di codice abbastanza comune C:

struct shoe { 
    int size; 
} shoe; 

Questo è comune in C particolare quando solo uno di una struttura deve esistere. In C questo sarebbe facile perché non ci sarebbe alcuna collisione tra i nomi dello struct shoe e la variabile shoe. In C++ questo funziona ancora anche se per mantenere la compatibilità con C.