variable uso example define c struct typedef

uso - typedef struct vs struct definiciones



typedef struct uso (12)

Con el último ejemplo, omite la palabra clave struct al usar la estructura. Así que en cualquier parte de tu código, puedes escribir:

myStruct a;

en lugar de

struct myStruct a;

Esto ahorra algo de escritura, y puede ser más legible, pero es una cuestión de gusto.

Esta pregunta ya tiene una respuesta aquí:

Soy un principiante en la programación en C, pero me preguntaba cuál es la diferencia entre usar typedef al definir una estructura y no usar typedef. Me parece que realmente no hay diferencia, logran lo mismo.

struct myStruct{ int one; int two; };

contra

typedef struct{ int one; int two; }myStruct;


El typedef , al igual que con otras construcciones, se utiliza para dar un nuevo nombre a un tipo de datos. En este caso, se realiza principalmente para que el código sea más limpio:

struct myStruct blah;

contra

myStruct blah;


El lenguaje común está utilizando ambos:

typedef struct X { int x; } X;

Son definiciones diferentes. Para aclarar la discusión, dividiré la oración:

struct S { int x; }; typedef struct S S;

En la primera línea está definiendo el identificador S dentro del espacio de nombre de la estructura (no en el sentido de C ++). Puede usarlo y definir variables o argumentos de función del tipo recién definido definiendo el tipo del argumento como struct S :

void f( struct S argument ); // struct is required here

La segunda línea agrega un alias de tipo S en el espacio de nombres global y, por lo tanto, le permite escribir:

void f( S argument ); // struct keyword no longer needed

Tenga en cuenta que dado que ambos espacios de nombre de identificador son diferentes, definir S tanto en las estructuras como en los espacios globales no es un error, ya que no está redefiniendo el mismo identificador, sino que crea un identificador diferente en un lugar diferente.

Para hacer más clara la diferencia:

typedef struct S { int x; } T; void S() { } // correct //void T() {} // error: symbol T already defined as an alias to ''struct S''

Puede definir una función con el mismo nombre de la estructura, ya que los identificadores se mantienen en espacios diferentes, pero no puede definir una función con el mismo nombre que typedef ya que esos identificadores chocan.

En C ++, es ligeramente diferente ya que las reglas para localizar un símbolo han cambiado sutilmente. C ++ aún conserva los dos espacios de identificador diferentes, pero a diferencia de C, cuando solo define el símbolo dentro del espacio de identificador de clase, no es necesario que proporcione la palabra clave struct / class:

// C++ struct S { int x; }; // S defined as a class void f( S a ); // correct: struct is optional

¿Qué cambios son las reglas de búsqueda, no donde se definen los identificadores? El compilador buscará la tabla de identificadores globales y, después de que no se haya encontrado S , buscará S dentro de los identificadores de clase.

El código presentado anteriormente se comporta de la misma manera:

typedef struct S { int x; } T; void S() {} // correct [*] //void T() {} // error: symbol T already defined as an alias to ''struct S''

Después de la definición de la función S en la segunda línea, la estructura S no puede ser resuelta automáticamente por el compilador, y para crear un objeto o definir un argumento de ese tipo, debe volver a incluir la palabra clave de struct :

// previous code here... int main() { S(); struct S s; }


El siguiente código crea una estructura anónima con el alias myStruct :

typedef struct{ int one; int two; } myStruct;

No puede referirlo sin el alias porque no especifica un identificador para la estructura.


En C (no en C ++), debe declarar variables de estructura como:

struct myStruct myVariable;

Para poder utilizar myStruct myVariable; en su lugar, puede typedef la estructura:

typedef struct myStruct someStruct; someStruct myVariable;

Puede combinar la definición de struct y la definición de tipo en una sola declaración que declara una struct anónima y la definición de tipo.

typedef struct { ... } myStruct;


En C, las palabras clave especificadoras de tipo de estructuras, uniones y enumeración son obligatorias, es decir, siempre tiene que prefijar el nombre del tipo (su etiqueta ) con struct , union o enum cuando se hace referencia al tipo.

Puede deshacerse de las palabras clave utilizando typedef , que es una forma de ocultación de información, ya que el tipo real de un objeto ya no será visible al declararlo.

Por lo tanto, se recomienda (consulte, por ejemplo, la guía de estilo de codificación del kernel de Linux , Capítulo 5) que solo haga esto cuando realmente desee ocultar esta información y no solo guardar algunas pulsaciones de teclas.

Un ejemplo de cuándo debería usar typedef sería un tipo opaco que solo se usa con las funciones de acceso / macros correspondientes.


La diferencia entra cuando usas la struct .

La primera manera que tienes que hacer:

struct myStruct aName;

La segunda forma le permite eliminar la struct palabras clave.

myStruct aName;


No se puede utilizar la declaración hacia adelante con la typedef struct .

La struct sí es un tipo anónimo, por lo que no tiene un nombre real para reenviar declarar.

typedef struct{ int one; int two; } myStruct;

Una declaración hacia adelante como esta no funcionará:

struct myStruct; //forward declaration fails void blah(myStruct* pStruct); //error C2371: ''myStruct'' : redefinition; different basic types


Otra diferencia que no se señala es que darle un nombre a la estructura (es decir, struct myStruct) también le permite proporcionar declaraciones de la estructura hacia adelante. Así que en algún otro archivo, podrías escribir:

struct myStruct; void doit(struct myStruct *ptr);

Sin necesidad de tener acceso a la definición. Lo que te recomiendo es que combines tus dos ejemplos:

typedef struct myStruct{ int one; int two; } myStruct;

Esto le brinda la comodidad del nombre typedef más conciso, pero aún así le permite usar el nombre completo de la estructura si lo necesita.


