在日常学习、工作或生活中,大家总少不了接触作文或者范文吧,通过文章可以把我们那些零零散散的思想,聚集在一块。范文怎么写才能发挥它最大的作用呢?接下来小编就给大家介绍一下优秀的范文该怎么写,我们一起来看一看吧。
c语言结构体中的结构体篇一
q:关于结构体的对齐,到底遵循什么原则?
a:首先先不讨论结构体按多少字节对齐,先看看只以1字节对齐的情况:
#include
#include
#define print_d(intvalue) printf(#intvalue" is %dn", (intvalue));#define offset(struct,member) ((char *)&((struct *)0)->member - (char *)0)#pragma pack(1)typedef struct{ char sex; short score; int age;}student;int main(){ print_d(sizeof(student)) print_d(offset(student,sex)) print_d(offset(student,score)) print_d(offset(student,age)) return 0;}
输出:sizeof(student) is 7offset(student,sex) is 0offset(student,score) is 1offset(student,age) is 3
可以看到,如果按1字节对齐,那么结构体内部的成员紧密排列,sizeof(char) == 1, sizeof(short) == 2, sizeof(int) == 4.
修改上面的代码, 去掉#pragma pack语句,代码如下:
#include
#include
#define print_d(intvalue) printf(#intvalue" is %dn", (intvalue));#define offset(struct,member) ((char *)&((struct *)0)->member - (char *)0)typedef struct{ char sex; short score; int age;}student;int main(){ print_d(sizeof(student)) print_d(offset(student,sex)) print_d(offset(student,score)) print_d(offset(student,age)) return 0;}
运行结果:sizeof(student) is 8offset(student,sex) is 0offset(student,score) is 2offset(student,age) is 4
此时,各个成员之间就不像之前那样紧密排列了,而是有一些缝隙。这里需要介绍下对齐原则:
此原则是在没有#pragma pack语句作用时的原则(不同平台可能会有不同):
原则a:struct或者union的成员,第一个成员在偏移0的位置,之后的每个成员的起始位置必须是当前成员大小的整数倍;
原则b:如果结构体a含有结构体成员b,那么b的起始位置必须是b中最大元素大小整数倍地址;
原则c:结构体的总大小,必须是内部最大成员的整数倍;
依据上面3个原则,我们来具体分析下: sex在偏移0处,占1字节;score是short类型,占2字节,score必须以2的整数倍为起始位置,所以它的起始位置为2; age为int类型,大小为4字节,它必须以4的整数倍为起始位置,因为前面有sex占1字节,填充的1字节和score占2字节,地址4已经是4的整数倍,所以age的位置为4.最后,总大小为4的倍数,不用继续填充。
继续修改上面的代码,增加#pragma pack语句:
#include
#include
#define print_d(intvalue) printf(#intvalue" is %dn", (intvalue));#define offset(struct, member) ((char *)&((struct *)0)->member - (char *)0)#pragma pack(4)typedef struct{ char sex; short score; int age;}student;int main(){ print_d(sizeof(student)) print_d(offset(student,sex)) print_d(offset(student,score)) print_d(offset(student,age)) return 0;}
运行结果:sizeof(student) is 8offset(student,sex) is 0offset(student,score) is 2offset(student,age) is 4
具体分析下:
有了#pragma pack(4)语句后,之前说的原则a和c就不适用了。实际对齐原则是自身对齐值(成员sizeof大小)和指定对齐值(#pragma pack指定的对齐大小)的较小者。依次原则,sex依然偏移为0, 自身对齐值为1,指定对齐值为4,所以实际对齐为1; score成员自身对齐值为2,指定对齐值为4,实际对齐为2;所以前面的sex后面将填充一个1字节,然后是score的位置,它的偏移为2;age自身对齐值为4,指定对齐为4,所以实际对齐值为4;前面的sex和score正好占用4字节,所以age接着存放;它的偏移为4.
q:关于位域的问题,空域到底表示什么?
a:它表示之后的位域从新空间开始。
#include
#include
#define print_d(intvalue) printf(#intvalue" is %dn", (intvalue));#define offset(struct, member) ((char *)&((struct *)0)->member - (char *)0)typedef struct { int a : 1; int b : 3; int : 0; int d : 2;}bit_info;int main(){ print_d(sizeof(bit_info)) return 0;}
运行结果:sizeof(bit_info) is 8
bit_info中的a, b占用4个字节的前4位,到int:0; 时表示此时将填充余下所有没有填充的'位,即刚刚的4个字节的余下28位;int d:2; 将从第四个字节开始填充,又会占用4个字节,所以总大小为8.
再来看下面几个小例子
例1:
struct a{ char f1 : 3; char f2 : 4; char f3 : 5; };
a b c
a的内存布局:111,1111 *,11111 * * *
位域类型为char,第1个字节仅能容纳下f1和f2,所以f2被压缩到第1个字节中,而f3只能从下一个字节开始。因此sizeof(a)的结果为2。
例2:
struct b{ char f1 : 3; short f2 : 4; char f3 : 5; };
由于相邻位域类型不同,在vc6中其sizeof为6,在dev-c++中为2。
例3:
struct c{ char f1 : 3; char f2; char f3 : 5; };
非位域字段穿插在其中,不会产生压缩,在vc6和dev-c++中得到的大小均为3。
考虑一个问题,为什么要设计内存对齐的处理方式呢?如果体系结构是不对齐的,成员将会一个挨一个存储,显然对齐更浪费了空间。那么为什么要使用对齐呢?体系结构的对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。假设一个体系结构的字长为w,那么它同时就假设了在这种体系结构上对宽度为w的数据的处理最频繁也是最重要的。它的设计也是从优先提高对w位数据操作的效率来考虑的。有兴趣的可以google一下,人家就可以跟你解释的,一大堆的道理。
最后顺便提一点,在设计结构体的时候,一般会尊照一个习惯,就是把占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以相对节约一些对齐空间。
s("content_relate");【讲解c语言编程中的结构体对齐】相关文章:
1.
初步剖析c语言编程中的结构体
2.c语言编程中使用设计模式中的原型模式的讲解
3.c语言结构体(struct)常见使用方法
4.c语言结构体(struct)常见使用方法
5.如何学好c语言编程
6.怎么学习c语言编程
7.怎样学习c++c语言编程
8.c语言高效编程的方法
【本文地址:http://www.pourbars.com/zuowen/2797660.html】