¿Cuál es la forma sintácticamente correcta de declarar una estructura C?

6 minutos de lectura

He visto estructuras C declaradas de varias maneras antes. ¿Por qué es eso y qué, en todo caso, hace cada uno diferente?

Por ejemplo:

struct foo {
  short a;
  int b;
  float c;
};

typedef struct {
  short d;
  int e;
  float f;
} bar;

typedef struct _baz {
  short a;
  int b;
  float c;
} baz;

int main (int argc, char const *argv[])
{
  struct foo a;
  bar b;
  baz c;

  return 0;
}

  • Esto no responde a su pregunta para C, pero creo que todos son correctos para C++, aunque se prefiere el primero. Esto también puede haber cambiado entre diferentes versiones de C, pero dejaré que alguien más hable de eso, ya que no soy un experto en la historia de C/C++.

    – Merlyn Morgan-Graham

    15 de enero de 2011 a las 8:10

  • C++ es diferente: cuando escribes struct Foo { }; o class Foo { }; ahí, obtienes Foo gratis sin typedef.

    – Fred Foo

    15 de enero de 2011 a las 8:18

  • Sin embargo, todos seguirán funcionando, aunque pueden hacer cosas ligeramente diferentes (como contaminar su espacio de nombres con etiquetas adicionales).

    – Merlyn Morgan-Graham

    15 de enero de 2011 a las 8:20

  • @Merlyn – No exactamente. class X te permite declarar X x;pero X todavía está en el class / struct espacio de nombres de etiquetas, que permite a las personas probar cosas desagradables como class singleton { ... } singleton;

    – Chris Lutz

    15 de enero de 2011 a las 8:30


  • Tenga en cuenta que el uso de guiones bajos iniciales en los nombres de las etiquetas de estructuras es casi seguro que es incorrecto. Puede romper cosas y no sirve para nada. no lo hagas

    – R.. GitHub DEJA DE AYUDAR A ICE

    15 de enero de 2011 a las 13:14


¿Cual es la forma sintacticamente correcta de declarar una estructura
chris lutz

Bueno, la diferencia obvia se demuestra en su main:

struct foo a;
bar b;
baz c;

La primera declaración es de untypedefeducar struct y necesita la struct palabra clave a utilizar. El segundo es de un typedefed anonimo structy así usamos el typedef nombre. El tercero combina tanto el primero como el segundo: su ejemplo usa baz (que es convenientemente corto) pero podría usar con la misma facilidad struct _baz al mismo efecto.

Actualización: la respuesta de larsmans menciona un caso más común en el que debe usar al menos struct x { } para hacer una lista enlazada. El segundo caso no sería posible aquí (a menos que abandones la cordura y uses un void * en cambio) porque el struct es anónimo y el typedef no sucede hasta el struct está definido, lo que no le da forma de hacer un puntero (con seguridad de tipos) al struct escriba en sí mismo. La primera versión funciona bien para este uso, pero en mi experiencia generalmente se prefiere la tercera. Dale algo de reputación por eso.

Una diferencia más sutil está en la ubicación del espacio de nombres. C ª, struct las etiquetas se colocan en un espacio de nombres separado de otros nombres, pero typedef los nombres no lo son. Entonces lo siguiente es legal:

struct test {
  // contents
};

struct test *test() {
  // contents
}

Pero el siguiente no lo es, porque sería ambiguo cuál es el nombre test es:

typedef struct {
  // contents
} test;

test *test() {
  // contents
}

typedef acorta el nombre (siempre es una ventaja), pero lo coloca en el mismo espacio de nombres que sus variables y funciones. Por lo general, esto no es un problema, pero es una diferencia sutil más allá del simple acortamiento.

  • ¿Sería ilegal usar el mismo nombre tanto para la etiqueta como para el typedef? ¿O no es una buena idea? ¿O está perfectamente bien? Por ejemplo: typedef struct mystruct{ } mystruct;

    – Sean Ramey

    23 de enero de 2018 a las 21:23


  • No, no es ilegal ya que se encuentran en diferentes espacios de nombres. Lea stackoverflow.com/a/1675446/6214440 para obtener una buena explicación. También tenga en cuenta que en C11 puede definir estructuras anónimas: typedef struct { ... } Foo

    usuario6214440

    11 de octubre de 2019 a las 7:13

