为了弄清楚嵌套结构在内存中的存储方式,您可以运行以下代码:
#include <stdio.h>
#include <limits.h>
#include <stddef.h>
struct tag1{
int a;
struct tag2{
long b;
} var1;
} var2;
int main(void){
printf("CHAR_BIT is\t\t\t\t%d\n", CHAR_BIT);
puts("");
printf("sizeof var2 is\t\t\t\t%zu\n", sizeof var2);
printf("sizeof var2.var1 is\t\t\t%zu\n", sizeof var2.var1);
printf("sizeof var2.var1.b is\t\t\t%zu\n", sizeof var2.var1.b);
puts("");
printf("offsetof(struct tag1, a) is\t\t%zu\n", offsetof(struct tag1, a));
printf("offsetof(struct tag1, var1) is\t\t%zu\n", offsetof(struct tag1, var1));
printf("offsetof(struct tag1, var1.b) is\t%zu\n", offsetof(struct tag1, var1.b));
printf("offsetof(struct tag2, b) is\t\t%zu\n", offsetof(struct tag2, b));
return 0;
}
我要求你在你的实现上运行这段代码,而不是直接给你一个答案,因为:
- sizeof T 是实现定义的。如果你有
sizeof (long) == 1
和 CHAR_BIT == 32
呢?
- 结构体中可能会有填充位/字节。
- 其他因素。例如,使用
#pragma pack(n)
在我的实现(OS X 下的 clang)上,输出结果为:
CHAR_BIT is 8
sizeof var2 is 16
sizeof var2.var1 is 8
sizeof var2.var1.b is 8
offsetof(struct tag1, a) is 0
offsetof(struct tag1, var1) is 8
offsetof(struct tag1, var1.b) is 8
offsetof(struct tag2, b) is 0
嗯,在这里看起来不整齐,但在我的屏幕上显示时格式很好。
因此(对于我的实现),struct tag1
的内存布局将如下所示:
-----------------------
| | | | | | | | | ---> int a (8 bytes are used)
-----------------------
| | | | | | | | | ---> struct tag2 / long b (8 bytes are used)
-----------------------
offsetof()
宏来查看编译器如何布局不同的结构体。需要注意的是,具体的细节技术上取决于实现。例如,根据long
是否为 64 位类型或 32 位类型,您可能会看到不同之处。 - Michael Burrvar1
只是tag1
结构体内的另一个成员,就像相同结构体内的a
一样。var1
是一个结构体并不重要。因此,如果您想为嵌套结构的第二个示例执行“内存布局示例”,请将嵌套结构放在var1
所在的位置,就像您在第一个示例中放置了b
一样,区别在于您有long var1.b
而不是b
。 - Some programmer dude