结构体的数组成员变量对齐

来源:互联网 发布:女童皮短裙淘宝 编辑:程序博客网 时间:2024/06/05 06:59

#pragma pack 默认值 通常是8

#pragma pack规定的对齐长度,实际使用的规则是:

结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。

也就是说,当#pragma pack的值等于或超过所有数据成员长度的时候,这个值的大小将不产生任何效果。

而结构整体的对齐,则按照结构体中最大的数据成员 #pragma pack指定值之间,较小的那个进行。

//************************ stone ***

#include <stdio.h>#pragma pack(8)int main(int argc, const char * argv[]){struct P1 { //结构体模数 = 2 cmp 8 = 2;(取最小值作为模数)short a[3]; // 2char b[3]; // 1} p1;    //2*3 + 3*1 = 9 结构体大小至少是这个数    //对齐就是加0, 加多少这个结构体就增大多少而已.    //0-5 内存空间是a的,因为short a[3],2*3, 下标从0开始,所以    //成员1的大小刚好是 成员2的起始地址值, 起始地址必须是数据类型长度的整数倍.    //按照这个规律...6肯定是1的整数倍了, 所以不用加0    //排完了 长度是9 , 9再与模数判断, 9是否是模数的整数倍? 9不是2的整数倍, 填补一个0 变成10 , 10是2的整数倍,    // 所以长度是10    //内存中得表现    //a0a0 a0bb    //b0    // 64位CPU 一次读取8个字节,内存对齐是为了提高效率而设计的. 这样就 只读取两次就能拿到全部数据了.struct P2 {//结构体模数 = 8 cmp 8 = 8;(取最小值作为结构体模数)short a[3];//2char * b[3];//8 指针类型是 8个字节} p2;    // len = 2*3 + 8*3 = 30 至少是这个数    // 0~5 a[3] , 下标6 是否是8的整数倍? 不是, 要添加2个0 +2    // 8~32 b[3], 30+2 是否是模数的整数倍? 是, 长度 = 32;    // 内存中得表现    // a0a0 a000    // b000 0000    // b000 0000    // b000 0000struct P3 { //结构体模数 = 8 cmp 8 = 8int b; // 4struct P2 a[2];//结构体的数据类型长度用,结构体成员中得最大的数据类型长度 = 8struct P1 c[2]; // 2} p3;    // len = 4+2*10+2*32 = 88 至少是这个数    // 0~3 b, 下标4 是否是 8的整数倍? 否,加4个0, +4    // 8~71 a[2] , 下标72 是否是2的整数倍?是, 什么也不做    // len = 88 +4 = 92, 是否是模数的整数倍? 92不是8的整数倍,加4个0 , 96是8的整数倍, len = 96    // 内存中得表现    // b000 a0a0    // a000 0000    // b000 0000    // b000 0000    // b000 0000    // a0a0 a000    // b000 0000    // b000 0000    // b000 0000    // a0a0 a0bb    // b0a0 a0a0    // bbb0 0000struct P4 {struct P2 * a;int b;struct P1 c[2];} p4;struct P5 {char a;double b;char c;} p5;printf("p1 = %lu\n", sizeof(p1));printf("p2 = %lu\n", sizeof(p2));printf("p3 = %lu\n", sizeof(p3));printf("p4 = %lu\n", sizeof(p4));printf("p5 = %lu\n", sizeof(p5));return 0;}


0 0
原创粉丝点击