一、枚举与#define宏的区别
1、#define宏常量是在预编译阶段进行简单替换,枚举常量则是在编译的时候确定其值
2、一般在编译器里,可以调试枚举常量,但是不能调试宏常量。
3、枚举可以一次定义大量相关的常量,而#define宏一次只能定义一个
二、联合体
在结构中各成员有各自内容的内存空间,一个结构变量的总长度是各成员长度之和;而在联合中,各成员共享一段内存空间,一个联合变量长度等于各成员中最长的长度。联合变量可以被赋予任一成员值,每次只能赋予一种值,赋入新值冲去旧值。
三、结构体
1、定义:在网络协议、通信控制、嵌入式系统、驱动开发等地方,我们经常要传送的不是简单的字节流(char型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体。
2、需要结构体方面
1)如果所需要传送的内容依顺序保存在char型数组中,通过指针偏移的方法传送网络报文等消息。这样做一旦控制方式及通信协议有所变化,程序就要进行非常细致的修改,非常容易出错。这个时候需要结构体。
2)要求函数的参数尽量不多于4个,如果函数参数多于4个使用起来非常容易出错(包括每个参数的意义和顺序都容易弄错),效率也会降低(与具体CPU有关,ARM芯片对于超过4个参数的处理就有讲究)。这时,可以用结构体压缩参数个数。
3、结构体与数组比较
都由多个元素组成;
各个元素在内存中的存储空间是连续的;
数组中各个元素的数据类型相同,而结构体中的各个元素的数据类型可以不相同。
4、定义结构体使用
1)一般形式
struct student
{
char name[10];
char sex;
int age;
float score;
};
2)定义结构体类型的变量、指针变量和数组
方法一:定义结构体类型时,同时定义该类型的变量。
struct [student] //【】表示结构体名是可选的
{
char name[10];
char sex;
int age;
float score;
}stu1,*ps,stu[5]; //定义结构体类型的普通变量、指针变量和数组
方法二:先定义结构体类型,再定义该类型的变量
struct student
{
char name[10];
char sex;
int age;
float score;
};
struct student stu1,*ps,stu[5]; //定义结构体类型的普通变量、指针变量和数组
方法三:用类型定义符typedef先给结构体类型命别名,再用别名定义变量
typedef struct [student]
{
char name[10];
char sex;
int age;
float score;
}STU;
STU stu1,*ps,stu[5]; //用别名定义结构体类型的普通变量、指针变量和数组*
3)为结构体变量赋初值
struct [student]
{
char name[10];
char sex;
int age;
float score;
}stu[2] = { { "Li", 'F', 22, 90.5},{"Su", 'M', 20, 88.5} };
4)引用结构体变量中的成员
结构体变量名.成员名,如”stu1.name"。
结构体指针变量->成员名,如“ps->name”。
(*结构体指针变量).成员名,如"(*ps).name"。
结构体变量数组名.成员名,如“stu[0].name"。
5、内存字节对齐
1、解释:在空间与复杂度上达到平衡的一种技术手段,为了在可以接受的空间浪费的前提下,尽可能地提高对相同运算过程的最少(快)处理。
2、结构体需要对其原因
结构体在编译成机器代码后,没有本身集合的概念了。
类实际上是个加强版的结构体,类的对象在实例化时,内存中申请的就是一些变量的空间集合(类似于结构体,同时也不包含函数指针)
集合中每个变量,在使用中都需要涉及加工原则,需要在效率与空间之间做出权衡。
3、方法
typedef struct T
{
char c; //本身字节长度1字节
—int 64 d; //本身字节长度8字节
int e; //本身字节长度4字节
short f; //本身字节长度2字节
char g; //本身字节长度1字节
short h; //本身字节长度2字节
}
内存对齐正式原则
数据类型自身的对齐值:基本数据类型的自身对齐值,等于“sizeof(基本数据类型)”
指定对齐值:“#pragma pack(value)”时的指定对齐值value
结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值
数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的那个值