typedef struct vs struct definiciones [duplicate]

9 minutos de lectura

avatar de usuario
usuario69514

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

struct myStruct{
    int one;
    int two;
};

contra

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

  • Acabo de leer, aquí en SO, que la segunda opción daría un error de compilación. “pasar argumento de tipo de puntero incompatible” stackoverflow.com/questions/12708897/…

    – él Wi

    18 de diciembre de 2015 a las 16:10

  • Una mejor respuesta (en mi opinión) se puede encontrar aquí.

    – Meysam Sadeghi

    29 de agosto de 2019 a las 9:35


avatar de usuario
keith thompson

struct y typedef son dos cosas muy diferentes.

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

struct foo {
    int n;
};

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

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 nuevo nombre para int; my_int y int son exactamente el mismo tipo Del mismo modo, dada la struct definición anterior, puede escribir:

typedef struct foo foo;

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

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

typedef struct bar {
    int n;
} bar;

Este es un modismo 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, tiene que utilizar el struct versión 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 de typedef. En mi opinión, no hay una buena razón para eso; usar el mismo nombre es perfectamente legal y deja más 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 el typedef y referirse al tipo como struct bar. Él typedef ahorra 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 algo bueno. Si el código del cliente se va a referir al miembro n por nombre, entonces no es opaco; es visiblemente una estructura, y en mi opinión tiene sentido referirse a ella como una estructura. Pero muchos programadores inteligentes no están de acuerdo conmigo en este punto. Esté preparado para leer y comprender el código escrito de cualquier manera).

(C++ tiene reglas diferentes. Dada una declaración de struct blahpuede referirse al tipo como simplemente blah, incluso sin un typedef. Usar un typedef podría hacer que su código C se parezca un poco más a C++, si cree que es algo bueno).

  • Esta respuesta me ayudó a comprender mejor por qué es más probable que las bibliotecas C89 y el kernel de Linux usen struct mystruct_t {} en vez de typedef struct {} mystruct_t.

    – Josh Sanford

    25 de julio de 2016 a las 13:05

  • @KeithThompson Buena respuesta +1. Personalmente, me gustaría saber por qué o por qué no omitir la etiqueta de estructura al usar typedef, como lo hizo el OP en su pregunta: typedef struct{ int one; int two; }myStruct;. Alguien dice que se debe a la declaración de reenvío, pero en este comentario, otro usuario dijo que esto también es posible con typedefs. ¿Hay alguna razón para no omitirlo?

    – RobertS apoya a Mónica Cellio

    9 de febrero de 2020 a las 19:09


  • Una cosa más: ¿No quisiste decir “Usar un typedef podría hacer que su código C++ sea un poco más parecido a C” en vez de “Usar un typedef podría hacer que su código C sea un poco más parecido a C++“?

    – RobertS apoya a Mónica Cellio

    9 de febrero de 2020 a las 19:11

  • @RobertSsupportsMonicaCellio No puede hacer una declaración directa sin una etiqueta. El ejemplo en el comentario vinculado usó un typedef y una etiqueta. No, quise decir que usar un typedef puede hacer que el código C sea más parecido a C ++. En C++, se hace referencia a las estructuras (y las clases, las uniones y las enumeraciones) mediante un nombre que es un identificador único. Referirse a un tipo como struct foo es más como C.

    –Keith Thompson

    9 de febrero de 2020 a las 22:19

  • Excelente respuesta, realmente entendí esta. Creo que lo usaré de esta manera “struct node { .. };” Luego, eventualmente, para escribir más corto “typedef struct node node;” antes de usar realmente la estructura.

    – udarH3

    5 de julio de 2020 a las 10:23


  • Mi respuesta ya no está actualizada. Los compiladores actuales tratan “typedef struct” y “struct” de la misma manera. Se puede hacer referencia a ambos sin el prefijo “struct”. Es decir, VC2013 se comporta de esa manera.

    – AIRE SUAVE ROJO

    29 de marzo de 2018 a las 13:23

  • Agradezco tu respuesta corta así como la otra aceptada. En aras del orden, ¿qué quiere decir con “compiladores actuales”? ¿A qué tipo de versión C te refieres? Por ejemplo, probé el comportamiento durante una compilación cruzada con el compilador ARM (C99). En mi caso, “estructura typedef” y “estructura” no se tratan de la misma manera.

    – bitfox

    15 de marzo de 2019 a las 11:19

  • Las versiones de VC 2017 y posteriores (posiblemente también anteriores) no requieren escribir struct… cuando se crea una instancia de un objeto. Más no puedo decir.

    – AIRE SUAVE ROJO

    16 de marzo de 2019 a las 12:20

  • @REDSOFTADAIR “Los compiladores actuales tratan”typedef struct” y “struct” lo mismo. Se puede hacer referencia a ambos sin el “struc“prefijo”. – Tenga en cuenta que esta declaración no es cierta para C, solo es correcta para C ++, sin importar lo que haga una implementación específica. godbolt.org/z/XzFFv6

    – RobertS apoya a Mónica Cellio

    10 de febrero de 2020 a las 18:46

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

