当我在结构中定义字符类型时,它似乎需要超过1个字节;实际上它似乎需要4个字节。
以下是我的计划:
#include <stdio.h>
int main(void)
{
struct book{
char name;
float price;
int pages;
};
struct book b1={'B',130.00,550};
printf("\nAddress of structure:%u",&b1);
printf("\nAddress of character name:%u",&b1.name);
printf("\nAddress of float price:%u",&b1.price);
printf("\nAddress of integer pages:%u",&b1.pages);
printf("\n\n");
return 0;
}
当我运行上述程序时,我得到以下输出:
Address of structure:557762432
Address of character name:557762432
Address of float price:557762436
Address of integer pages:557762440
为什么我看到变量“name”的地址和变量“price”之间的4个字节的差异?
运行该程序的系统是运行Fedora-14的x86_64位。
答案 0 :(得分:11)
C标准允许实现向结构添加额外的填充位,以便通过使其与该实现所需的字节边界对齐来更快地访问结构。
这称为 Structure Padding 。
鉴于上述情况,结构的大小可能与各个成员的大小总和不同。您应该始终使用sizeof
来确定结构的大小。
此外,上面提到的原因是您没有看到结构成员放置在您期望它们所在的内存地址。
答案 1 :(得分:3)
您正在遇到对齐规则。这是一个非常特定于编译器和系统的东西,但默认情况下(即,除非您在代码中使用编译器标志或特殊对齐请求另行指定)x64 Linux上的GCC将结构的每个字段对齐其大小的倍数。因此,一个字符的字节没有特别担心对齐。但是,int或float始终位于4字节边界上,而double始终位于8字节边界上。这就是你在这里看到的。
正如Ethan在评论中指出的那样,某些处理器甚至不会访问未以某种方式对齐的内存对象,如果未对齐,英特尔处理器将更慢地访问内存。
答案 2 :(得分:0)
严格地说,char
总是占用一个字节,但可能后跟0或更多字节填充。填充多少取决于编译器和CPU,以及结构中char
之后的类型对齐,以及任何有效的打包编译指示。如果N字节类型必须是N字节对齐的,例如在SPARC上,那么:
struct s16 { char c; double d; };
struct s8 { char c; long l; };
struct s4 { char c; short s; };
struct s2 { char c; char b; };
单个char
后面是SPARC机器上面结构中的7,3,1和0字节,也是x86_64机器上的。{/ p>
答案 3 :(得分:0)
C中的“char”通常需要8位(一个字节)。
但是,结构中的char在单词,双字或甚至四字边界上“对齐”:
http://en.wikipedia.org/wiki/Data_structure_alignment
有一些编译器指令可用于强制对齐为4,2或1个字节(这会绕过这种行为)。
例如,在Visual C ++中,您可以说“#pragma pack(1)”。