我发现这个事情有点棘手,并且递归有关sizeof运算符如何计算链表中一个节点的大小。我将以下结构作为列表中的一个节点,例如:
struct ll_core
{
char c_ll;
struct ll_core * next;
};
printf("size of struct ll_core = %d\n\n",sizeof(struct ll_core));
它给出了答案8.现在它如何决定大小8,因为要添加单个struct元素的大小,它会再次遇到相同的struct ll_core。所以它在计算大小时是一种循环或递归。请原谅,让我知道,如果我这样想,我是否会遗漏任何基本的东西。
答案 0 :(得分:3)
它不再需要struct的大小,因为struct只包含结构的指针,而不是结构本身。
“指向struct ll_core
的指针”的大小与struct ll_core
的大小无关,它们是两种不同的类型。一个是指针,另一个不是。
你不能声明一个“真正的”递归数据结构,因为它是无限的。
答案 1 :(得分:2)
因为要添加单个struct元素的大小,它会再次遇到相同的
struct ll_core
。
不,它遇到{em>指针到struct ll_core
。如果遇到结构本身,那将导致无限大小。编译器知道struct ll_core *
的大小和对齐要求,即使不了解struct ll_core
,也可以添加成员的大小加上对齐所需的填充(next
成员在这种情况下)找到struct ll_core
的大小。
答案 2 :(得分:2)
假设您在32位机器上运行代码,指针的大小将为4个字节。由于结构将在字边界上对齐,因此将填充3个字节,因此大小将为8个字节。
这个结构实际上就像,
struct ll_core{
char c_11:
char const byte[3]; //padded bytes for alignment reasons
struct ll_core *next;
};
答案 3 :(得分:1)
struct ll_core
{
char c_ll;
struct ll_core * next;
};
sizeof
运算符会添加结构ll_core
成员的大小。这是一个字符(c_ll
)和一个指针(next
)。
有关如何计算大小的更多信息。
结构填充:
在64位系统中,数据将以8字节块的形式读写。因此,当计算结构的大小时,就会发生填充。意味着编译器将在结构的成员之间插入一些间隙以“对齐”到体系结构地址边界。如下:
struct ll_core
{
char c_ll;
/* 7 bytes of padding */
struct ll_core * next;
};
因此,64位系统中此结构的大小将为16个字节。
结构包装:
您可以通过执行结构打包来阻止编译器执行结构填充。在GCC中,它是这样完成的:
struct __attribute__((__packed__)) ll_core
{
char c_ll;
struct ll_core * next;
};
现在,64位计算机上的大小将为9个字节。
sizeof(char) + sizeof(pointer)
编辑 - 从您的问题看来,您似乎在32位计算机上运行。在32位机器中,数据将作为4字节块读取和写入。
答案 4 :(得分:0)
如果某些类型在某些地址上对齐,许多处理器的效果会更好。这意味着编译器在单个char
元素之后填充结构,以便指针位于本机字边界上。
至于结构中的“递归”,没有,因为next
字段是结构的指针,而不是结构本身。
答案 5 :(得分:0)
你错过了这一点,仔细看......“下一个”只是一个指针。 你不能只做'struct ll_core next'..那就是没有*。所以,只要它是一个指针。 将仅针对指针的大小计算大小。通常,指针大小为4。
如果您有任何疑惑,请从下一步中删除 * ,然后尝试编译代码。
答案 6 :(得分:0)
有2个元素是char(大小为1)和指针(大小为4),因此您认为大小为5,但结构填充为4个字节(字大小)。 char填充为4个字节,总共为8个字节。