union联合:
是一个能在联合同一个存储空间里(但不同时)存储不同类型数据的数据类型。
union u_data {
unsinged char a;
unsigned int b;
} data; 下面是使用联合写的一段程序来判断系统是LSB还是FSBint is_lsb (void)
{
union test
{
unsigned char a;
unsigned int b;
}data;
data.b = 0x12345678;
if(data.b == 0x78)
return 1;
else
return 0;
}
联合的大小为此存储空间中最大的数据类型
枚举enum:
使用枚举类型声明表示整数常量的符号名称。枚举里常量如未赋初值,则按序增长
enum
{
Gold, //Gold = 0
Wood, //wood = 1
Water, //Water = 2
Fire = 8, //Fire = 8
Earth, //Earth = 9
};
switch(five_line)
{
case Gold:
do_something;
break;
default:
break;
}
typedef:
用来定义一种新的数据 例如:typedef unsigned char u8; u8 var1, var2;定义了新的数据类型u8,u8代表的数据类型为unsigned char类型,因此变量var1,var2的数据类型为unsigned char。结构体struct:
结构体可以由基本数据类型构造出一种新的复合数据类型来。定义结构体时没有分配内存,使用结构体时才会开辟内存。 typedef 与struct一起使用可以定义一种新的结构体数据类型:typedef struct _st_student
{
char name[32];
int gender;
int age;
float score;
} st_student ;
定义了一个结构体_st_student,又定义了一种新的数据类型st_student
结构体对齐 自身对齐值: 自身对齐值就是结构体变量里每个成员的自身大小; 指定对齐值: 指定对齐值是由宏#pragma pack (N)指定的值,里面的N必须是2的幂次方, 如1,2,4,8,16等。如果没有通过#pragma pack宏那么在32位的Linux主机上默认指定对 齐值为4,64位的Linux主机上默认指定对齐值为8,ARM CPU默认指定对齐值为8; 有效对齐值: 结构体成员自身对齐时有效对齐值为自身对齐值与指定对齐值中较小的一个, 结构体圆整时,为所有成员中自身对齐值最大的与指定对齐值较小的一个; 步骤: 1, 结构体各成员对齐 2,整个结构体圆整 结构体嵌套: 结构体变量可以嵌套使用,但不能嵌套定义: struct a struct test { { struct b{}; 或 int a; struct test b; }; } 以上两种情况是不允许的。 但是可以嵌套使用:typedef struct _st_score
{
float math;
int english;
int chinese;
}st_score;
typedef struct _student
{
char name[32];
int gender; int age;
st_score score;
st_score *pscore;
}st_student;
st_student student;
st_student *ptr = &student;
student.score.math = 90.0; //变量.变量.变量
student.pscore->math = 90.0 //变量.变量->指针
ptr->scrore.math = 90.0; //指针->变量.变量
ptr->pscore->math = 90.0 //指针->指针->指针
定义了新的数据类型st_score,当在结构体_student时可以将该数据类型st_score当成新的变量进行封装,这就是结构体的嵌套使用;
还有结构体数组,结构体指针,在这里就不多讲了
define宏:
宏操作是按位替换
#define ADD(a,b) a+b #define MUL(a*b) a*b var1 = 5 * ADD(3,4); var2 = MUL(3+4,5);
将程序执行的结果打印:var1 = 19;var2=23;
而不是我们想的var1 = 35, var2 = 35;
这是因为define只能进行简单的替换而不进行计算,因此var1的计算过程:5*3+4=19,var2的计算过程:3+4*5 = 23,想要解决这一问题,那么对应每一个带参数的宏要加上括号。
对一些关键字的比较:
const 与define 的比较
(1)起作用阶段比较:#define是在预处理阶段起作用,而const是在编译、运行时起作用。
(2)起作用方式比较:#define是字符串替换,没有类型检查,const有对应的数据类型,需要进行判断。
(3)储存方式比较:#define在内存中有多个备份,而const定义的只读变量在程序运行过程中只有一份备份。
(4)调试方便程度比较:const常量可以进行调试,而define是不能进行调试的,因为在预处理阶段已经替换掉了。
typedef 与 define 的区别?
·#define是预处理指令,在预处理时进行简单而机械的字符串替换,不作正确性检查,只有在编译已被展开的源程序的时候才会可能报错。
·#typedef是关键字,在编译时处理,有类型检查功能。它在自己的作用域里给一个已经存在的类型一个别名,但不能在一个函数定义里面使用typedef。
| #define | Typedef | |
| 作用阶段 | 预处理阶段 | 编译阶段 |
| 分号 | 没有,是一个宏指令 | 有,是一个语句 |
| 定义 | #define plt int* 定义plt a,b;一个是指针,一个是int | typedef int* plt; 定义plt a,b;会定义两个指针 |
| 作用域 | 如果放在所有函数之外,它的作用域就是从它定义开始直到文件尾; 如果放在某个函数内,定义域就是从定义开始直到该函数结尾; | 不管是在某个函数内,还是在所有函数之外,作用域都是从定义开始直到整个文件结尾。 |
| 检错 | 不能 | 能 |



