paso - ¿cuál es la estructura de un programa en lenguaje c?




Cómo inicializar una estructura de acuerdo con los estándares del lenguaje de programación C (9)

Quiero inicializar un elemento de estructura, división en declaración e inicialización. Esto es lo que tengo:

typedef struct MY_TYPE {
  boolean flag;
  short int value;
  double stuff;
} MY_TYPE;

void function(void) {
  MY_TYPE a;
  ...
  a = { true, 15, 0.123 }
}

¿Es esta la forma de declarar e inicializar una variable local de MY_TYPE de acuerdo con los estándares del lenguaje de programación C (C89, C90, C99, C11, etc.)? ¿O hay algo mejor o al menos funciona?

Actualización terminé teniendo un elemento de inicialización estático donde configuré cada subelemento de acuerdo con mis necesidades.



El estándar de lenguaje de programación C ISO / IEC 9899: 1999 (comúnmente conocido como C99) permite utilizar un inicializador designado para inicializar miembros de una estructura o unión de la siguiente manera:

MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 };

Se define en el paragraph 7 , sección 6.7.8 Initialization de la norma ISO / IEC 9899: 1999 como:

Si un designador tiene la forma
. identificador
entonces el objeto actual (definido abajo) tendrá estructura o tipo de unión y el identificador será el nombre de un miembro de ese tipo.

Tenga en cuenta que el paragraph 9 de la misma sección establece que:

Excepto cuando se indique explícitamente lo contrario, para los fines de esta subcláusula, los miembros sin nombre de los objetos de estructura y tipo de unión no participan en la inicialización. Los miembros sin nombre de los objetos de estructura tienen un valor indeterminado incluso después de la inicialización.

En la implementación de GNU GCC, sin embargo, los miembros omitidos se inicializan como cero o como valores de tipo de tipo apropiado. Como se indica en la sección https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html de la documentación de GNU GCC:

Los miembros de campo omitidos se inicializan implícitamente igual que los objetos que tienen una duración de almacenamiento estático.

El compilador de Microsoft Visual C ++ debe admitir los inicializadores designados desde la versión 2013 de acuerdo con la publicación oficial del blog C ++ Conformance Roadmap . El artículo sobre Initializing unions and structs de Initializers en la documentación de MSDN Visual Studio sugiere que los miembros sin nombre se inicializaron con valores apropiados similares a cero de manera similar a GNU GCC.

La nueva norma ISO / IEC 9899: 2011 (comúnmente conocida como C11) que había reemplazado a ISO / IEC 9899: 1999 conserva los inicializadores designados en la sección 6.7.9 Initialization . También conserva el paragraph 9 sin cambios.


Encontré otra forma de inicializar estructuras.

La estructura:

typedef struct test {
    int num;
    char* str;
} test;

Inicialización:

test tt = {
    num: 42,
    str: "nice"
};

Según la documentación de GCC, esta sintaxis está https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html .


He leído la documentación de Microsoft Visual Studio 2015 para inicializar tipos agregados , sin embargo, todas las formas de inicialización con {...} se explican allí, pero la inicialización con punto, denominada "designador" no se menciona allí. No funciona también.

La inicialización del capítulo 6.7.8 de C99 explica la posibilidad de los designadores, pero en mi opinión no está muy claro para estructuras complejas. El estándar C99 como pdf .

En mi mente, puede ser mejor

  1. Utilice el = {0}; -inicialización para todos los datos estáticos. Es menos esfuerzo para el código máquina.
  2. Usa macros para inicializar, por ejemplo

    typedef MyStruct_t{ int x, int a, int b; } MyStruct; define INIT_MyStruct(A,B) { 0, A, B}

La macro se puede adaptar, su lista de argumentos puede ser independiente del contenido de la estructura modificada. Es correcto si se deben inicializar menos elementos. También es apropiado para estructuras anidadas. 3. Una forma simple es: Inicializar en una subrutina:

