2012-01-18 29 views
3

当我在一个结构中定义一个字符类型时,它似乎需要多于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 

为什么,我看到的地址之间的4个字节的区别变量“名称”和变量“价格”?

运行此程序的系统是运行Fedora-14的x86_64位版本。

+0

编译器打包结构以便数据成员正确对齐,并且程序可以快速运行。由于对齐不准确,某些芯片(ARM)只会失效,其他(x86)则运行速度较慢。 – Lalaland 2012-01-18 06:20:09

+0

在64位机内存字创建的64位,因为它是32位的32位地址 x86_64 – 2012-01-18 06:21:56

+0

@RashmiKantShrivastwa感谢您的答复,将阅读更多关于填充 – mrashok 2012-01-18 06:37:34

回答

11

C标准允许实现向结构中添加额外的填充位,以便按照该实现的要求将其与字节边界对齐,从而更快地访问结构。

这就是着名的Structure Padding

鉴于上述结构的大小可能不同于单个成员的大小的总和。您应始终使用sizeof来确定结构的大小。

此外,上面提到的是,您没有看到放置在您期望它们在内存地址的结构成员。

+0

谢谢@Als,现在我明白了 – mrashok 2012-01-18 06:36:39

+3

@ user1150645:不,问题:)做[接受一个答案](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work),你觉得以最好的方式回答你的问题。 – 2012-01-18 07:01:16

3

您正在运行对齐规则。这是一个非常特定于编译器和系统的东西,但默认情况下(即除非您在代码中使用编译器标志或特殊对齐请求来指定),则x64 Linux上的GCC会将结构的每个字段与其多个尺寸。所以,一个字符的字节没有什么特别担心对齐。但是,int或float总是放在4字节边界上,而double总是放在8字节边界上。这就是你在这里看到的。

正如Ethan在注释中所述,某些处理器甚至不会访问未按照某种方式对齐的内存对象,而且如果未对齐,英特尔处理器将访问内存的速度会更慢。

+0

为您的答复,现在我明白了为什么我看到这种行为。非常感谢 – mrashok 2012-01-18 06:38:49

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之后是在上述结构7,3,1和0字节上的SPARC机器以及x86_64机器上。

0

C中的“char”通常需要8位(一个字节)。

然而,在一个结构体一个炭“对齐”上的字,双字或甚四字边界:

http://en.wikipedia.org/wiki/Data_structure_alignment

存在可用于强制对准到4,2或1个字节编译器指令(这规避了这种行为)。

例如,在Visual C++中,可以说“#pragma pack(1)”。

相关问题