Es en gran medida una cuestión de preferencia personal. Me gusta dar a los nuevos tipos un nombre que comience con una letra mayúscula y omita el structasí que suelo escribir typedef struct { ... } Foo. Eso significa que no puedo escribir struct Foo.

La excepción es cuando un struct contiene un puntero a su propio tipo, por ejemplo

typedef struct Node {
    // ...
    struct Node *next;
} Node;

En este caso, también debe declarar el struct Node tipo, ya que el typedef no está dentro del alcance de la struct definición. Tenga en cuenta que ambos nombres pueden ser iguales (no estoy seguro de dónde se originó la convención de guión bajo, pero supongo que los compiladores de C más antiguos no pudieron manejar typedef struct X X;).

  • ¡Do! Olvidé el caso de uso obvio de “lista enlazada”. +1

    – Chris Lutz

    15 de enero de 2011 a las 8:12

Todos sus usos son sintácticamente correctos. Prefiero el siguiente uso

 /* forward declare all structs and typedefs */
typedef struct foo foo;
.
.
/* declare the struct itself */
struct foo {
  short a;
  int b;
  foo* next;
};

Obsérvese que esto permite utilizar fácilmente el typedef ya dentro de la declaración de la struct mismo, y que incluso para struct que se refieren mutuamente.

  • +1 para un área que me perdí, y agrega eso si usas typedef struct foo foo; en sus encabezados y no proporcionan una definición de struct fooel código de usuario tendrá un puntero opaco (es decir, pueden pasar foo * punteros y recibirlos de las funciones de la biblioteca, pero no puede acceder a los miembros internos.) Esto es bueno para la encapsulación de datos, y un idioma común: el estándar FILE * type es uno de esos ejemplos de esto.

    – Chris Lutz

    15 de enero de 2011 a las 8:42

1647546848 518 ¿Cual es la forma sintacticamente correcta de declarar una estructura
mike t

La confusión surge porque algunas de las declaraciones de hecho declaran hasta tres construcciones C. Debes tener en cuenta la diferencia entre:

  1. Una declaración typedef,
  2. Una definición de estructura, y
  3. Una declaración de estructura.

Todos son construcciones de C muy diferentes. Todos hacen cosas diferentes; pero puede combinarlos en una construcción compuesta, si lo desea.

Veamos cada declaración a su vez.


struct foo {
  short a;
  int b;
  float c;
};

Aquí estamos usando la sintaxis de definición de estructura más básica. Estamos definiendo un tipo C y le damos el nombre foo en el etiqueta espacio de nombres Posteriormente se puede usar para declarar variables de ese tipo usando la siguiente sintaxis:

struct foo myFoo;  // Declare a struct variable of type foo.

Esta siguiente declaración le da al tipo otro nombre (alias) en el global espacio de nombres Desglosémoslo en sus componentes usando la declaración básica anterior.

typedef foo bar;   // Declare bar as a variable type, the alias of foo.

bar myBar;         // No need for the "struct" keyword

¡Ahora simplemente reemplace “foo” con la definición de la estructura y listo!

typedef struct {
  short d;    
  int e;
  float f;
} bar;

typedef struct _baz {
  short a;
  int b;
  float c;
} baz;

La sintaxis anterior es equivalente a la siguiente secuencia de declaraciones.

struct _baz {
  short a;
  int b;
  float c;
}

typedef _baz baz;  // Declare baz as an alias for _baz.

baz myBaz;         // Is the same as: struct _baz myBaz;

¿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