预处理器
预定义符号
由预处理器定义的符号
// 进行编译的源文件名称 __FILE__ // 文件当前行号 __LINE__ // 文件被编译的日期 __DATE__ // 文件被编译的时间 __TIME__ // 如果编译器遵循ANSI C,值为1,否则未定义 __STDC__
#define
#define reg register//将reg定义为register修饰符,为register修饰符创建了一个别名 #define do_forever for( ; ; )//用do_forever代表无限循环 #define CASE break;case//用来方便记忆
#define peintf \ for(int i=0;i<5;i++)\ printf("*"); #include<stdio.h> #include<stdlib.h> #include<string.h> int main() { peintf return 0; }
宏
#define机制包含一个设定,允许将参数替换到文本中,这种实现方式叫做宏或者定义宏
#define name(parameter-list) stuff//宏的声明方式
举一个例子
#define square(x) x*x//将参数x替换为x*x //但是这个写法是有问题的,如果有表达式square(a+1) //那么表达式就会变为a+1*a+1,就会发生错误 //因此,可以改为(x)*(x),但是还是有问题 //如果有表达式10*add(a+1) //表达式就变为10*(a+1)+(a+1),结果依然不对 //最终答案是((x)*(x))
来看宏的应用
#define a do #define b(x) while((x)) #include<stdio.h> #include<stdlib.h> #include<string.h> //这样a和b就构成了新的语句 int main() { int i = 0; a{ printf("*\n"); i++; }b(i<5); return 0; }
#define的替换
在调用宏的时候,会先检查参数,观察是否有#define定义的符号,如果有他们将首先被替换
替换文本被放到原先文本的地方,对于宏,参数名被他们的值所代替
最后,再次对结果文本进行扫描,检查是否还有#define定义的符号,如果有就重复上述流程
宏与函数
相对于宏来说,函数有两点不足:一是函数的调用和返回需要的代码量较大,在简单的小型计算方面,宏相对更加具有优势,
二是函数对参数有类型要求,有着应用局限性,而宏与类型无关
但是宏的缺点是每次使用宏时都会将宏的副本复制一遍,加大代码量
下面展示一个宏比函数更有优势的例子:
#define MALLOC(type,n) (type,n)\ (type*)malloc(n*sizeof(type))
宏的副作用
参数求值方面,参数每次用于宏定义时,他们都会重新求值,由于多次求值,具有副作用的参数可能产生永久性影响
#undef
解除指定的宏定义,当想重新定义一个已有宏时,需要先解除原先的宏
更多关于宏
C语言宏的定义和宏的使用方法(#define) (biancheng.net)
条件编译
条件编译的基本结构为#if指令和与其匹配的 #endif指令,如果多条件还可以增加#elif和 #else指令,#elif没有数量限制,#else只有在前面语句全部为假时才能生效
#if constant-expression statements; #elif constant-expression other statements; #else constant-expression #endif
文件包含
#include指令使得另一个文件的内容被编译,其执行过程相对简单,预处理器将该指令删除,并用包含文件的内容代替,如果一个头文件被包含到10个源文件,那么它将被编译10次,但是这所引起的开销是不必担心的,因为这种开销非常小,且发生在编译时期,对运行效率影响不大
标签:__,定义,编译,参数,处理器,include,define From: https://www.cnblogs.com/alexlance/p/17437921.html