结构:struct
结构是由程序员自己设计的一种数据类型,用于描述一种事物的各项数据,由若干项不同的基础数据类型组成
设计结构类型:
struct 结构类型名
{
类型名1 成员名1;
类型名2 成员名2;
...
}; // 分号不能少
定义结构变量:
struct 结构类型名 结构变量;
注意:在C语言中定义结构变量时,struct不能省略
初始化结构变量:
struct 结构类型名 结构变量 = {val1,val2,val3,...};
注意:初始化的顺序要与结构成员顺序一致
struct 结构类型名 结构变量 = {.成员名=val1,...};
注意:可以不按顺序初始化某些成员
struct 结构类型名 结构变量 = 同类型的结构变量;
注意:同类型结构变量可以直接整体初始化或赋值
访问成员:
结构变量.成员名;
由于结构变量的字节数一般都比较大,值传递效率较低,因此一般传递结构变量的地址,访问成员需要使用->,此时结构变量共享后有被修改的风险,一般通过const保护
结构指针->成员名;
typedef重定义结构类型
typedef struct 结构类型名 结构类型名;
之后就可以不使用struct关键字了
typedef struct 结构类型名
{
类型名1 成员名1;
类型名2 成员名2;
...
}结构类型名;
注意:一般结构变量存储在堆内存较为合适
如何计算结构的总字节数:
结构成员的顺序会影响它的总字节数,在设计结构时合理地安排成员的顺序可能会大大地节约内存
内存对齐:
假设第一个成员从零地址开始,存储每个成员的地址编号必须能被它的类型字节数整除,如果不能整除,则会填充空白字节数直到能整除为止
内存补齐:
结构的总字节数,必须是它最大成员类型字节数的整数倍,如果不是,则会在末尾填充空白字节直到是为止
注意:数组成员按照元素类型字节数计算,不会根据数组总长度计算
注意:在32位Linux系统中计算结构体的对齐、补齐时,如果成员的字节数超过4字节则按照4字节数计算
在Windows系统、64位的Linux系统中,按照实际字节数计算对齐补齐
#pragma pack(n) 设置对齐、补齐的最大字节数
n == 1\2\4
联合:union
联合的使用方式与结构基本一致,与结构的区别是联合中所有成员共用同一块内存,一个成员的值发生改变,其它所有成员的值都随之变化
union 类型名
{
类型名 成员1;
};
联合的目的是为了使用少量的内存对应多个标识符名,从而达到节约内存的目标,现在基本不再使用联合
联合的常考笔试题:
1、联合是天然对齐的,但是还要考虑补齐问题
union Data
{
char ch[5];
int num;
}; //总字节数8
2、通过联合可以判断系统是大端系统还是小端系统?
如何判断系统的大小端问题?
假设十六进制数0x01020304存储0xA~0xD连续的4字节内存中
大端系统:高位数据存储在低位地址
(0xA:01 0xB:02 0xC:03 0xD:04)
小端系统:高位数据存储高位地址
(0xA:04 0xB:03 0xC:02 0xD:01)
个人PC一般都是小端系统,而UNIX服务器和网络设备都是大端
本地数据称为本地字节序、网络设备数据称为网络字节序,因此数据的上传下载都需要转换字节序
JSON
sprintf
sscanf
100 "100" -> 100 200->"200" 200
枚举:enum
枚举就是把一种数据类型中可能出现的所有数值全部罗列出来,并且取一个有意义的名字,如果该枚举类型变量的值等于其它值则非法(愿望)
注意:在C语言编译器中,为了编译速度,不会专门去检查枚举变量的值,因此给枚举变量赋值没有限制
但是g++编译器严格限制,必须使用枚举常量赋值
枚举可以看做是值受限的int类型,在C语言中只是锦上添花
枚举常量与宏常量区别?
1、枚举常量需要占用内存,宏常量只是声明不需要占用内存
2、枚举常量具有类型,宏常量没有类型
3、枚举常量设计的目的是为了限制实际数据的使用,而宏定义是为了完成代码的替换和维护