假设我的代码是:
typedef stuct {
int x;
double y;
char z;
} Foo;
Run Code Online (Sandbox Code Playgroud)
会x,y以及z,在内存旁边对方?指针算术可以“迭代”它们吗?我的 C 生锈了,所以我不能完全正确地测试这个程序。这是我的完整代码。
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int x;
double y;
char z;
} Foo;
int main() {
Foo *f = malloc(sizeof(Foo));
f->x = 10;
f->y = 30.0;
f->z = 'c';
// Pointer to iterate.
for(int i = 0; i == sizeof(Foo); i++) {
if (i == 0) {
printf(*(f + i));
}
else if (i == (sizeof(int) + 1)) {
printf(*(f + i));
}
else if (i ==(sizeof(int) + sizeof(double) + 1)) {
printf(*(f + i));
}
else {
continue;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*lli 14
不,不能保证struct成员在内存中是连续的。
从 C 标准中的第 6.7.2.1 点第 15 点开始(此处为第 115 页):
结构对象内可能有未命名的填充,但不是在其开头。
大多数时候,类似于:
struct mystruct {
int a;
char b;
int c;
};
Run Code Online (Sandbox Code Playgroud)
确实与 对齐sizeof(int),如下所示:
0 1 2 3 4 5 6 7 8 9 10 11
[a ][b][padding][c ]
Run Code Online (Sandbox Code Playgroud)
Kei*_*son 10
是和否。
是的,结构的成员被分配在一个连续的内存块中。在您的示例中,类型的对象Foo占用sizeof (Foo)内存的连续字节,并且所有成员都在该字节序列内。
但是不,不能保证成员本身彼此相邻。任何两个成员之间或最后一个成员之后都可以有填充字节。该标准确实保证第一个定义的成员位于偏移量 0 处,并且所有成员都按照定义的顺序分配(这意味着有时可以通过对成员重新排序来节省空间)。
所以你不能(直接)迭代结构的成员。如果您想这样做,并且所有成员都属于同一类型,请使用数组。
您可以使用offsetof定义在 中的宏<stddef.h>来确定(非位域)成员的字节偏移量,有时使用它来构建可用于迭代结构成员的数据结构会很有用。但它很乏味,而且很少比简单地按名称引用成员更有用——特别是如果它们具有不同的类型。