一、宏

1.#define的使用

1.1预处理 编译 汇编 链接

1
预处理:gcc define.c -o define.i -E 编译生成.i文件,使代码停留在这个阶段

1.2标识符命名规则

①只能由数字、字母、下划线组成

②不能以数字开头

③不能是C语言关键字

1
5za     _he     xxx    A#a    b^sss    sdfg2    a_af2*   break

1.3 宏延续运算符 \ 表示逻辑上连成一行

1
2
#define d(x, y) x = (7 + \
y + x)

2.define定义常量宏

2.1基本用法

1
2
#define N	100
#define PI 3.14

2.2取消宏标识符PI的声明

1
#undef PI

3.define的带参宏

3.1宏定义的表达式都加上括号,传入参数可能是表达式

1
#define X(a)	((a) * (a))

防止参数类型不一致,typeof(a) 获取表达式a的结果类型,定义一个变量存储它的值 {}把这一段看成一个整体 (void)(&_a == &_b); 检查两个比较参数的类型是否一致,C语言对地址类型非常敏感。

1
2
3
4
5
6
#define MAX(a, b)       \
({typeof(a) _a=a;\
typeof(b) _b=b;\
(void)(&_a == &_b);\
(_a)>(_b) ? (_a) : (_b);})
float max = MAX(23.12, 34.8);

3.2宏定义的#的使用

①#的作用,把传入的参数添加双引号,当作字符串处理

1
2
#define PRI(a, b) printf(#a " and " #b ":We are friend\n")
PRI(123, 456);

输出:123 and 456:We are friend

②##的作用,n##x链接两个字符串

1
2
#define PRI(x) printf("n"#x " = %d\n", n##x);int n1 = 100;
PRI(1);

输出:n1 = 100

③C语言把多个字符串以空格隔开,会看成一个,处理时会链接在一起

1
2
3
char *s = "123 " "456 " "xyz";
printf("%s\n", s);
printf("abc""xyz");

输出:123 456 xyz

abcxyz

④可以用do … while(0)将宏的多条语句这种子串放在一起

1
2
3
4
#define TEST(x, y) do{
x = x+y;
y = y+1;
}while(0)

4.预定义宏

1
2
3
4
5
6
DATE	//预处理日期,格式为“MMM DD YYYY”的字符串
TIME //预处理时间,格式为“HH:MM:SS”的字符串
FILE //当前文件名, 字符串
LINE //当前行号
STDC //当编译器为ANSI标准的时候,则值为1
FUNCTION //当前函数名, 字符串

5.ifdef和ifndef和#if

①ifndef

1
2
3
4
5
#ifndef 宏名
代码块1
#else
代码块2
#endif

②ifdef

1
2
3
4
5
#ifdef 宏名
代码块1
#else
代码块2
#endif

③#if

1
2
3
4
5
6
7
8
9
#if 整型常量表达式1
代码块1
#elif 整型常量表达式2
代码块2
#elif 整型常量表达式3
代码块3
#else
代码块4
#endif

区别:#if后面跟整型常量表达式

表达式为真假,来判断代码编译与否

#ifdef和#ifndef 后面跟宏名

宏名有没有定义,来判断代码是否编译

④编译的时候,gcc可以添加-D参数,定义一个宏标识符

1
gcc ifdef和ifndef.c -o d.i -E -DA

二、Typedef的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 基本类型别名定义
typedef char CHAR;
typedef short SHORT;
typedef int INT;
typedef float FLOAT;
typedef double DOUBLE;// 指针类型别名定义
typedef char * CHARP;
typedef short * SHORTP;
typedef int * INTP;
typedef int (*INTARRAY5P)[5];
typedef int (*FUNCP)(int);// 数组类型别名定义
typedef int INTARRAY5[5];
typedef float FLOATARRAY5[3];// 函数类型的别名
typedef int FUNC(int);// 结构体类型别名
typedef struct Node
{
int a;
char b;
}NODE_t, *NODEP_t;