struct myStruct myVariable;

Para poder usar myStruct myVariable; en cambio, puedes typedef la estructura:

typedef struct myStruct someStruct;
someStruct myVariable;

Puedes combinar struct definición y typedefs en una sola declaración que declara un anónimo struct y typedefsentar.

typedef struct { ... } myStruct;

  • El último bloque de código no es equivalente al código anterior. En la última línea, está definiendo un alias de tipo ‘myStruct’ en una estructura sin nombre. Hay una diferencia (muy) sutil entre las dos versiones.

    – David Rodríguez – dribeas

    4 de noviembre de 2009 a las 17:52

  • dribeas: cubrí esta sutil diferencia en la oración “… una declaración única que declara una estructura anónima y…”

    – mmx

    4 de noviembre de 2009 a las 18:10

  • @DavidRodríguez-dribeas ¿Le importa explicar las sutiles diferencias?

    – Antonio

    21 de marzo de 2013 a las 0:12

  • @anthony-arnold: Uhm… Creo que ya lo mencioné. En un caso hay un tipo con nombre y también un alias, en el otro solo tienes un alias. ¿Dónde importa? Rara vez, pero si tienes un tipo anónimo no puedes hacer struct T x; para declarar una variable, o reutilizar el nombre para un tipo diferente de símbolo: typedef struct {} f; void f(); struct f x; falla en las dos últimas afirmaciones. Por supuesto, no se recomienda tener un código como ese (¿un tipo y una función con el mismo nombre?)

    – David Rodríguez – dribeas

    21 de marzo de 2013 a las 2:19

  • La respuesta aceptada no hizo un buen trabajo al contrastar “struct” y “typedef struct”, esta respuesta me dejó en claro que la técnica “typedef struct” se usa para que C pueda emular C ++ para omitir “struct” cuando se usa la estructura como un tipo de datos al pasarlo.

    – Último

    7 de abril de 2016 a las 4:46

avatar de usuario
jjnguy

Él typedef, como ocurre con otras construcciones, se utiliza para dar un nuevo nombre a un tipo de datos. En este caso, se hace principalmente para que el código sea más limpio:

struct myStruct blah;

contra

myStruct blah;

  • El último bloque de código no es equivalente al código anterior. En la última línea, está definiendo un alias de tipo ‘myStruct’ en una estructura sin nombre. Hay una diferencia (muy) sutil entre las dos versiones.

    – David Rodríguez – dribeas

    4 de noviembre de 2009 a las 17:52

  • dribeas: cubrí esta sutil diferencia en la oración “… una declaración única que declara una estructura anónima y…”

    – mmx

    4 de noviembre de 2009 a las 18:10

  • @DavidRodríguez-dribeas ¿Le importa explicar las sutiles diferencias?

    – Antonio

    21 de marzo de 2013 a las 0:12

  • @anthony-arnold: Uhm… Creo que ya lo mencioné. En un caso hay un tipo con nombre y también un alias, en el otro solo tienes un alias. ¿Dónde importa? Rara vez, pero si tienes un tipo anónimo no puedes hacer struct T x; para declarar una variable, o reutilizar el nombre para un tipo diferente de símbolo: typedef struct {} f; void f(); struct f x; falla en las dos últimas afirmaciones. Por supuesto, no se recomienda tener un código como ese (¿un tipo y una función con el mismo nombre?)

    – David Rodríguez – dribeas

    21 de marzo de 2013 a las 2:19

  • La respuesta aceptada no hizo un buen trabajo al contrastar “struct” y “typedef struct”, esta respuesta me dejó en claro que la técnica “typedef struct” se usa para que C pueda emular C ++ para omitir “struct” cuando se usa la estructura como un tipo de datos al pasarlo.

    – Último

    7 de abril de 2016 a las 4:46

avatar de usuario
hermano

No puede usar la declaración directa con el typedef struct.

Él struct en sí mismo es un tipo anónimo, por lo que no tiene un nombre real para declarar hacia adelante.

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

Una declaración de reenvío como esta no funcionará:

struct myStruct; //forward declaration fails

void blah(myStruct* pStruct);

//error C2371: 'myStruct' : redefinition; different basic types

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad