morir de vergüenza
Quiero inicializar un elemento de estructura, dividirlo en declaración e inicialización. Esto es lo que tengo:
typedef struct MY_TYPE {
bool 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 que funcione?
Actualizar Terminé teniendo un elemento de inicialización estático donde configuré cada subelemento según mis necesidades.
cesarb
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 };
-
Entonces, ¿los inicializadores designados son para cuando declara y define al mismo tiempo, pero los literales compuestos son para cuando define una variable ya declarada?
– Geremia
24 de marzo de 2016 a las 19:09
-
@Geremia, primero debe definir la estructura en ambos casos, pero con inicializadores designados, hace que el código sea más legible y más resistente a los errores, en caso de cambios en la estructura.
– hoijui
18 de diciembre de 2017 a las 7:05
-
Esto es un poco complicado. Muchas veces (algunas con éxito) he intentado usar inicializadores designados. Sin embargo, solo ahora ha quedado claro (gracias a su ejemplo y el de @philant) que debe existir una conversión si el inicializador no se usa en el momento de la creación del objeto. Sin embargo, ahora también aprendí que si los inicializadores se usan en un momento que no sea la creación de objetos (como en su ejemplo), se lo conoce como un literal compuestono estrictamente un inicializador designado. ideone.com/Ze3rnZ
– sherrellbc
28 de diciembre de 2017 a las 12:23
ron nuni
Veo que ya recibiste una respuesta sobre ANSI C 99, por lo que lanzaré un hueso sobre ANSI C 89. ANSI C 89 te permite inicializar 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;
}
Una cosa 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 basura”.
¡Buena suerte!
-
¿Es posible utilizar variables en la inicialización?
– Cian
20 mayo 2016 a las 13:47
-
@Cyan Es para objetos con duración de almacenamiento automático. Ver 6.7.9 13) en open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf . Para los objetos globales está bastante restringido a los literales. Ni siquiera puede usar otros objetos globales, incluso si son constantes.
– PSkocik
9 oct 2016 a las 11:47
-
Entonces, ¿la única diferencia con C 99 es que no puede especificar las designaciones?
– Akaisteph7
24 de febrero de 2020 a las 23:55
Neuron – Libertad para Ucrania
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 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 (es decir, si solo declara esa variable), todo variable.members
contendrá “valores basura”, ¡solo si la declaración es local!
Si la declaración es global o estático (como en este caso), todos sin inicializar variable.members
se inicializará automáticamente a:
0
para enteros y punto flotante'\0'
porchar
(por supuesto, esto es lo mismo que0
ychar
es un tipo entero)NULL
para punteros.
-
¿Es posible utilizar variables en la inicialización?
– Cian
20 mayo 2016 a las 13:47
-
@Cyan Es para objetos con duración de almacenamiento automático. Ver 6.7.9 13) en open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf . Para los objetos globales está bastante restringido a los literales. Ni siquiera puede usar otros objetos globales, incluso si son constantes.
– PSkocik
9 oct 2016 a las 11:47
-
Entonces, ¿la única diferencia con C 99 es que no puede especificar las designaciones?
– Akaisteph7
24 de febrero de 2020 a las 23:55
Neuron – Libertad para Ucrania
ya casi lo tienes…
MY_TYPE a = { true, 15, 0.123 };
-
Creo que esto es cierto para el estándar C, pero no para ANSI C (99?). Además, estoy sujeto a reglas de codificación que no me permiten hacer la declaración y la inicialización a la vez, por lo que tengo que dividirlo e inicializar cada uno de los subelementos.
– morir de vergüenza
1 de diciembre de 2008 a las 13:26
-
La inicialización solo puede ocurrir en el punto de declaración. Eso es lo que significa ‘inicializar’. De lo contrario, está permitiendo que un valor indefinido sea el valor inicial de su variable/estructura, y luego asignando un valor más adelante.
– Kieveli
1 de diciembre de 2008 a las 13:43
-
um… ¿Tienes reglas de codificación que son deliberadamente malas? Tal vez debería presentarle al tipo que los escribió “Adquisición de recursos es inicialización” (en.wikipedia.org/wiki/RAII)
– James Curran
1 de diciembre de 2008 a las 15:10
-
Confía en mí, realmente, realmente, no puedo cambiar ni un poco de estas reglas en este momento. Se siente horrible codificarlo. Y hay muchas otras reglas de los años 70, como encabezados de código estáticos con información de administración como el número de revisión. Cambios para cada lanzamiento, incluso si la fuente no cambió…
– morir de vergüenza
2 de diciembre de 2008 a las 7:12
realmente deberías aceptar una mejor respuesta, veo que tuviste que usar una mala guía de codificación, pero aún así no deberías sugerir a otras personas que esa es la forma correcta de hacerlo.
–Karoly Horvath
28 de julio de 2012 a las 9:43
@KarolyHorvath bueno, la mayoría de las buenas respuestas son específicas de C99. ¿Quizás mi pregunta es un duplicado de stackoverflow.com/questions/6624975/…?
– morir de vergüenza
29 de julio de 2012 a las 10:02
si esa era su intención original, entonces probablemente sí, pero luego 1) los votos serían muy engañosos. 2) de los principales resultados de búsqueda, este es el único que muestra la forma C99… sería mejor reutilizar esta página para la demostración C99… (aparentemente, la gente comenzó a vincular esta página para mostrar cómo hazlo)
–Karoly Horvath
29 de julio de 2012 a las 11:02
Es interesante que la respuesta aceptada (y fuertemente votada) en realidad no responda la pregunta, incluso como se publicó originalmente. Los inicializadores designados no abordan el problema del OP, que es separar la declaración de la inicialización. Para C anterior a 1999, la única solución real es asignar a cada miembro; para C99 y posteriores, un literal compuesto, como en la respuesta de CesarB, es la solución. (Por supuesto, un inicializador real, con o sin designadores, sería aún mejor, pero aparentemente el OP estaba cargado con un estándar de codificación realmente malo).
–Keith Thompson
9 de junio de 2013 a las 6:39
Estrictamente hablando, el término “ANSI C” ahora se refiere a la norma ISO de 2011, que ANSI ha adoptado. Pero en la práctica, el término “ANSI C” comúnmente se refiere al estándar (oficialmente obsoleto) de 1989. Por ejemplo, “gcc -ansi” aún aplica el estándar de 1989. Dado que es ISO la que publicó los estándares de 1990, 1999 y 2011, es mejor evitar el término “ANSI C” y referirse a la fecha del estándar si existe alguna posibilidad de confusión.
–Keith Thompson
9 de junio de 2013 a las 6:43