Iterating Over a Struct in C++

C method for iterating through a struct's members like an array?

If all of your structure fields are of the same type, you could use a union as following:

typedef union vec3_u
{
struct vec3_s {
float x, y, z;
};
float vect3_a[3];
}
vec3;

This way you could access to each x, y or z field independently or iterate over them using the vect3_a array. This solution cost nothing in term of memory or computation but we may be a bit far from a C++ like solution.

iterating through a struct in c

In *ptr++, the ++ has higher precedence than the *, so this post-increments the pointer, and reads and discards the value originally pointed to. Now that the pointer has been incremented, you are reading uninitialized memory in the printf. If your intention was to increment the value being pointed at, try:

(*ptr)++;

Or

ptr[0]++;

Edit

Hmm, since your loop bound is based upon the number of bools that fit in the size of the struct, maybe your intention was to increment the pointer. In which case, you don't need to dereference it at the same time, and you shouldn't expect to get anything meaningful in the printf. Also, as pointed out, since the struct is not an array, you will be wandering into undefined behavior land since the compiler may decide to add padding:

From C99 §6.7.2.1:

12 Each non-bit-field member of a structure or union object is aligned in an implementation- defined manner appropriate to its type.

13 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

Iterating over same type struct members in C

The easiest way would be to create a union, one part which contains each member individually and one part which contains an array. I'm not sure if platform-dependent padding might interfere with the alignment.

How to loop through structure members?

The best way is probably type punning over union. It allows you to use the same memory area with different variable representations, for example by giving each struct member individual names, while at the same time remaining able to loop through them.

#include <stdio.h>

typedef union {
struct // anonymous struct, requires standard C compiler
{
int a;
int b;
int c;
};
int array[3];
} Example;


int main (void)
{
Example ex = { .a=1, .b=2, .c=3 };

for(size_t i=0; i<3; i++)
{
printf("%d\n", ex.array[i]);
}
}

If you can't change the struct definition, then the second best is some pointer arithmetic through a character type. This takes much more care though, so that you don't end up writing code with poorly-defined behavior - you need to be aware of things like alignment and strict aliasing. Character types are preferred to work with in case the struct turns more complex with different types of members, because character types are safe from aliasing issues.

Assuming uint8_t is a character type, then:

#include <stdio.h>
#include <stdint.h>

typedef union {
struct
{
int a;
int b;
int c;
};
} Example;


int main (void)
{
Example ex = { .a=1, .b=2, .c=3 };
uint8_t* begin = (uint8_t*)&ex;
uint8_t* end = begin + sizeof ex;


for(uint8_t* i=begin; i!=end; i+=sizeof(int))
{
printf("%d\n", *(int*)i);
}
}

Is there any way to loop through a struct with elements of different types in C?

I'm not sure what you want to achieve, but you can use X-Macros and have the preprocessor doing the iteration over all the fields of a structure:

//--- 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;
}

This will print :

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

You can also add the name of the function to be invoked in the X_FIELDS...



Related Topics



Leave a reply



Submit