sizeof 字节的对齐,位域sizeof的计算

合集下载

C语言结构体字节对齐简单计算方法

C语言结构体字节对齐简单计算方法

C语⾔结构体字节对齐简单计算⽅法
1.在C语⾔⾥⾯每⼀种数据类型都有字节对齐⽐如在32位操作系统下:整型的⾃⾝对齐数就是 4 字节,字符型就是 1 字节,double就是 8 字节。

但是结构体的计算⽅式就和普通的数据类型不⼀样。

在C语⾔⾥⾯字节对齐的⽅式主要根据“有效对齐数”来确定,那么有效对齐数是怎杨确定的呢?
在结构体⾥⾯::: 有效字节对齐数 = (⾃⾝对齐数 < 最⼤字节)?(⾃⾝对齐数):(最⼤字节);
⾃⾝对齐数 = 4字节(32位操作系统);(8 字节为32位操作系统)。

最⼤字节数 = 结构体⾥⾯最⼤的⼀个数据类型所占的字节数。

列:struct test{
char a;
int a;
short c;
}d;
sizeof(d) == ? ; //在32位操作系统下为12字节,64位操作系统下也为12字节。

(每⼀次都开4个字节)
struct test2{
char a;
double b;
short c;
}d;
sizeof(d) == ? ;// 在32位操作系统下为16字节(每⼀次开4个字节),在64位操作系统下为24字节(每⼀次开8个字节)。

VC_Sizeof

VC_Sizeof

VC的sizeof、字节对齐、位域见到N多的笔试题目考到相关内容,作题目时老是非常迷糊,索性一怒,狂看,终于有所得。

在这做个总结:一、VC默认方式的字节对齐:1.数据成员对齐规则:在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量:sizeof(类型)或其倍数2.整体对齐规则:结构的总大小也有个约束条件:最大sizeof(类型)的整数倍如:struct MyStruct{char dda;double dda1;int type};//sizeof=1+7+8+4+4=24二、自己设定字节对齐方式VC中提供了#pragma pack(n)来设定变量以n字节对齐方式。

1.数据成员对齐规则:n字节对齐就是说变量存放的起始地址的偏移量:min(sizeof(类型),对齐方式)或其倍数.2.整体对齐规则:结构的总大小也有个约束条件:min(最大的sizeof(类型),对齐方式)的倍数.#pragma pack(push) //保存对齐状态#pragma pack(4)//设定为4字节对齐struct test{char m1; //默认偏移量double m4;//非默认偏移量int m3; //默认偏移量}; //sizeof=1+3+8+4=16应为4的倍数#pragma pack(pop)//恢复对齐状态#pragma pack(push) //保存对齐状态#pragma pack(16)//设定为4字节对齐struct test{char m1;//默认偏移量double m4;//默认偏移量int m3;//默认偏移量}; //sizeof=1+7+8+4+4=24应为8的倍数。

#pragma pack(pop)//恢复对齐状态三、sizeof简单应用1.参数为数据类型或者为一般变量。

例如sizeof(int),sizeof(long)等等。

这种情况要注意的是不同系统系统或者不同编译器得到的结果可能是不同的。

关于字节对齐的sizeof的讨论

关于字节对齐的sizeof的讨论

关于字节对齐的sizeof的讨论众所周知,程序为了提高访问效率,编译器在编译的时候,进行字节对齐。

程序员也可以字节指定对齐方式。

Win32下的为progma指令,具体来说#pragma pack(push) //保存原对齐状态#pragma pack(4)//设定为4字节对齐struct test{int a;};#pragma pack(pop)//恢复对齐状态在linux下,gcc是默认的编译器。

g++ 支持progma指令,gcc也支持GNU扩展__attribute__指令参考《__attribute__》,对于字节对齐的举例为struct test{short b[3];} __attribute__ ((aligned (8)));__attribute__还支持aligned 和packed ,解释如下__attribute__ ((aligned)); 选择针对目标机器最大的对齐方式,可以提高拷贝操作的效率。

