2011-01-23 16 views
36
typedef struct { 
    int hour; 
    int min; 
    int sec; 
} counter_t; 

Y en el código, me gustaría inicializar instancias de esta estructura sin inicializar explícitamente cada variable miembro. Es decir, me gustaría hacer algo como:¿Cómo asignar una estructura C en línea?

counter_t counter; 
counter = {10,30,47}; //doesn't work 

para 10:30:47

en lugar de

counter.hour = 10; 
counter.min = 30; 
counter.sec = 47; 

No recuerdo sintaxis para esto, y no lo hizo busque inmediatamente una forma de hacerlo desde Google.

Gracias!

+5

Eso debería funcionar. –

+1

Sí, parece que funciona si hago la declaración en la misma línea, por ejemplo, 'counter_t counter = {10,30,47}', pero no si la declaración se ha realizado antes de esta asignación. – mindthief

+5

@Oli: ¿Por qué debería funcionar? Como está escrito, es una tarea, no una inicialización. – sth

Respuesta

69

Inicialización:

counter_t c = {10, 30, 47}; 

Asignación:

c = (counter_t){10, 30, 48}; 

Este último se llama un "compuesto literal".

+7

Tenga en cuenta que esto requiere GCC o C99, no un estricto compilador C89 o C++. –

+9

@Jeremiah: buen punto, no noté la etiqueta C++. En cuanto a C89, si la gente da vueltas diciendo "C" cuando quieren decir "C89", están por su propia cuenta ;-) –

+0

Bien, sí, también lo descubrí - contador usado = (counter_t) {10,30,47} que es lo mismo que sugeriste. "Compuesto literal" ¿eh? ¡Gracias! – mindthief

7

En aras de mantenimiento prefiero la sintaxis de una lista con las variables identificadas de forma explícita, de la siguiente manera:

counter_t counter = {.hour = 10, .min = 30, .sec = 47}; 

o para el retorno de línea, por ejemplo:

return (struct counter_t){.hour = 10, .min = 30, .sec = 47}; 

puedo imaginar un escenario en el que uno cambia el orden en que se declaran las variables, y si no identifica explícitamente sus variables, debe pasar por todo el código para corregir el orden de las variables. De esta manera es más limpio y más fácil de leer Creo

nota lateral:

Como @AshleyDuncan y poner @MM, esta característica fue retirado de la ISO C++ después de C99 https://stackoverflow.com/a/12122261/2770195, pero se apoya en gnu C++.

Así, mientras que usted puede hacer esto muy bien:

g++ -std=gnu++11 main.cpp -o main 

Esto generará un error si se intenta el ejemplo anterior:

# need an example. I was unable to find. Even clang++ supports it. If you know 
# one, please suggest an edit 

Si necesita compilar con un compilador de C++ con el apoyo para ISO C++ 11 o posterior que no reconoce esta extensión gnu, puede que tenga que usar una clase con un constructor simple:

// backup workaround 
// not cool 
class gnuFTW { 
public: 
    int hour; 
    int min; 
    int sec; 
    gnuFTW(int hour, int min, int sec) { 
     this->hour = hour; 
     this->min = min; 
     this->sec = sec; 
    } 
}; 

int main(int argc, const char * argv[]) { 
    gnuFTW counter = gnuFTW(10,30,47); 
    cout << counter.hour << endl; 
    return 0; 
} 
+2

También me gusta esto pero no tan bueno si también desea compilar con un compilador de C++ ya que es una característica única de C99 que no es compatible con C++. https://stackoverflow.com/questions/12122234/how-to-initialize-a-struct-using-the-c-style-while-using-the-g-compiler –

+0

No sabía eso. Es una lástima, es una característica tan útil. El mejor enfoque, creo que en este caso es la solución de Don Doerner: https://stackoverflow.com/a/14206226/2770195. En pocas palabras: use clases con variables y un solo inicializador. No parece una buena práctica, pero hace exactamente lo que hacen las estructuras. Voy a actualizar la respuesta con una aclaración, gracias por recordar – MuhsinFatih

+0

Estoy confundido, acabo de compilar un ejemplo con la opción -gnu ++ 11: https://1drv.ms/i/s!ArNqKg0GFwIE0HVGDPPHvpEgaGrh. ¿Me estoy perdiendo de algo? – MuhsinFatih

Cuestiones relacionadas