Si usas struct sin typedef , siempre tendrás que escribir

struct mystruct myvar;

Es ilegal escribir

mystruct myvar;

Si usas typedef ya no necesitas el prefijo de struct .


Veo que hay alguna aclaración en orden sobre esto. C y C ++ no definen tipos de manera diferente. C ++ originalmente no era más que un conjunto adicional de inclusión encima de C.

El problema que prácticamente todos los desarrolladores de C / C ++ tienen hoy en día es que a) las universidades ya no enseñan los fundamentos, yb) las personas no entienden la diferencia entre una definición y una declaración.

La única razón por la que existen tales declaraciones y definiciones es para que el vinculador pueda calcular las compensaciones de dirección a los campos en la estructura. Esta es la razón por la que la mayoría de las personas se salen con un código que realmente está escrito incorrectamente, porque el compilador puede determinar el direccionamiento. El problema surge cuando alguien intenta hacer algo por adelantado, como una cola o una lista enlazada, o hacer una copia de seguridad de una estructura O / S.

Una declaración comienza con ''struct'', una definición comienza con ''typedef''.

Además, una estructura tiene una etiqueta de declaración directa y una etiqueta definida. La mayoría de las personas no lo saben y utilizan la etiqueta de declaración directa como una etiqueta de definición.

Incorrecto:

struct myStruct { int field_1; ... };

Acaban de usar la declaración hacia adelante para etiquetar la estructura, por lo que ahora el compilador es consciente de ello, pero no es un tipo definido real. El compilador puede calcular el direccionamiento, pero esta no es la forma en que se pretendía utilizar, por razones que mostraré momentáneamente.

Las personas que usan esta forma de declaración, siempre deben poner ''struct'' en prácticamente todas las referencias a ella, porque no es un tipo nuevo oficial.

En cambio, cualquier estructura que no haga referencia a sí misma, debe declararse y definirse de esta manera solamente:

typedef struct { field_1; ... }myStruct;

Ahora es un tipo real, y cuando se usa puede usar at ''myStruct'' sin tener que añadirlo con la palabra ''struct''.

Si desea una variable de puntero a esa estructura, incluya una etiqueta secundaria:

typedef struct { field_1; ... }myStruct,*myStructP;

Ahora tienes una variable de puntero a esa estructura, personalizada a ella.

DECLARACIÓN ADELANTE--

Ahora, aquí están las cosas elegantes, cómo funciona la declaración directa. Si desea crear un tipo que se refiera a sí mismo, como una lista vinculada o un elemento de cola, debe usar una declaración de reenvío. El compilador no considera la estructura definida hasta que llega al punto y coma al final, por lo que se declara antes de ese punto.

typedef struct myStructElement { myStructElement* nextSE; field_1; ... }myStruct;

Ahora, el compilador sabe que aunque todavía no sabe cuál es el tipo completo, todavía puede hacer referencia a él utilizando la referencia directa.

Por favor declare y tipifique sus estructuras correctamente. En realidad hay una razón.


struct y typedef son dos cosas muy diferentes.

La palabra clave struct se utiliza para definir o referirse a un tipo de estructura. Por ejemplo, esto:

struct foo { int n; };

crea un nuevo tipo llamado struct foo . El nombre foo es una etiqueta ; es significativo solo cuando está precedido inmediatamente por la palabra clave struct , porque las etiquetas y otros identificadores están en espacios de nombres distintos. (Esto es similar, pero mucho más restringido que, el concepto de C ++ de namespace de namespace s).

Un typedef , a pesar del nombre, no define un nuevo tipo; simplemente crea un nuevo nombre para un tipo existente. Por ejemplo, dado:

typedef int my_int;

my_int es un nombre nuevo para int ; my_int e int son exactamente del mismo tipo. Del mismo modo, dada la definición de struct anterior, puede escribir:

typedef struct foo foo;

El tipo ya tiene un nombre, struct foo . La declaración typedef le da al mismo tipo un nuevo nombre, foo .

La sintaxis le permite combinar una struct y typedef en una sola declaración:

typedef struct bar { int n; } bar;

Este es un idioma común. Ahora puede referirse a este tipo de estructura como struct bar o simplemente como bar .

Tenga en cuenta que el nombre typedef no se vuelve visible hasta el final de la declaración. Si la estructura contiene un puntero a sí mismo, debe usar la versión de struct para referirse a ella:

typedef struct node { int data; struct node *next; /* can''t use just "node *next" here */ } node;

Algunos programadores usarán identificadores distintos para la etiqueta de estructura y para el nombre typedef. En mi opinión, no hay una buena razón para eso; usar el mismo nombre es perfectamente legal y deja claro que son del mismo tipo. Si debe usar identificadores diferentes, al menos use una convención consistente:

typedef struct node_s { /* ... */ } node;

(Personalmente, prefiero omitir typedef y referirme al tipo como struct bar . El typedef guarda un poco de escritura, pero oculta el hecho de que es un tipo de estructura. Si desea que el tipo sea opaco, esto puede ser una buena opción. Si el código del cliente se va a referir al miembro n por su nombre, entonces no es opaco; es visiblemente una estructura, y en mi opinión, tiene sentido referirse a él como una estructura. Pero muchos programadores inteligentes no están de acuerdo conmigo en este punto. Esté preparado para leer y entender el código escrito de cualquier manera.)

(C ++ tiene reglas diferentes. Dada una declaración de struct blah , puede referirse al tipo simplemente como blah , incluso sin typedef. El uso de typedef puede hacer que su código C sea un poco más parecido a C ++, si usted considera que es una buena opción. cosa.)