valor predeterminado para el miembro de estructura en C

82

¿Es posible establecer valores predeterminados para algún miembro de estructura? Intenté lo siguiente, pero causaría un error de sintaxis:

typedef struct
{
  int flag = 3;
} MyStruct;

Errores:

$ gcc -o testIt test.c 
test.c:7: error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token
test.c: In function ‘main’:
test.c:17: error: ‘struct <anonymous>’ has no member named ‘flag’
usuario1508893
fuente
Puede crear una función de inicialización para la estructura.
sgarizvi
4
No en C. Puede crear una función que devuelva una estructura con los valores que desee.
Vaughn Cato
Cuando lo crea, puede inicializar los valores de esta manera: stackoverflow.com/questions/749180/default-values-in-ac-struct
Fantastic Mr Fox
Para la estructura C ++, puede iniciar datos predeterminados en el constructor
Zac

Respuestas:

122

La estructura es un tipo de datos . No le das valores a un tipo de datos. Le das valores a instancias / objetos de tipos de datos.
Entonces no, esto no es posible en C.

En su lugar, puede escribir una función que realice la inicialización de la instancia de estructura.

Alternativamente, puede hacer:

struct MyStruct_s 
{
    int id;
} MyStruct_default = {3};

typedef struct MyStruct_s MyStruct;

Y luego siempre inicialice sus nuevas instancias como:

MyStruct mInstance = MyStruct_default;
Alok Save
fuente
3
Si tengo una matriz global: 'MyStruct arr [MAX_SIXE];', ¿cómo se puede utilizar la función? (Nota: No se puede tener una función init () que ir a través de todo el miembro y establecer el indicador)
user1508893
10
MyStruct_default debe declararse como const.
Lundin
1
Gracias por tu respuesta. Terminé haciendo un sandbox de código para probarlo en línea, tuve problemas para conectar todo al principio, espero que esto ayude a alguien más: ideone.com/knQ7xS
HoldOffHunger
52

no puedes hacerlo de esta manera

Utilice lo siguiente en su lugar

typedef struct
{
   int id;
   char* name;
}employee;

employee emp = {
.id = 0, 
.name = "none"
};

Puede utilizar macro para definir e inicializar sus instancias. esto le facilitará cada vez que desee definir una nueva instancia e inicializarla.

typedef struct
{
   int id;
   char* name;
}employee;

#define INIT_EMPLOYEE(X) employee X = {.id = 0, .name ="none"}

y en su código cuando necesite definir una nueva instancia con el tipo de empleado, simplemente llame a esta macro como:

INIT_EMPLOYEE(emp);
MOHAMED
fuente
1
No parece bueno si desea pasar al parámetro no cumplir con los requisitos.
18

Estoy de acuerdo con Als en que no puede inicializar al momento de definir la estructura en C. Pero puede inicializar la estructura al momento de crear la instancia que se muestra a continuación.

C ª,

 struct s {
        int i;
        int j;
    };

    struct s s_instance = { 10 ,20 };

en C ++ es posible dar un valor directo en la definición de estructura que se muestra a continuación

struct s {
    int i;

    s(): i(10)
    {
    }
};
Chirag Desai
fuente
13

Tu puedes hacer:

struct employee_s {
  int id;
  char* name;
} employee_default = {0, "none"};

typedef struct employee_s employee;

Y luego solo debe recordar hacer la inicialización predeterminada cuando declara una nueva variable de empleado:

employee foo = employee_default;

Alternativamente, siempre puede construir su estructura de empleado a través de una función de fábrica.

Donnie
fuente
8

Si está utilizando gcc, puede ceder designated initializersen la creación de objetos.

typedef struct
{
   int id=0;
   char* name="none";
}employee;

employee e = 
{
 .id = 0;
 .name = "none";
};

O simplemente use como inicialización de matriz.

employee e = {0 , "none"};

Omkant
fuente
1
He visto que algunos códigos también usan dos puntos para los inicializadores designados, más en esta pregunta: stackoverflow.com/questions/1601201/…
sdaau
7

Cree una estructura predeterminada como las otras respuestas han mencionado:

struct MyStruct
{
    int flag;
}

MyStruct_default = {3};

Sin embargo, el código anterior no funcionará en un archivo de cabecera - obtendrá el error: multiple definition of 'MyStruct_default'. Para resolver este problema, utilice externen su lugar en el archivo de encabezado:

struct MyStruct
{
    int flag;
};

extern const struct MyStruct MyStruct_default;

Y en el carchivo:

const struct MyStruct MyStruct_default = {3};

