结构:
结构是由程序员自己设计的一种数据类型,用于描述一种事物的各项数据,由若干个不同的基础类型组成
设计:
struct 结构体类型名
{
类型名 成员名;
...
};
定义:
struct 结构体类型名 结构变量名
注意:C语言中在定义结构变量时,struct关键字不能省略
初始化:
struct 结构体类型名 结构变量名={v1,v2,v3...};
注意:必须根据成员的设计顺序初始化
struct 结构体类型名 结构变量名={.成员名1=v1,.成员名2=v2,...};
注意:不需要按照顺序,只初始化某些成员
struct 结构体类型名 结构变量名 = 同类型的结构变量;
注意:同类型的结构体变量可以直接整体赋值
访问成员:
结构体变量名.成员名
结构体指针->成员名:
注意:由于结构体变量一般字节数都较大,普通值传递效率较低,因此一般都传递结构体变量的地址
存储结构变量一般存在堆内存比较合适
typedef重定义结构类型:
typedef struct 结构类型 结构类型;
typedef struct 结构体类型名
{
}结构类型;
如何计算结构体的总字节数
结构体的顺序可能影响它的粽总字节数,因此如果能在设计结构体时合理安排结构成员顺序可以大大地节约内存
内存对齐:
假定第一个成员从零地址开始,存储每个成员的地址编号必须能被该成员类型自己的数整除,如果不能整除则填充空白字节数直到能整除为止
内存补齐:
结构体的总字节数,必须能被它字节数最大的成员整除,如果不能,则在末尾填充空白字节,知道能整除为止
在Linux系统中,计算结构体的对齐和补齐时,通过成员的类型字节数超过4,按照4字节算,
在Windows系统中,会根据实际字节数计算
#pragma pack(n) 设置对齐补齐的最大字节数,在Linux中只有 1和2有效果
联合:union
联合与结构的使用方法基本一致,与结构的区别是所有成员共用一块内存,其中一个成员的值改变,其他成员的值也会随之改变
联合就是想用少量的内存对应较多的标识符,从而可以节约内存的目的,现在基本不再使用
常考的联合笔试题:
union Data
{
char ch[5];
int num;
};
8字节
注意:计算联合的字节数时,虽然不考虑内存对齐,但是依然要考虑内存补齐
如何判断系统的大小端?
假设有十六进制的数据0x01020304,存储在0x0A起始的4字节内存中
小端系统:高位数据存在高位地址
(0A:04 0B:03 0C:02 0D:01)
大端系统:高位数据存在低位地址
(0A:01 0B:02 0C:03 0D:04)
注意:个人计算机一般都是小端,但是UNIX服务器和网络设备都是大端
因此本地数据(本地字节序)传输到网络设备(网络字节序)是时需要进行转化,该转换称为序列化和反序列化(JSON、xml)
168 "168" sprintf sscanf
枚举:enum
枚举类型是希望把一种类型可能出现的所有值罗列出来,并取一个有意义的名字表示,除此之外,该类型的值如果是其他值则非法
注意:gcc不检查是否非法,但g++检查
可以把枚举当做值受限的int类型,但是gcc编译器不检查
注意:如果枚举成员不赋值,成员的值默认从0开始,逐渐+1,如果某个成员设置了值,后续的成员在它的基础上逐渐+1
枚举常量与宏定义的区别:
1、枚举常量需要占用内存,而定义宏常量的定义不占用内存
2、枚举常量的设计目的是为了限制实际数据输入,定义宏是为了完成代码的替换和维护
3、枚举常量是有类型的,宏定义没有类型