目录
union联合:
联合是一个能在同一个存储空间里(但不同时)存储不同类型数据的数据类型。
union u_data {
unsinged char a;
unsigned int b;
int 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:
结构体struct:
typedef struct _st_student
{
char name[32];
int gender;
int age;
float score;
} st_student ;
定义了一个结构体_st_student,又定义了一种新的数据类型st_student
结构体对齐
1、结构体(struct)的数据成员,第一个数据成员放在offset为0的位置,以后每个数据成员在对齐数的整数倍的位置。
对齐数=编译器默认的对齐数与该成员大小的较小值。
2、结构体总大小为最大对齐数(每个成员都有一个对齐数)的整数倍。
3、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
//64位系统中
struct A
{
int a;
char b;
double c;
};
//sizeof(A)=16;
struct B
{
char b;
double c;
int a;
};
//sizeof(B)=24
struct A和struct B里面的数据除了顺序不同,里面的数据是一样的,但是编译之后发现它们的结构体长度是不一样的。所以数据的顺序不同结构体的对齐方式也不同,结构体的大小自然不同
struct A :a是4字节,b是1字节,不符合对齐规则,所以b自动补全3个字节刚好和a加起来是8字节完成对齐,c是8字节,所以加起来是16字节
struct B :b是一个字节,不符合对齐规则,不全7个字节完成对齐,c是8个字节,b是4个字节,不符合对齐规则,不全4个字节完成对齐,所以struct B的大小是24
结构体嵌套:
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 //指针->指针->指针
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;会定义两个指针 |
作用域 | 如果放在所有函数之外,它的作用域就是从它定义开始直到文件尾; 如果放在某个函数内,定义域就是从定义开始直到该函数结尾; | 不管是在某个函数内,还是在所有函数之外,作用域都是从定义开始直到整个文件结尾。 |
检错 | 不能 | 能 |