aligned属性使被设置的对象占用更多的空间,相反的,使用packed可以减小对象占用的空间。

需要注意的是,attribute属性的效力与你的连接器也有关,如果你的连接器最大只支持16字节对齐,那么你此时定义32字节对齐也是无济于事的。

__attribute__ ((packed))使用该属性可以使得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐。

下面以pragma 来讨论指定结构体对齐方式!总的来说规律如下#pragma pack(n)来设定变量以n字节对齐方式。

n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。

结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。

字节对齐(强制对齐以及自然对齐)

字节对齐(强制对齐以及自然对齐)

字节对齐(强制对齐以及⾃然对齐)struct {}node;32为的x86,window下VC下sizeof(node)的值为1,⽽linux的gcc下值为0;⼀、WINDOWS下(VC--其实GCC和其原理基本⼀样,象这种问题,⼀般要查具体的编译器设置)字节对齐的规则:1、⼀般设置的对齐⽅式为1,2,4字节对齐⽅式,VC⼀般默认为4字节(最⼤为8字节)。

结构的⾸地址必须是结构内最宽类型的整数倍地址;另外,结构体的每⼀个成员起始地址必须是⾃⾝类型⼤⼩的整数倍(需要特别注意的是windows下是这样的,但在linux的gcc编译器下最⾼为4字节对齐),否则在前⼀类型后补0;这⾥特别提到的是数组⼀定要注意,⽽且在⼀些编程的技巧中,我们可以使⽤数组强制字节达到对齐的⽬的。

这在⽹络编程中是很常见的。

举例:⽐如CHAR型占⽤空间为1字节,则其起始位置必须可被1整除。

INT为4字节,其起始位置必须被4带队,依次类推。

(我们假定类或结构体的起始位置为0位置,其实编译器是在开辟空间时,会寻找起始位置可被结构内最宽类型整除的地址做为开始地址,因此我们可以假定其为0值,因为这0值可以被任意的类型整除。

)2、结构体的整体⼤⼩必须可被对齐值整除,默认4(默认,且结构中的类型⼤⼩都⼩于默认的4)。

3、结构体的整体⼤⼩必须可被本结构内的最宽类型整除。

(其实和上⼀条是⼀样的,但这⾥独⽴出来,起注意作⽤。

⽐如结构体⾥的有DOUBLE,那么结构的⼤⼩最后必须可被8整除)注意:GCC不是这样,就是最⾼只能被4整除,它是个死的。

否则(2、3条),编译器会在结构的最后添充⼀定的特定字符来补齐。

struct T{char ch;double d ;};在VC中是16个字节,GCC中为12个字节。

4、对于结构体内嵌套结构体的形势,规定是必须按照基本数据类型来定义,⽽不能以嵌套结构⼤⼩来做为上三种使⽤的基准。

⼆、举例:struct A{int a;char b;short c;};struct B{char b;int a;short c;};struct C{double t;char b;int a;short c;};struct D{char b;double t;int a;short c;};在VC中,SIZEOF这四个结构体,分别为:8、12、24、24;我们先谈第⼀个,(说明⼀下,在考虑结构体⼤⼩时,我们基本可以忽略起始地址的问题,因为这个编译器会⾃动为我们做好,见上⾯的说明),结构体内⾸先是⼀个INT的4字节,起始地址假定为0,整除4,其⼩于等于默认的4字节对齐且0为4(INT的占⽤空间)的整数倍,所以,其占四个字节;其后为起始地址为5,空间为1个字节的CHAR,⼩于4且5为1(CHAR占⽤空间)的整数倍,故占⽤1个字节,然后是⼀个起始地址为5占2个字节的SHORT,其⼩于4,但5不为2的整数倍,故补齐⼀个字节,从第6个字节开始,占2字节空间。

