C语言提供的预处理指令主要有:宏定义、文件包含、条件编译
1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生 一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译
2.为了区分预处理指令和一般的C语句,所有预处理指令都以符号"#"开头,并且结尾不用分号预处理指令在代码翻译成0和1之前执行。
3.预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾。习惯上我们尽可能将预处理指令写在 源程序开头,这种情况下,它的作用范围就是整个源程序文件
宏定义可以分为2种:不带参数的宏定义 和 带参数的宏定义。
1:不带参数的宏:宏名一般用大写或者用K开头,变量名一般用小写。#define 宏名 字符串比如#define ABC 10右边的字符串也可以省略,比如#define ABC它的作用是在编译预处理时,将源程序中所有"宏名"替换成右边的"字符串",常用来定义常量。
1> 宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误
2> 对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作。
3> 在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查
4> 宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用#undef命令,使宏失效。
5> 定义一个宏时可以引用已经定义的宏名
2:带参数的宏例如: #define sum(n1,n2) n1+n2
可以实现函数的作用 :int sum (inta,int b)
{return a+b;}
int main ()
{int c=sum(10,11);
return0;}
宏定义可以返回两个值的和。
但是:int c= sum (9,8)*(4,3);这个不能用宏替换,因为用宏的话会变成:int c= 9+8*4+3;
这是因为带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。运算时在运行过程中进行的,而宏定义是在代码编译成0和1之前替换文本。所以在定义宏时,一般用一个小括号括住字符串的参数。
注意:#define pingfang (a) (a*a)
#define pingfang (a) a*a
#define pingfang (a) ((a)*(a) )
作用是不一样的。从整个使用过程可以发现,带参数的宏定义,在源程序中出现的形式与函数很像。但是两者是有本质区别的:宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行。带参数的宏效率比函数高,因为函数调用时占用程序运行时间,在程序运行时才调用函数,要根据函数名找到相应的函数定义,而宏定义在程序编译之前就把代码换成相应的文本了。
所以应该改成: # define sum(n1,n2) ((n1)+(n2))
条件编译:在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编译(只有参与编译的代码最终才能被执行),这就是条件编译。
格式: # if (条件1)code1
#elif (条件2)code2
#elif (条件3 )code3...
#endif
1> 如果条件1成立,那么编译器就会把#if 与 #elif之间的code1代码编译进去(注意:是编译进去,不是执行,很平时用的if-else是不一样的)
2> 如果条件1不成立、条件2成立,那么编译器就会把#elif 与 #else之间的code2代码编译进去
3> 如果条件1、2都不成立,那么编译器就会把#else 与 #endif之间的code3编译进去4> 注意,条件编译结束后,要在最后面加一个#endif,不然当某个条件成立时,相应的code 会被编译,之后的多有语句不再有效,return 0 也不再有效。
5> #if 和 #elif后面的条件一般是判断宏定义而不是判断变量,因为条件编译是在编译之前做的判断,宏定义也是编译之前定义的,而变量是在运行时才产生的、才有使用的意义条件编译与 if else 很相像,但是两者也是有区别的:
1:if ...else 是在程序运行过程中执行的,而 # if ...#endif 是在编译之前做的。
2:# if ...#endif 不想执行的代码可以直接不参与编译,而if ...else中不管哪个条件成立,都会全部编译占据目标文件的空间。
3:相比较下# if ...#endif 效率更高。
例如:#define Max 10int main (){
#if (Max==5)
priintf("Max=%d\n",Max);
#elif (Max==10)
priintf("Max=%d\n",Max)
;#endifreturn 0;
}
系统编译后程序相当于:
#define Max 10int main (){
priintf("Max=%d\n",Max);
return 0;}
#if 和 #elif后面的条件不仅仅可以用来判断宏的值,还可以判断是否定义过某个宏。
#if defined(MAX)...code...#endif
2: #ifdef的使用和#if defined()的用法基本一致#ifndef MAX...code...#endif
如果前面没有定义过MAX这个宏,就将code编译进去
网友评论