预定义符号:
__FILE__ // 进行编译的源文件;
__LINE__ // 文件当前的行号;
__DATE__ // 文件被编译的日期;
__TIME__ // 文件被编译的时间;
__STDC__ // 如果编译器遵循 ANSI C,其值为1 ,否则未定义 ;经测试VS编译器中这个是未定义的;
printf("file:%s line:%d\n",__FILE__,__LINE__);
# 开头的都叫做预处理指令,比如说 ->
1. #include
2. #define
3. #pragma
4. #if
5. #endif
6. ifdef
7. #line
8. .........
#define 定义标识符
语法:#define name stuff 【我们在定义#define标识符的时候用的都是大写,这是我们的约定】
实例代码:
#define MAX 100; #define STR "澜色海湾" extern int add(int x , int y); int main() { int max = MAX; char str[] = STR; printf("%d\n",max); printf("%s\n",str); return 0; }#define 后面可以是 标识符名 也可以是 一段代码,无论是什么,都会在预处理阶段将代码中的相应的 标识符 进行替换;
问题:在 #define后面需要加 分号;吗?
不需要,因为在#define 后面加上分号,当预处理去替换的时候会把 分号 一起替换过去,有可能会出现一些问题;
#define 定义宏
#define 机制包括一个规定,允许把参数替换到文本中,这种实现通常称为宏 ( macro ) 或定义宏 ( define macro );
下面是宏的声明方式:【定义宏的时候都是大写,这是我们的约定】
#define name ( parament - list ) stuff 其中的 parament - list 是一个由逗号隔开的符号表,他们可能出现在 stuff 中;
注意:参数列表的左括号必须与name紧邻;如果两者之间有任何空白、空格存在,参数列表就会被解释为 stuff 的一部分;
如:
#define SQUARE(x) x * x //这里指的是会将 SQUARE(x) 替换成 x 的平方
这个宏接收一个参数 x,如果在上述声明之后,你把
SQUARE ( 5 );
置于程序中,预处理器就会用下面这个表达式替换上面的表达式 ->
5 * 5
警告:这个宏存在一个问题 ,观察下面的代码段:
#define SQUARE(x) x*x int main() { int ret = SQUARE(5+1); printf("%d",ret); return 0; }咋一看,我们可能会认为会输出 36 ,因为 6 的平方等于 36;
但是实际上输出的是 11;为什么呢?
因为这里不是传参【 传参应该是 int x 而不是单单一个 x 】,而是替换,他会完完全全把 x 替换成 5+1,所以计算的是 5 + 1 * 5 + 1 根据计算优先级得出结果为 11;
#define的替换规则:
在程序中扩展 #define 定义符号和宏时,需要涉及几个步骤?
1. 在调用宏时,首先对参数进行检查,看看是否包含任何由 #define 定义的符号;如果是,他们首先被替换;【例如:DOUBLE(MAX+MAX),此时DOUBLE和MAX都是宏,那么由于MAX是DOUBLE的参数,所以先将MAX替换,再去替换DOUBLE】;
2. 替换文本随后被插入到程序中原来文本的位置;对于宏,参数名被他们的值替换;
3. 最后,再次对结果文件进行扫描,看看他是否包含任何由 #define 定义的符号;如果是,就重复上述处理过程;
注意:
1. 宏参数和#define定义中可以出现其他 #define 定义的变量;但是对于宏,不能出现递归;
2. 当预处理器搜索 #define 定义的符号的时候,字符串常量的内容并不被搜索【就是字符串常量不会被宏替换掉 】;例如->
#define MAX 100; int main() { printf("MAX = %d" , MAX); return 0; }printf() 中的第一个MAX不会被替换,第二个会被宏替换掉;
预处理操作符 # 和 ##
先来看看预处理操作符 #
如何把宏的参数插入到字符串中?
实例代码如下所示 ->
#define PRINT(x) printf("the value of "#x"is %d\n",x); int main() { int a = 10; int b = 20; PRINT(a); PRINT(b); return 0; }此时,PRINT(a); 会被替换成 printf ( " the value of " "a" " is %d\n " , a ); #x 并没有把 a 替换成 10,而是替换成了字符串 "a";
输出的结果就是 the value of a is 10
the value of b is 10
预处理操作符 ## 又是什么呢?
## 的作用 ->
## 可以把位于它两边的符号合成一个符号;他允许宏定义从分离的文本片段创建标识符;
举个例子 ->
#define CAT(X,Y) X##Y int main() { int lanSeHaiWan = 100; printf("%d\n",CAT(lanSe,HaiWan)); return 0; }执行代码后,这段代码中的:
printf("%d\n",CAT(lanSe,HaiWan));
会被替换成 ->
printf("%d\n",lanSe##HaiWan); //由于 ## 会把两端的符号合并成为一个,其实就相当于是 -> printf("%d\n",lanSeHaiWan);所以输出的结果依旧是 100
注:这样的连接必须产生一个合法的标识符;否则结果就是未定义的;