C语言中sizeof的用法总结

C语言中sizeof的用法总结

C语言中sizeof的用法总结一、sizeof的概念sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。

它并不是函数。

sizeof操作符以字节形式给出了其操作数的存储大小。

操作数可以是一个表达式或括在括号内的类型名。

操作数的存储大小由操作数的类型决定。

二、sizeof的使用方法1、用于数据类型sizeof使用形式:sizeof(type)数据类型必须用括号括住。

如sizeof(int)。

2、用于变量sizeof使用形式:sizeof(var_name)或sizeof var_name变量名可以不用括号括住。

如sizeof (var_name),sizeof var_name等都是正确形式。

带括号的用法更普遍,大多数程序员采用这种形式。

注意:sizeof操作符不能用于函数类型,不完全类型或位字段。

不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。

如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式。

三、sizeof的结果sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。

该类型保证能容纳实现所建立的最大对象的字节大小。

1、若操作数具有类型char、unsigned char或signed char,其结果等于1。

ANSI C正式规定字符类型为1字节。

2、int、unsigned int 、short int、unsigned short 、long int 、unsigned long 、float、double、long double类型的sizeof 在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2、2、2、2、4、4、4、8、10。

一篇文章带你了解C语言内存对齐公式

一篇文章带你了解C语言内存对齐公式

⼀篇⽂章带你了解C语⾔内存对齐公式⽬录⼀、前⾔⼆、公式2.1、例⼦⼀2.2、例⼦⼆2.3、例⼦三总结⼀、前⾔每⼀个特定平台上的编译器都有⾃⼰的默认“对齐系数”(也叫对齐模数)。

GCC中默认#program pack(4),即4个字节的内存对齐。

Keil也是采⽤4字节对齐的。

也可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这⼀系数,⼀般情况下尽量使⽤⾃然对齐系数,不要修改它。

STM32单⽚机上各个变量占⽤的字节数:⼆、公式公式⼀、结构体变量⾥,成员的起始地址必须满⾜:起始地址 % 成员的字节数(sizeof值)= 0 (说⽩了就是能整除)公式⼆、结构体变量的总字节数必须满⾜:总字节数 % 最⼤的成员字节数 = 0 (说⽩了就是能整除)2.1、例⼦⼀struct te_a{/* 公式⼀ */char a; /* a的起始地址0x00,然后⽤公式⼀计算:0x00 % 1(char为1个字节) = 0,所以成员a占⽤了内存0x00 */int b; /* b的起始地址0x01 % 4(int为4个字节)不等于0,那么再计算0x02%4还是不等于0,直到0x04 % 4 = 0 ,所以成员b占⽤了内存0x04 ~ 0x07 */char c; /* 成员b的结尾地址是0x07,所以成员c从0x08开始计算,那么计算0x08 % 1 = 0 , 所以成员c占⽤了内存0x08 */}Test1;OK,经过公式⼀的运算后,结构体⾥成员的分布如下:经过公式⼀的计算后,结构体变量Test1的⼤⼩是9个字节。

内存对齐的计算还没有结束,接着使⽤公式⼆计算:结构体变量的总字节数 % 最⼤的成员字节数 = 0 ,在结构体变量Test1⾥,最⼤的成员是b,b的⼤⼩是4个字节。

那么,当前的结构体变量⼤⼩9字节 % 4字节等于 0 。

当结构体变量⼤⼩为12字节 % 4字节 = 0,所以最终结构体变量Test1占⽤的内存字节数是12,其内存的分布如下:以上的都是根据公式计算出来的结果,那实际在单⽚机⾥是不是这样呢?把代码下载到STM32单⽚机⾥,进⼊DEBUG模式看看。

sizeof与字节对齐

sizeof与字节对齐

sizeof的用法sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着“辛苦我一个,幸福千万人”的伟大思想,我决定将其尽可能详细的总结一下。