Espero que esto ayude a cualquiera que tenga problemas con el archivo de encabezado.

David Callanan
fuente
Un comentario unos años después: probablemente tenga más sentido si pudiera hacer esto directamente en el archivo de encabezado.
David Callanan
5

Aún más, para agregar las respuestas existentes, puede usar una macro que oculta un inicializador de estructura:

#define DEFAULT_EMPLOYEE { 0, "none" }

Luego en tu código:

employee john = DEFAULT_EMPLOYEE;
Bogdan Alexandru
fuente
3

Puede implementar una función de inicialización:

employee init_employee() {
  empolyee const e = {0,"none"};
  return e;
}
máscara de bits
fuente
Observó que el objeto variable de estructura de C e (const o no) desaparecerá cuando el bloque en el que está definido salga. Si es un puntero, provocará el problema del puntero colgante. Por lo tanto, no es una buena solución si el tipo de retorno es un puntero. La mejor manera es tener un objeto variable de estructura global estática con valores predeterminados usando inicializadores de estructura C y usar las funciones set y get para que la variable cambie sus valores durante el tiempo de ejecución del programa. O pase un objeto de variable de estructura local a una función establecida como parámetro y cambie sus valores de propiedad dentro de la función establecida.
Ecle
2
Lo siento, pero eso está mal @ecle. El valor de retorno es una estructura desnuda, no un puntero. Se copiará, no se devolverá por referencia. Honestamente, el compilador probablemente lo optimizará al máximo.
máscara de bits
@bismask No me malinterpretes ... mencioné si la función devuelve un puntero si es un puntero . Tal vez hayas comentado mi comentario anterior antes de mi edición reciente.
ecle
2

Puede usar alguna función para inicializar la estructura de la siguiente manera,

typedef struct
{
    int flag;
} MyStruct;

MyStruct GetMyStruct(int value)
{
    MyStruct My = {0};
    My.flag = value;
    return My;
}

void main (void)
{
    MyStruct temp;
    temp = GetMyStruct(3);
    printf("%d\n", temp.flag);
}

EDITAR:

typedef struct
{
    int flag;
} MyStruct;

MyStruct MyData[20];

MyStruct GetMyStruct(int value)
{
    MyStruct My = {0};
    My.flag = value;
    return My;
}

void main (void)
{
    int i;
    for (i = 0; i < 20; i ++)
        MyData[i] = GetMyStruct(3);

    for (i = 0; i < 20; i ++)
        printf("%d\n", MyData[i].flag);
}
Adeel Ahmed
fuente
2
Bueno, ¿qué pasa si quiero tener una matriz global de estructuras, cómo propones que se llame a GetMyStruct ()?
user1508893
¿No debería GetMyStruct usar malloc?
Dmitry
1

Si solo usa esta estructura por una vez , es decir, crea una variable global / estática, puede eliminar typedefe inicializar esta variable instantáneamente:

struct {
    int id;
    char *name;
} employee = {
    .id = 0,
    .name = "none"
};

Luego, puede usar employeeen su código después de eso.

HaxtraZ
fuente
0

Una función de inicialización de una estructura es una buena forma de otorgarle valores predeterminados:

Mystruct s;
Mystruct_init(&s);

O incluso más corto:

Mystruct s = Mystruct_init();  // this time init returns a struct
Israel Unterman
fuente
Si tengo una matriz global: 'MyStruct arr [MAX_SIXE];', ¿cómo se puede utilizar la función? (NOTA: no puedo tener una función init () que pase por todos los miembros y establezca el indicador)
user1508893
0

Otro enfoque para los valores predeterminados. Cree una función de inicialización con el mismo tipo que la estructura. Este enfoque es muy útil al dividir código grande en archivos separados.

struct structType{
  int flag;
};

struct structType InitializeMyStruct(){
    struct structType structInitialized;
    structInitialized.flag = 3;
    return(structInitialized); 
};


int main(){
    struct structType MyStruct = InitializeMyStruct();
};
Agricultor
fuente
0

Puedes crear una función para ello:

typedef struct {
    int id;
    char name;
} employee;

void set_iv(employee *em);

int main(){
    employee em0; set_iv(&em0);
}

void set_iv(employee *em){
    (*em).id = 0;
    (*em).name = "none";
}
José Peña
fuente
0

Otro enfoque, si la estructura lo permite, es usar un #define con los valores predeterminados dentro:

#define MYSTRUCT_INIT { 0, 0, true }

typedef struct
{
    int id;
    int flag;
    bool foo;
} MyStruct;

Utilizar:

MyStruct val = MYSTRUCT_INIT;
CSharpino
fuente