结构体字节对齐,C语言结构体字节对齐详解
发布时间:2020-12-15 17:34:26 所属栏目:百科 来源:网络整理
导读:问大家一个问题: struct STUDENT{ char a; int b;}data; 如上结构体变量 data 占多少字节?char 占 1 字节,int 占 4 字节,所以总共占 5 字节吗?我们写一个程序验证一下: # include stdio.hstruct STUDENT{ char a; int b;}data;int main(void){ printf("
问大家一个问题:
struct STUDENT { char a; int b; }data;如上结构体变量 data 占多少字节?char 占 1 字节,int 占 4 字节,所以总共占 5 字节吗?我们写一个程序验证一下: # include <stdio.h> struct STUDENT { char a; int b; }data; int main(void) { printf("%p,%pn",&data.a,&data.b); //%p是取地址输出控制符 printf("%dn",sizeof(data)); return 0; }输出结果是: 00427E68,00427E6C 8 我们看到 data 不是占 5 字节,而是占 8 字节。变量 a 的地址是从 00427E68 到 00427E6B,占 4字 节;变量 b 的地址是从 00427E6C 到 00427E6F,也占 4 字节。b 占 4 字节我们能理解,但 a 是 char 型,char 型不是占 1 字节吗,这里为什么占 4 字节?其实不是它占了 4 字节,它占的还是 1 字节,只不过结构体中有一个字节对齐的概念。 什么叫字节对齐?我们知道结构体是一种构造数据类型,里面可以有不同数据类型的成员。在这些成员中,不同的数据类型所占的内存空间是不同的。那么系统是怎么给结构体变量的成员分配内存的呢?或者说这些成员在内存中是如何存储的呢?通过上面这个例子我们知道肯定不是顺序存储的。 那么到底是怎么存储的呢?就是按字节对齐的方式存储的!即以结构体成员中占内存最多的数据类型所占的字节数为标准,所有的成员在分配内存时都要与这个长度对齐。我们举一个例子:我们以上面这个程序为例,结构体变量 data 的成员中占内存最多的数据类型是 int 型,其占 4 字节的内存空间,那么所有成员在分配内存时都要与 4 字节的长度对齐。也就是说,虽然 char 只占 1 字节,但是为了与 4 字节的长度对齐,它后面的 3 字节都会空着,即:
所谓空着其实也不是里面真的什么都没有,它就同定义了一个变量但没有初始化一样,里面是一个很小的、负的填充字。为了便于表达,我们就暂且称之为空好了。 如果结构体成员为: struct STUDENT { char a; char b; int c; }data;那么这三个成员是怎么对齐的?a 和 b 后面都是空 3 字节吗?不是!如果没有 b,那么 a 后面就空 3 字节,有了 b 则 b 就接着 a 后面填充。即:
所以这时候结构体变量 data 仍占 8 字节。我们写一个程序验证一下: # include <stdio.h> struct STUDENT { char a; char b; int c; }data; int main(void) { printf("%p,%p,&data.b,&data.c); //%p是取地址输出控制符 printf("%dn",00427E69,00427E6C
即总共占 12 字节。我们写一个程序验证一下: # include <stdio.h> struct STUDENT { char a; char b; char c; char d; char e; int f; }data; int main(void) { printf("%p,&data.c,&data.d,&data.e,&data.f); //%p是取地址输出控制符 printf("%dn",00427E6A,00427E6B,00427E6C,00427E70
下面写一个程序验证一下: # include <stdio.h> struct STUDENT { char a; int b; char c; }data; int main(void) { printf("%p,00427E70
总共 24 字节,我们写一个程序验证一下: # include <stdio.h> struct STUDENT { char name[10]; int age; char sex; float score; }data; int main(void) { printf("%p,&data.name[0],&data.name[1],&data.name[2],&data.name[3],&data.name[4],&data.name[5],&data.name[6],&data.name[7],&data.name[8],&data.name[9],&data.age,&data.sex,&data.score); printf("%dn",00427E6D,00427E6E, |
推荐文章
站长推荐
热点阅读