void init_MyStruct(MyStruct* thiz, int a, int b) {
  thiz->a = a; thiz->b = b; }

Esta rutina se parece a ObjectOriented en C. ¡Usa thiz , no this para compilarlo también con C ++!

MyStruct data = {0}; //all is zero!
init_MyStruct(&data, 3, 456);

No me gustó ninguna de estas respuestas, así que hice las mías. No sé si esto es ANSI C o no, es solo GCC 4.2.1 en su modo predeterminado. Nunca puedo recordar el paréntesis, así que comienzo con un subconjunto de mis datos y lucho contra los mensajes de error del compilador hasta que se cierra. La legibilidad es mi primera prioridad.

    // in a header:
    typedef unsigned char uchar;

    struct fields {
      uchar num;
      uchar lbl[35];
    };

    // in an actual c file (I have 2 in this case)
    struct fields labels[] = {
      {0,"Package"},
      {1,"Version"},
      {2,"Apport"},
      {3,"Architecture"},
      {4,"Bugs"},
      {5,"Description-md5"},
      {6,"Essential"},
      {7,"Filename"},
      {8,"Ghc-Package"},
      {9,"Gstreamer-Version"},
      {10,"Homepage"},
      {11,"Installed-Size"},
      {12,"MD5sum"},
      {13,"Maintainer"},
      {14,"Modaliases"},
      {15,"Multi-Arch"},
      {16,"Npp-Description"},
      {17,"Npp-File"},
      {18,"Npp-Name"},
      {19,"Origin"}
    };

Los datos pueden comenzar como un archivo delimitado por tabulaciones que busca y reemplaza para masajearlo en otra cosa. Sí, esto es Debian. Entonces, un par externo de {} (que indica la matriz), luego otro par para cada estructura interna. Con comas entre. Poner las cosas en un encabezado no es estrictamente necesario, pero tengo aproximadamente 50 elementos en mi estructura, así que los quiero en un archivo separado, tanto para mantener el desorden de mi código como para que sea más fácil de reemplazar.


Puedes hacerlo con un literal compuesto . Según esa página, funciona en C99 (que también cuenta como ANSI C ).

MY_TYPE a;

a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 };
...
a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false };

Las designaciones en los inicializadores son opcionales; También podrías escribir:

a = (MY_TYPE) { true,  123, 0.456 };
...
a = (MY_TYPE) { false, 234, 1.234 };

Veo que ya recibió una respuesta sobre ANSI C 99, así que le diré algo sobre ANSI C 89. ANSI C 89 le permite iniciar una estructura de esta manera:

typedef struct Item {
    int a;
    float b;
    char* name;
} Item;

int main(void) {
    Item item = { 5, 2.2, "George" };
    return 0;
}

Algo importante para recordar, en el momento en que inicializa incluso un objeto / variable en la estructura, todas sus otras variables se inicializarán al valor predeterminado.

Si no inicializa los valores en su estructura, todas las variables contendrán "valores de basura".

¡Buena suerte!


como dijo Ron Nuni:

typedef struct Item {
    int a;
    float b;
    char* name;
} Item;

int main(void) {
    Item item = {5, 2.2, "George"};
    return 0;
}

Una cosa importante a recordar: en el momento en que inicialice incluso un objeto / variable en la estructura, todas sus otras variables se inicializarán al valor predeterminado.

Si no inicializa los valores en su estructura (es decir, si acaba de declarar esa variable), todos los variable.members contendrán "valores de basura", solo si la declaración es local.

Si la declaración es global o estática (como en este caso), todos los miembros de variable.members sin inicializar se inicializarán automáticamente para:

  • 0 para enteros y punto flotante
  • '\0' para char (por supuesto, esto es igual a 0 , y char es un tipo entero)
  • NULL para los punteros.

void function(void) {
  MY_TYPE a;
  a.flag = true;
  a.value = 15;
  a.stuff = 0.123;
}




initialization