但当我总结的时候才发现,这个问题既可以简单,又可以复杂,所以本文有的地方并不适合初学者,甚至都没有必要大作文章。

但如果你想“知其然,更知其所以然”的话,那么这篇文章对你或许有所帮助。

菜鸟我对C++的掌握尚未深入,其中不乏错误,欢迎各位指正啊1. 定义:sizeof是何方神圣sizeof乃C/C++中的一个操作符(operator)是也,简单的说其作用就是返回一个对象或者类型所占的内存字节数。

MSDN上的解释为:The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t.其返回值类型为size_t,在头文件stddef.h中定义。

这是一个依赖于编译系统的值,一般定义为typedef unsigned int size_t;世上编译器林林总总,但作为一个规范,它们都会保证char、signed char和unsigned char的sizeof值为1,毕竟char是我们编程能用的最小数据类型。

2. 语法:sizeof有三种语法形式,如下:1) sizeof( object ); // sizeof( 对象 );2) sizeof( type_name ); // sizeof( 类型 );3) sizeof object; // sizeof 对象;所以,int i;sizeof( i ); // oksizeof i; // oksizeof( int ); // oksizeof int; // error既然写法3可以用写法1代替,为求形式统一以及减少我们大脑的负担,第3种写法,忘掉它吧!实际上,sizeof计算对象的大小也是转换成对对象类型的计算,也就是说,同种类型的不同对象其sizeof值都是一致的。

c语言结构体大小的计算公式

c语言结构体大小的计算公式

c语言结构体大小的计算公式C语言中的结构体是一种自定义的数据类型,它可以由不同类型的数据组成,用于表示一个复杂的数据结构。

在使用结构体时,我们需要了解它的大小,以便在内存中合理地分配空间。

本文将介绍计算C语言结构体大小的公式,并对其进行详细解析。

在C语言中,结构体的大小由其成员变量的大小决定。

常见的成员变量类型包括整型、浮点型、字符型、指针型等。

不同的数据类型在内存中占用的空间大小是不同的,因此结构体的大小也会受到成员变量类型的影响。

计算结构体大小的公式如下:```sizeof(结构体类型) = 对齐后的第一个成员变量的偏移量 + 结构体中所有成员变量的大小之和```其中,对齐后的第一个成员变量的偏移量是指结构体中第一个成员变量相对于结构体起始地址的偏移量。

在计算结构体大小时,编译器会根据对齐规则对结构体进行对齐,以提高访问效率。

对于结构体中的每个成员变量,编译器会根据其数据类型和对齐规则来确定其大小。

对齐规则是由编译器和编译选项决定的,不同的编译器和编译选项可能会有不同的对齐规则。

在计算结构体大小时,需要注意以下几点:1. 结构体的大小是成员变量大小的总和,不包括对齐字节。

2. 结构体的大小可能会受到编译器和编译选项的影响,不同的编译器和编译选项可能得到不同的结果。

3. 结构体的大小通常是按字节对齐的,即结构体的大小必须是成员变量大小的整数倍。

