益田附近网站建设,做电商到底如何赚钱,网站建设实施步骤,东营交通信息网官网复习下struct的大小、成员偏移量offsetof#xff0c;说下我的理解#xff1a;
64位下默认对齐数default8原则1#xff1a;struct中每一个成员变量tmp的对齐数realmin{default,tmp}
struct Student {int num;//0char name[8];double score;
} stu;
这个结构体stu中#x…复习下struct的大小、成员偏移量offsetof说下我的理解
64位下默认对齐数default8原则1struct中每一个成员变量tmp的对齐数realmin{default,tmp}
struct Student {int num;//0char name[8];double score;
} stu;
这个结构体stu中第一个成员num为int的对齐数real_nummin{8,4}4。 第二个成员name为char类型对齐数real_namemin{8,1}1。 第三个成员score为double类型对齐数real_scoremin{8,8}8。原则2偏移量offsetof必须是real的倍数 1所以第一个成员num偏移量startid0*real_num0*40从startid开始size14即4个bytes被用掉即[id0~3已用]。
2因为上面size14已用4个bytes。第二个成员name偏移量是startidreal_name*倍数1*倍数3故此时倍数取4所以偏移量startid4而name的size28所以id4~11已用。 3因为上面size1size212已用12个bytes。而第三个成员score的偏移量startidreal_score*倍数8*倍数必需11所以倍数不能取0或1只能取2所以startid8*216即从16开始放score而score的大小size38此时id16~23已用。所以stu这个结构体在内存中就是如下的样子
所以stu的size等于id0一直到id23即size24。所以逻辑是先计算偏移量再自然计算得到struct整体的大小。
struct Test1 {int x;double y;
} t1;
struct Test2 {int x;char y[8];
} t2;
在t1中对x来说 real_xmin{8,4}4 偏移量startidreal_x*倍数4*00,size14,id0~3被使用。 在t1中对y来说 real_ymin{8,8}8偏移量startidreal_y*倍数8*倍数同时必需3所以倍数就是1startid8。
当你换成char y[8]后如结构体t2所示对y来说real_ymin{8,1}1 偏移量startidreal_y*倍数1*倍数同时必需3所以倍数就是4startid4。
由此可见t1和t2偏移量不一样所以struct的size是不一样的。虽然它们的成员变量都是4bytes、8bytes但终究偏移量不同导致了结构体大小的不同。
原则3struct的对齐数等于其所有成员real对齐数的最大值。
所以对于结构体嵌套结构体的情况我们易知:
struct Student {int num;char name[8];double score;
};struct CombineStudent {short memb;Student originstruct[2];char lastmem[3];
} comstu;
现在结构体Student由之前分析知结构体的size为24字节作为新结构体comstu的成员且个数为2的数组originstruct。 根据原则3结构体Student的对齐数real_stumax(real_numreal_namereal_score)max(4,1,8)8
对于结构体comstu 1第一个成员memb为short的对齐数real_memmin{8,2}2。偏移量startid0*real_mem0*20 而short占2字节即[id0~1已用]。
2第二个成员originstruct为Student类型对齐数real_originstructmin{8,8}8偏移量startid倍数*real_originstruct倍数*8必须1故倍数1即偏移量startid1*88。而每个Student占24字节现在有2个Student即[id8~824*2-1也就是8~55已用]。 3第三个成员lastmem为char类型对齐数real_lastmemmin{8,1}1偏移量startid倍数*real_lastmem倍数*1,必须55故倍数取56即可startid56而每个char占1字节现在共3个共id56~58已用。但你以为结构体comstu的大小就是id0~5859吗天真还有原则4
原则4结构体的总大小size必须是对齐数real的整数倍
所以虽然上面的结构体comstu的id0~5859但结构体CombineStudent的real_comstumax(real_membreal_originstructreal_lastmem)max(2,8,1)8但是我们之前算好的59并不是real_comstu的整数倍所以后面必须要补几位直到占到id63即id0~63总size64才是CombineStudent的大小
所以大家这下明白为啥C建议我们定义变量时按从一定的顺序去定如换个位置
struct Combine2Student {short memb;char lastmem[3];Student originstruct[2];
} ;
刚刚的结构体CombineStudent如果换成这样结果就不一样了可以节约内存。大家可以算算
real_membmin{8,2}2size12startid0是real_memb的倍数占id0~1
real_lastmemmin{8,1}1size23startid2是real_lastmem的倍数占id2~4
real_originstructmin{8,8}8size324*248startid8是real_originstruct的倍数占id8~55
算到这里总id0~5556已经是real_Combine2Studentmax(real_membreal_lastmem,real_originstruct)max(2,8,1)8的倍数了所以不需再补所以结构体Combine2Student的size56
调换位置后命名相同的三个成员但结构体Combine2Student就是比ComebineStudent占内存少