博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言---结构体struct---结构体对齐
阅读量:3921 次
发布时间:2019-05-23

本文共 3507 字,大约阅读时间需要 11 分钟。

结构体定义

1、定义一个结构体(顺便实例结构体变量):

struct tag(结构体类型名)			//struct + tag 这两者共同构成了结构体类型  单独的tag(结构体类型名) 不能称之为结构体类型{
成员列表}(结构体变量名);

2、定义的同时使用typedef(相当于定义结构体 + 为结构体起新名字)

typedef struct tag(结构体类型名)			//struct + tag(结构体类型名) ==  结构体类型{
成员列表}mystruct(结构体类型);此时mystruct == struct tag实例化时: 1、C中: struct tag a; //struct + tag 这两者共同构成了结构体类型 单独的tag(结构体类型名) 不能称之为结构体类型 mystruct a; //mystruct(结构体类型) = struct +结构体类型名2、C++中 tag a; 合理 tag和mtstruct均是结构体类型 mystruct a; 合理

结构体定义+结构体变量定义

结构体类型的定义格式为:strcut结构体名{成虽说明列表};

结构体变量的定义有3种形式:
1、定义结构体型的同时定义结构体变量
   如:strcut结构体名{成员说明列表}变量;
2、先定义一个结构体类型,然后使用该类型来定义结构体变量,
   如:strcutstudent{成员说明列表}:student变量;
3、定义一个无名称的结构体类型的同时定义结构体变量
   如:strcutstudent{成员说明列表}变量;

如果在函数内声明→作用域仅限函数内部

可以只初始化一个成员,也可以任意顺序初始化struct boot gift = {
.value=25.99, //使用,分隔           .author="Jime",           0.25 //新的float值0.25替代了旧的值25.99}

结构体内存对齐

意义:内存对齐可以大大提升内存访问速度,是一种用空间换时间的方法。

(内存不对齐会导致每次读取数据都会读取两次,使得内存读取速度减慢。)

1、对齐基本概念

1、数据成员自身的对齐值:

2、结构体/类的自身对齐值:其成员中自身对齐值最大的那个值。
3、对齐系数:#pragma pack (value)时的指定对齐值value。(VS中默认的值为8;linux中的默认值为4。)
4、数据成员、结构体/类的有效对齐值N:自身对齐值和指定对齐值中小的那个值。

仅long和point的长度受到系统环境的影响

在这里插入图片描述

2、内存对齐原则:

1、第一个成员的首地址为0.

2、其余成员的首地址是对齐数的整数倍,对齐数=min(对齐系数,成员自身长度)
3、结构体的总大小,为所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

修改默认对齐数:

预处理指令: #pragma pack(?)
例如:#pragma pack(4)

struct{
char a[10]; 4(char a[4])+4(char a[4]) +4(char a[2] + 2字节)int b; 4(int)short c[3]; 4(short[2])+4(short[1] + 2字节空余)} 故整体结构体的内存对齐为24字节1.下面的结构体大小分别是多大(假设32位机器)?struct A {
char a; //1char b; //1char c; //1};//进行整体对齐,最大类型为1
<对齐系数4,按1整体对齐,所以1+1+1=3 struct b { int a; 4char b; 1short c; 2}; 进行整体对齐,最大类型为4 1+2="3<4" 对齐4 所以4+4="8" c char 1int 4short 1<4(对齐4) 4="4" 2<4(对齐4) 所以4+4+4="12" #pragma pack(2)struct d 1>
对齐系数n(2),所以按2整体对齐 1<2(对齐2)4>2(2的倍数) 2=2 所以2+4+2=8 //4行(每行2字节)// 1字节char 空白1字节// int前半2字节// int后半2字节// short2字节2. 有一个如下的结构体:struct A{
long a1; short a2; int a3; int *a4;}; 答案及解析:2464位编译器下:指针8字节(一定不能忘记),题目不说默认4字节对齐long a1; //8short a2; //2 8+2=10(不是4的倍数)对齐到4的倍数12int a3; //4 4+12=16(4的倍数)int *a4; //8 8+16=24(4的倍数)//6行// long前4字节// long后4字节// short2字节 空白2字节// int4字节// point前4字节// point后4字节 3.在32位cpu上选择缺省对齐的情况下,有如下结构体定义:struct A{
unsigned a : 19; unsigned b : 11; unsigned c : 4; unsigned d : 29; char index;};则sizeof(struct A)的值为16字节题目不说,默认linux对齐系数=4字节对齐19+11=30<32bit 44+29=33>32bit 4+41byte=8bit 1 对齐到 44+4+4+4=16//4行(对齐4字节)// a19位 b11位 空白2位// c4位 空白28位// d29位 空白3位// char1字节 空白3字节
typedef struct bb			//sizeof(BB) == 16字节{
//起始地址对齐值 int id; //4=min(linux默认对齐系数4,int长度4) double weight; //4=min(linux默认对齐系数4,double长度8) float height; //4=min(linux默认对齐系数4,float长度4)}BB;//4行,每行4=double对齐值4= min(linux默认对齐系数4,double长度8)// int4字节// double前4字节// double4字节// float4字节typedef struct aa{
char name[2]; int id; double score; short grade;     BB b; }AA;//9行,每行4字节 此结构体的对齐值 = 该结构体中最大的对齐值,即4// char2字节 空白2字节// int4字节// double前4字节// double后4字节// short2字节 空2字节// 4行BB(每行4字节) BB成员的对齐值 = min(linux对齐参数4,BB长度16) = 4

