¿Hay alguna forma de recorrer una estructura con elementos de diferentes tipos en C?

3 minutos de lectura

avatar de usuario
drigoSkalWalker

mi estructura es algo así

typedef struct {
  type1 thing;
  type2 thing2;
  ...
  typeN thingN;
} my_struct 

¿Cómo enumerar struct childs en un bucle como while o for?

  • que operación le quieres hacer a cada uno?

    – Ramónster

    23 de noviembre de 2009 a las 17:48

  • No puedo ver por qué querrías recorrer diferentes tipos. ¿Cada tipo no requiere una operación diferente? Por favor explique.

    – Al sr

    23 de noviembre de 2009 a las 17:49

  • curiosidad, tengo una función que acepta un valor con el orden de los hijos de una estructura, ejemplo, función (“cadena1”, “cadena2”, 1 // este es el índice de niños de la estructura) en el cuerpo de la función, lo sé, donde mantendré los parámetros de las cadenas, sé que puedo pasar el puntero a los niños que quiero, pero creo que esa es otra forma. gracias por toda respuesta

    – drigoSkalWalker

    23 de noviembre de 2009 a las 17:53

avatar de usuario
filante

No estoy seguro de lo que quieres lograr, pero puedes usar X-macros y hacer que el preprocesador haga la iteración sobre todos los campos de una estructura:

//--- first describe the structure, the fields, their types and how to print them
#define X_FIELDS \
    X(int, field1, "%d") \
    X(int, field2, "%d") \
    X(char, field3, "%c") \
    X(char *, field4, "%s")

//--- define the structure, the X macro will be expanded once per field
typedef struct {
#define X(type, name, format) type name;
    X_FIELDS
#undef X
} mystruct;

void iterate(mystruct *aStruct)
{
//--- "iterate" over all the fields of the structure
#define X(type, name, format) \
         printf("mystruct.%s is "format"\n", #name, aStruct->name);
X_FIELDS
#undef X
}

//--- demonstrate
int main(int ac, char**av)
{
    mystruct a = { 0, 1, 'a', "hello"};
    iterate(&a);
    return 0;
}

Esto imprimirá:

mystruct.field1 is 0
mystruct.field2 is 1
mystruct.field3 is a
mystruct.field4 is hello

También puede agregar el nombre de la función que se invocará en X_FIELDS…

  • X-Macro fue una revelación para mí. Se siente un poco sucio, pero un poco correcto. ¡Gracias!

    – KarateSnowMachine

    20 de abril de 2012 a las 6:09

avatar de usuario
Brian R. Bondy

No existe una forma segura de enumerar los miembros de una estructura, a menos que se conozca el contenido exacto de la estructura, e incluso en ese caso, debe tener cuidado con cosas como la alineación/relleno de la estructura.

Dependiendo de su problema, podría ser más seguro tener una matriz de su estructura.

Dado que planea manejarlos en un bucle, supongo que los diferentes tipos pueden al menos tratarse de la misma manera o tener tamaños similares.

Si este es el caso, su elección dependerá del tamaño de los elementos. Si son todos iguales, puede recuperar un puntero a la estructura, convertirlo en uno de sus tipos e incrementarlo hasta que “agote” toda la estructura.

PD: De hecho, no es una práctica muy segura. Esta situación se manejó mucho mejor con un enfoque OO, aprovechando el polimorfismo. De lo contrario, no hay garantías sobre la alineación como se mencionó anteriormente.

No hay forma de iterar a través de los miembros de la estructura en lenguaje C, independientemente de si tienen el mismo tamaño/tipo o diferentes tamaños/tipos.

Como referencia, puede recorrer los elementos de la estructura utilizando la aritmética de punteros, si son del mismo tipo:

typedef struct numbers{
    int a;
    int b;
    int c;
} numbers;

numbers nums;

nums.a = 42;
nums.b = 99;
nums.c = 23;

int count = sizeof(nums) / sizeof(int);  // 3

for(int i=0; i < count; i++){
    printf("%d ", *(&nums.a + i) );      // start on the first field's address
}

¿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