2010-04-13 18 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; 

Soy nuevo en la codificación ... y tengo una pregunta acerca de por qué hay Estudiantes; después del paréntesis ... ¿es un formato que tenemos que seguir?Nombramiento redundante en C/C++ typedefs/structs

+1

Eso es C, no C++. ¿Seguro que te estás refiriendo al idioma correcto? –

+5

C o C++, no hay diferencia en este ejemplo. Busque typedef en google o en sus libros. –

+6

@gbrandt: Sí, pero no hay ninguna razón para declarar una estructura de esa manera en C++. –

Respuesta

0

Estudiante es el nombre del nuevo tipo que ha creado typedef. StudentRec es el nombre de la estructura que define.

13

Esto está creando un nombre de tipo "Estudiante" para significar la estructura. Usar typedef para este propósito no es necesario en C++. Podría definirse así:

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

En la mayoría de los casos no es necesario, pero hay ligeras diferencias entre la definición de struct y typedef-ing it. Los identificadores residen en diferentes espacios de nombres (no en el sentido de la palabra clave 'namespace' en C++). http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions/1675446#1675446 –

17

usted está confundiendo dos cosas. En C se puede definir una estructura como esta:

struct foo { 
    int a, b; 
}; 

A continuación, utilizar uno que tiene que hacer esto:

struct foo myFoo; 

Esto es muy prolijo, por lo que tuvo esta brillante idea de usar typedef para hacer un nuevo tipo. Puedo hacer algo como esto:

typedef int myInt; 

y luego usarlo:

myInt x; 

Así que lo que estás haciendo está declarando que hay un nuevo tipo, los estudiantes, lo que equivale a una estructura StudentRec . Por convención, muchas personas utilizan el mismo nombre para el typedef struct como para el - es legal:

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

Nada de esto se aplica a C++. En C++ prefieren:

struct Foo 
{ 
    . . . 
}; 

El resto sólo se aplica a C.

Técnicamente struct Foo {}; es suficiente para la mayoría de los propósitos. Sin embargo, es un poco detallado para usar como struct debe repetirse cada vez que se utiliza el tipo Foo.

struct Foo {} 

void func(struct Foo* foo); 

typedef lo hace más simple.

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

Esto se puede acortar aún más con:

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

Al hacer un chiste también es posible utilizar esta sintaxis:

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

Esto está creando un anónimo struct y luego dando es el nombre Foo. Esto se ve más a menudo con enum s.

typedef enum { } Bar; 

Existe una razón por la cual el Foo redundante inicial generalmente se deja allí. Es solo la única forma de crear una estructura de autorreferencia, como una lista vinculada.

typedef struct Node 
{ 
    Node* next; 
} Node; 

Si la inicial Node donde omite, no habría manera de declarar un puntero a la estructura. Técnicamente, esto también es válido, pero ahora tienes que encontrar dos nombres, en lugar de solo uno.

typedef struct node_ 
{ 
    node_* next; 
} Node; 

Entonces, ¿por uso:

typedef struct Foo { } Foo; 

Para uniformidad. Este estilo de declaración cubre todas sus bases, por lo que nunca tendrá que pensar al declarar una estructura.

4

En C hay diferentes espacios de nombres para nombres de estructuras y nombres de tipos (como int) {el espacio de nombres de tipo se comparte con la variable y el espacio de nombres de funciones, así que tenga en cuenta que}. Cuando define una nueva estructura, automáticamente agrega su nombre al espacio de nombres de la estructura, pero cuando declara una variable de ese tipo debe preceder su nombre con struct para que el compilador sepa buscar en el espacio de nombres de la estructura para ver exactamente qué es que quieres que esta variable sea

Usando la palabra clave typedef puede agregar un nombre para la variable al espacio de nombres de tipo para que no tenga que usar la palabra clave struct en sus declaraciones.

El ejemplo que usted dio combinó la declaración typedef con la definición de estructura, pero usó diferentes nombres para la estructura en el espacio de nombres de tipo y el espacio de nombres struct. Usted puede hacer esto por dos razones. En primer lugar, el prefijo de una declaración que se ve exactamente como una declaración de variable con typedef define un nombre de tipo en lugar de una variable con el nombre especificado. En segundo lugar, puede declarar variables de un tipo de estructura incluyendo sus nombres inmediatamente después de la declaración de estructura y el punto y coma. Tu ejemplo combinó estos.

hay otras formas legales de este en C. Por ejemplo:

/* 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++ tiene una estructura diferente espacio de nombres, que estoy seguro que usted ha notado ya que tiene la palabra clave namespace. En esta instancia, aunque C++ es más simple que C. Al definir una estructura (o clase o unión o enumeración) automáticamente se agrega el nombre que usaste (si existe) al espacio de nombres al que typedef agrega nombres. Esto simplifica las cosas en gran medida, en su mayor parte, pero hay algunos inconvenientes. En su mayoría tienen que ver con la retención de la compatibilidad con versiones anteriores de C. Principalmente, esta compatibilidad tiene que ver con notar cuando alguien typedefs struct foo foo; y no tratarlo como un error al tratar de nombrar algo con un nombre ya usado.

Otro problema surge con este tipo de código C bastante común:

struct shoe { 
    int size; 
} shoe; 

Esto es común en C sobre todo cuando sólo uno de una estructura debe existir. En C esto sería fácil porque no habría colisión entre los nombres de struct shoe y la variable shoe. En C++ esto aún funciona para mantener la compatibilidad con C.