printf("%ld %ld\n",sizeof(me),sizeof(*me));//output is 8 80 how??
其实应该是:
printf("%zu %zu\n",sizeof(me),sizeof(*me));//output is 8 80 how??
"%zu"
是size_t
值的正确格式字符串,例如您从sizeof
. "%ld"
可能碰巧在某些系统上工作(显然它在你的系统上),但你不应该指望这一点。
如果您的编译器不支持"%zu"
,您可以使用"%lu"
(需要一个unsigned long
参数)并显式转换参数:
printf("%lu %lu\n", (unsigned long)sizeof(me), (unsigned long)sizeof(*me));
你得到8
了sizeof(me)
因为这恰好是你正在使用的编译器上的指针大小(8 字节,64 位)。如果您在不同的系统上编译并运行您的程序,您可能会得到4
,因为很多系统都有 32 位指针。(这假设一个字节是 8 位,这对于大多数系统都是正确的,但语言不能保证。)
大多数编译器使所有指针大小相同,但这也不是由语言保证的。例如,在字寻址的机器上,int*
指针可能只是一个机器级地址,但char*
指针可能需要额外的信息来指定它指向的字中的哪个字节。您不太可能遇到指针大小不同的系统,但假设所有指针大小相同仍然没有意义。
至于结构的大小,也可能因编译器而异。这是你的结构:
struct krishna {
int i,j,k,l,m;
char c;
double d;
char g[48];
};
char
总是正好是 1 个字节,并且char[48]
总是正好是 48 个字节。
an 中的字节数int
可能因系统而异;如今,4 个字节是最常见的。
a 的大小double
通常为 8 字节,但这也可能有所不同(尽管我认为我从未见过sizeof (double)
不是 8 字节的系统。)
结构成员按声明它们的顺序排列,因此您的i
will 位于结构的最开始,然后是j
, k
,依此类推。
最后,编译器通常会在成员之间或最后一个成员之后插入填充字节,以便每个成员正确对齐。例如,在许多系统上,一个 4 字节int
需要在一个 4 字节的倍数的偏移处对齐;如果它未对齐,访问它可能会很慢和/或非常困难。
在您的系统上sizeof (struct krishna)
恰好是 80 字节的事实并不是那么重要。更重要的是理解 (a) 编译器用来确定结构布局方式的一般规则,以及 (b) 这些规则可能导致不同系统的不同布局这一事实。
语言定义和您的编译器保证您可以拥有 type 的对象struct krishna
,并且您可以访问这些对象及其成员,并取回您存储在其中的任何值。如果你想知道 a 有多大struct krishna
,答案很简单sizeof (struct krishna)
。如果由于某种原因,您需要了解更多细节(例如,如果您需要匹配一些外部强加的布局),您可以做一些实验和/或查阅编译器的文档——但请注意具体情况将适用仅适用于您在使用它的系统上使用的编译器。(通常,您系统的ABI会限制编译器的选择。)
您还可以使用sizeof
and offsetof
(查找)来找出每个成员的分配位置。