下面通过一个示例来说明结构体大小的计算方法:```c#include <stdio.h>struct Student {int id;char name[20];float score;};int main() {printf("Sizeof(struct Student) = %zu\n", sizeof(struct Student));return 0;}```在上述示例中,我们定义了一个名为`struct Student`的结构体,它包含三个成员变量:一个整型变量`id`、一个字符数组`name`和一个浮点型变量`score`。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2,所以有效对齐值也是 2,可以存放在 0x0008 到 0x0009 这两个字节空间中, 符合 0x0008%2=0。所以从 0x0000 到 0x0009 存放的都是 B 内容。再看数据结 构 B 的自身对齐值为其变量中最大对齐值(这里是 b)所以就是 4,所以结构体 的有效对齐值也是 4。根据结构体圆整的要求,0x0009 到 0x0000=10 字节,(10 +2)%4=0。所以 0x0000A 到 0x000B 也为结构体 B 所占用。故 B 从 0x0000 到 0x000B 共有 12 个字节,sizeof(struct B)=12;其实如果就这一个就来说它已将 满足字节对齐了,因为它的起始地址是 0,因此肯定是对齐的,之所以在后面补充 2 个字节,是因为编译器为了实现结构数组的存取效率,试想如果我们定义了一个结 构 B 的数组,那么第一个结构起始地址是 0 没有问题,但是第二个结构呢?按照数 组的定义,数组中所有元素都是紧挨着的,如果我们不把结构的大小补充为 4 的整 数倍,那么下一个结构的起始地址将是 0x0000A,这显然不能满足结构的地址对 齐了,因此我们要把结构补充成有效对齐大小的整数倍.其实诸如:对于 char 型数 据,其自身对齐值为 1,对于 short 型为 2,对于 int,float,double 类型,其自身 对齐值为 4,这些已有类型的自身对齐值也是基于数组考虑的,只是因为这些类型 的长度已知了,所以他们的自身对齐值也就已知了.
代码中关于对齐的隐患,很多是隐式的。比如在强制类型转换的时候。例如: unsigned int i = 0x12345678; unsigned char *p=NULL; unsigned short *p1=NULL; p=&i; *p=0x00; p1=(unsigned short *)(p+1); *p1=0x0000; 最后两句代码,从奇数边界去访问 unsignedshort 型变量,显然不符合对齐的规 定。 在 x86 上,类似的操作只会影响效率,但是在 MIPS 或者 sparc 上,可能就是一 个 error,因为它们要求必须字节对齐. 八.如何查找与字节对齐方面的问题: 如果出现对齐或者赋值问题首先查看 1. 编译器的 big little 端设置 2. 看这种体系本身是否支持非对齐访问 3. 如果支持看设置了对齐与否,如果没有则看访问时需要加某些特殊的修饰来标 志其特殊访问操作。 九.相关文章:转自 /goodluckyxl/archive/2005/10/17/506827.aspx ARM 下的对齐处理 from DUI0067D_ADS1_2_CompLib 3.13 type qulifiers 有部分摘自 ARM 编译器文档对齐部分 对齐的使用: 1.__align(num)
如果在编程的时候要考虑节约空间的话,那么我们只需要假定结构的首地址 是 0,然后各个变量按照上面的原则进行排列即可,基本的原则就是把结构中的变 量按照 类型大小从小到大声明,尽量减少中间的填补空间.还有一种就是为了以空间换取 时间的效率,我们显示的进行填补空间进行对齐,比如:有一种使用空间换时间做 法是显式的插入 reserved 成员:
还是让我们来看看例子。
示例 1: struct BF1 {
char f1 : 3; char f2 : 4; char f3 : 5; }; 其内存布局为: |__f1___|____f2___ |__|____f3______|______| |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__| 位域类型为 char,第 1 个字节仅能容纳下 f1 和 f2,所以 f2 被压缩到第 1 个字节 中,而 f3 只 能从下一个字节开始。因此 sizeof(BF1)的结果为 2。 示例 2: struct BF2 { char f1 : 3; short f2 : 4; char f3 : 5; }; 由于相邻位域类型不同,在 VC6 中其 sizeof 为 6,在 Dev-C++中为 2。 示例 3:
struct BF3 {
char f1 : 3; char f2; char f3 : 5; }; 非位域字段穿插在其中,不会产生压缩,在 VC6 和 Dev-C++中得到的大小均为 3。
五.如何修改编译器的默认对齐值? 1.在 VC IDE 中,可以这样修改:[Project]|[Settings],c/c++选项卡 Category 的 Code Generation 选项的 Struct Member Alignment 中修改,默认是 8 字节。 2.在编码时,可以这样动态修改:#pragma pack .注意:是 pragma 而不是 progma. 六.针对字节对齐,我们在编程中如何考虑?
sizeof 字节的对齐,位域 sizeof 的计算
分类: 技术 2009-03-23 21:45 1411 人阅读 评论(0) 收藏 举报
struct 编译器数据结构 alignmentfloat 汇编
一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型的
面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍; 3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6 采取 不压缩方式,Dev-C++和 GCC 采取压缩方式; 4) 如果位域字段之间穿插着非位域字段,则不进行压缩; 5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
struct A{ char a; char reserved[3];//使用空间换时间 int b;
}
reserved 成员对我们的程序没有什么意义,它只是起到填补空间以达到字节对齐 的目的,当然即使不加这个成员通常编译器也会给我们自动填补对齐,我们自己加
上它只是起到显式的提醒作用. 七.字节对齐可能带来的隐患:
变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常 在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列, 而不是顺序的一个接一个的排放,这就是对齐。
对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些 平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的 CPU 在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程 必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适 合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每 次读都是从偶地址开始,如果一个 int 型(假设为 32 位系统)如果存放在偶地 址开始的地方,那么一个读周期就可以读出这 32bit,而如果存放在奇地址开始 的地方,就需要 2 个读周期,并对两次读出的结果的高低字节进行拼凑才能得到 该 32bit 数据。显然在读取效率上下降很多。
#pragma pack () /*取消指定对齐,恢复缺省对齐*/ sizeof(struct C)值是 8。 修改对齐值为 1: #pragma pack (1) /*指定按 1 字节对齐*/ struct D {
char b; int a; short c; }; #pragma pack () /*取消指定对齐,恢复缺省对齐*/ sizeof(struct D)值为 7。 后面我们再讲解#pragma pack()的作用. 三.编译器是按照什么样的原则进行对齐的? 先让我们看四个重要的基本概念: 1.数据类型自身的对齐值: 对于 char 型数据,其自身对齐值为 1,对于 short 型为 2,对于 int,float,double 类型,其自身对齐值为 4,单位字节。 2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。 3.指定对齐值:#pragma pack (value)时的指定对齐值 value。 4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。 有 了这些值,我们就可以很方便的来讨论具体数据结构的成员和其自身的对齐 方式。有效对齐值 N 是最终用来决定数据存放地址方式的值,最重要。有效对 齐 N,就是表示“对齐在 N 上”,也就是说该数据的"存放起始地址%N=0".而数据 结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址 就是数据结构的起始地址。结构体的成员变量要对齐排放,结构体本身也要根据 自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对 齐值的整数倍,结合下面例子理解)。这样就不能理解上面的几个例子的值了。 例子分析:
同理,分析上面例子 C: #pragma pack (2) /*指定按 2 字节对齐*/ struct C {
char b; int a; short c; }; #pragma pack () /*取消指定对齐,恢复缺省对齐*/ 第 一个变量 b 的自身对齐值为 1,指定对齐值为 2,所以,其有效对齐值为 1, 假设 C 从 0x0000 开始,那么 b 存放在 0x0000,符合 0x0000%1= 0;第二个变量,自身对齐值为 4,指定对齐值为 2,所以有效对齐值为 2,所以 顺序存放在 0x0002、0x0003、0x0004、0x0005 四个连续 字节中,符合 0x0002%2=0。第三个变量 c 的自身对齐值为 2,所以有效对齐值 为 2,顺序存放 在 0x0006、0x0007 中,符合 0x0006%2=0。所以从 0x0000 到 0x00007 共八字节存放的是 C 的变量。又 C 的自身对齐值为 4,所以 C 的有效对齐值为 2。又 8%2=0,C 只占用 0x0000 到 0x0007 的八个字节。所以 sizeof(struct C)=8.
二.字节对齐对程序的影响: 先让我们看几个例子吧(32bit,x86 环境,gcc 编译器):
设结构体如下定义: struct A {
int a; char b; c;
相关文档
最新文档