3、结构体末尾的柔性数组

柔性数组,它只能放在结构体末尾,是申明一个长度为0的数组,就可以使得这个结构体是可变长的。

例如:char data[0];

char data[];
//[]中没有或者0

对于编译器来说,此时长度为0的数组并不占用空间,因为数组名本身不占空间,它只是一个偏移量, 数组名这个符号本身代 表了一个不可修改的地址常量 (注意:数组名永远都不会是指针! ),但对于这个数组的大小,我们可以进行动态分配 请仔细理解后半部分,对于编译器而言,数组名仅仅是一个符号,它不会占用任何空间,它在结构体中,只是代表了一个偏移量,代表一个不可修改的地址常量!

对于0长数组的这个特点,很容易构造出变成结构体,如缓冲区,数据包等等:
注意:构造缓冲区就是方便管理内存缓冲区,减少内存碎片化,它的作用不是标志结构体结束,而是扩展
柔性数组是C99的扩展,简而言之就是一个在struct结构里的标识占位符(不占结构struct的空间)。

意义:1、方便管理内存缓冲区

   2、减少内存碎片化
   3、把单一元素的数组放在一个struct的尾端,使得每个struct对象可以拥有可变大小的数组。

typedef struct list_t{
struct list_t *next; struct list_t *prev; char data[0]; 也可以写成char data[]; 本身不占内存和内存对齐 区别:char data[1];表示长度为1的数组}list_t;

转载地址:http://xyhrn.baihongyu.com/

你可能感兴趣的文章
rmmod命令
查看>>
centos7安装PHP5.5
查看>>
cenos7排错之yum依赖错误处理:清理重复的rpm包
查看>>
php卸载
查看>>
服务器多块网卡绑定后,bond没有起来
查看>>
Nginx安装的前期准备工作
查看>>
nginx 编译参数详解
查看>>
安装nginx
查看>>
Linux之history指令
查看>>
行首行尾字符^$
查看>>
Linux中的. 和*字符
查看>>
linux sed命令详解
查看>>
Shell脚本基本信息
查看>>
xz压缩命令
查看>>
source、sh、bash、./执行脚本的区别
查看>>
centos7安装Apache虚拟主机
查看>>
Job for network.service failed
查看>>
在同一个网络接口上绑定多个IP
查看>>
TreeMap源码分析(基于jdk1.8)
查看>>
中介者模式
查看>>