迭代C中相同类型的struct成员

是否可以使用指针迭代C结构,其中所有成员都是相同类型。 这是一些不编译的示例代码:

#include  #include  typedef struct { int mem1 ; int mem2 ; int mem3 ; int mem4 ; } foo ; void my_func( foo* data ) { int i ; int* tmp = data ; // This line is the problem for( i = 0; i < 4; ++i ) { ++tmp ; printf( "%d\n", *tmp ) ; } } int main() { foo my_foo ; // my_foo.mem1 = 0 ; my_foo.mem2 = 1 ; my_foo.mem3 = 2 ; my_foo.mem4 = 3 ; // my_func( &my_foo ) ; return 0 ; } 

假设您的编译器/内核不尝试为缓冲区溢出提供堆栈保护,则foo的成员应该在内存中一个接一个地对齐。

所以我的问题是:

我将如何迭代相同类型的C结构的成员。

最简单的方法是创建一个联合,一个部分包含每个成员,一个部分包含一个数组。 我不确定平台相关的填充是否会干扰对齐。

使用带arrays的并集的大多数尝试都很容易失败。 只要你只使用int,它们就有很好的工作机会,但对于其他类型,特别是较小的类型,它们可能会经常失败,因为编译器可以(特别是对于较小的类型通常会)在成员之间添加填充。一个struct ,但是不允许使用数组元素这样做。

但是,C确实有一个可以使用的offsetof()宏。 它会产生struct项目的偏移量,因此您可以创建一个偏移数组,然后(在投射时要小心)您可以将该偏移量添加到结构的地址以获取该成员的地址。 在转换中的注意是因为偏移量是以字节为单位,因此您需要将struct的地址强制转换为char * ,然后添加偏移量,然后将结果转换为成员的类型(在您的情况下为int )。

从语言的角度来看:你做不到。 结构的数据成员在C中不是……呃……“可迭代的”,无论它们是相同类型还是不同类型。

使用数组而不是一堆独立成员。

您还可以使用未命名的union / struct:

 struct foo { union { struct { int mem1; int mem2; int mem3; int mem4; }; int elements[4]; }; }; foo thefoo; for (int i = 0; i < 4; ++i) { thefoo.elements[i] = i; } 

这可能不适用于某些编译器,在这种情况下,您必须在foo明确命名union和struct,

  int* tmp = &data->mem1 ; // explicitly get the address of the first int member 

如你所说,你必须小心对齐和其他内存布局问题。 你应该很好用int做这个。

但我会质疑这会使您的代码具有可读性。

顺便说一句,

  tmp += ( i * sizeof(foo) ) ; 

我认为这不符合你的想法,但我不完全确定你想要它做什么。 使用++tmp; 如果你想步入同一个foo对象的下一个int成员。

这是另一种方法; 我从来没有理由这样做,但它的优点是不会破坏结构定义。 创建一个指向您感兴趣的成员的指针数组,然后迭代该数组:

 typedef struct { int mem1; int mem2; int mem3, int mem4; } foo; ... foo theStruct; int *structMembers[4] = { &theStruct.mem1, &theStruct.mem2, &theStruct.mem3, &theStruct.mem4}; ... for (i = 0; i < 4; i++) { printf("%d\n", *structMembers[i]); } 

这样你就不必担心咬你的对齐问题了,你可以任意命令你想要迭代成员的方式(例如,你可以订购它,所以walk是“mem4,mem3,mem2,mem1”)。

您应该能够将foo指针强制转换为int指针。

一个更清洁的解决方案是声明foo如下。

 typedef struct { int fooints[ 4 ] ; } foo ; 

然后迭代int数组。

 for ( int i = 0 ; i < 4 ; i++ ) { printf( "%d\n" , *( foo->fooints + i ) ) ; } 

您可以继续创建成员函数来访问和/或操作int数组。