C语言------预处理
1. 宏定义指令#define用来定义一个标识符和一个字符串,以这个标识符来代表这个字符串,在程序中每次遇到该标识符时就用所定义的字符串替换它。
#define 宏名 字符串
几点说明:1.#表示这是一条预处理命令;2. 宏名是一个标识符,必须符合C语言标识符的规定;3. 字符串这里可以是常数、表达式、格式字符串等。
2. 宏名要简单且明确,一般习惯用大写字母表示,以便与变量名相区别。
3. 宏定义不是C语句,因此不需要在行末加分号。
4. 不带参数的宏定义有几点需要注意:
1. 如果在串中含有宏名,则不进行替换;例如:#define TEST "this is an example" char exp[30] = "this TEST is not that TEST"; 输出时TEST不会替换成原来的字符串。
2. 如果串长度长于一行,可以在该行末尾用一反斜杠“\”续行;
3. #define命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到此源文件结束。
4. 可以用#undef命令终止宏定义的作用域;
5. 宏定义用于预处理命令,它不同于定义的变量,只作字符替换,不分配内存空间。
5. 带参数的宏定义:
#define 宏名(参数表) 字符串
举个例子:
#include<stdio.h>
#define MIX(a,b) ((a)*(b)+(b))
main()
{
int x = 5, y = 9;
printf("x, y:\n");
printf("%d, %d\n", x, y);
printf("the min number is: %d\n", MIX(x, y));
}
6. 用宏替换代替实在的函数的一个好处是宏替换增加了代码的速度,因为不存在函数调用。但是不好的地方是增加了代码的长度,因为仅是代码替换,因此增加了代码的长度。
7. 关于带参数的宏有几点需要注意,结合上面的这个例子仔细看:
1. 宏定义时,参数要加括号,如不加括号,则有时结果会不正确。
2. 宏扩展必须使用括号来保护表达式中低优先级的操作符,以确保调用时达到想要的效果。
3. 对带参数的宏的展开,只是将语句中的宏后面括号内的实参字符串代替#define命令行中的形参。
4. 在宏定义时,宏名与带参数的括号之间不可以加空格,否则会将空格以后的字符都作为替代字符串的一部分。
5. 在带参宏定义中,形式参数不分配内存单元,因此不必做类型定义。
8. #include "stdio.h"和#include <stdio.h>的区别:
用尖括号时,系统到存放C库函数头文件所在的目录中寻找要包含的文件,这是标准方式;
用双引号时,系统先在用户当前目录中寻找要包含的文件,若找不到,则再去存放C库函数头文件所在的目录中寻找。
9. 一般情况下将如下内容放到.h文件中:
1. 宏定义
2. 结构、联合和枚举声明
3. typedef声明
4. 外部函数声明
5. 全局变量声明
10. 条件编译:
#if
#else
#endif
----------------------
变异有两种:
#if
#else
#if
#else
#endif
#endif
---------------------------
#if
#elif
#elif
#else
#endif
11. #ifdef和#ifndef宏
#ifdef
#else
#endif
-----------------------------
#ifndef
#else
#endif
12. #undef的目的是将宏定义名局限在仅需要他们的代码段中。
13. #pragma命令和#line命令都只了解一下即可
14. ANSI标准说明了以下5个预定义宏替换名
_LINE_ :其含义是当前被编译代码的行号;
_FILE_ : 其含义是当前源程序的文件名称;
_DATE_ :其含义是当前源程序的创建日期;
_TIME_ : 其含义是当前源程序的创建时间;
_STDC_ : 其含义是用来判断当前编译器是否为标准C,若其值为1,则表示符合标准C,否则不是标准C。