目录
1.预定义符号
c语言设置了一些预定义符号,可以直接使用,预定义符号就是在预处理期间处理的:
1.__FILE__ 进行编译的原文件
2.__LINE__ 这个符号所在的行号
3.__DATE__ 文件被编译的日期
4.__TIME__ 文件被编译的时间
5.__STDC__ 如果编译器遵顼ANSIC,其值为1,否则未定义(visual studio的编译器并没有__STDC__)
2.#define定义常量
语法形式:#define name stuff
预处理阶段会将#define的name全部完全的替换成stff,然后将#define删除。
注意:在#duffine定义的时候不要在后面加分号,因为替换的时候会将分号也替换进去。
3.#define定义宏
#define机制包括一个规定:允许把参数替换到文本中,这种实现就是宏。
宏的申明方式:#define name(parament-list) stuff 注:parament-list是一个由逗号隔开的符号表,他们可能出现在stuff中。
注意:参数列表的左括号必须跟name紧邻,否则将理解为:参数列表也是后面内容的一一部分。
当我们使用这个宏的时候,会将数值(假如说是x)传给n,然后替换为((x)*(x))。
没错这确实很像c++中的内联函数,感兴趣可以去看一下这个c++入门 (蒟蒻版)-CSDN博客
这里读者可能会注意到我的宏写了好多括号,这是很有必要的,因为宏的机制是完全的替换,可能会因为参数中的操作符或者邻近的操作符之间的优先级问题,造成非预期的结果。
4.带有副作用的宏参数
当宏的参数在宏定义中出现不止一次,如果参数带有副作用,那么可能会出现不可预测的后果。如x+1就没有副作用,x++就有副作用。 看下面代码:
解释:从左到右依次计算,后置++是先使用后++,所以是8>1,然后执行++后a为9,b为2。再执行后面a++(b++不会执行)和赋值给z的操作,因为后置++,所以先赋值给z再++。所以最后z=9,a=10,b=2。
5.宏的替换规则
1.在调用宏的时候,首先对参数进行检查,如果包含被#define定义的符号(#define定义常量),那么他们先被替换。
2.替换文本随后被插入到原来开的位置。对于宏。参数名被他们的值所代替。
3.最后再次对结果进行扫描,看是否存在#define定义的符号,若有重上述步骤。
注意:宏参数和#define定义中可以出现其他的#define定义的符号。但是不能出现递归。
当预处理器搜索#define定义的符号时,字符串常量当然是不会被搜索的
6.宏与函数的对比
宏就像杀鸡刀:迅速但只能杀杀鸡
函数像杀牛刀:相对慢但能杀牛
宏的优势:
对于简单的运算可以考虑使用宏,为什么不用函数。有句话叫杀鸡焉用宰牛刀,函数的执行效率比宏要慢规模更大,宏是直接的替换,而函数还要建立函数栈帧,再执行里面的操作,再返回值。
并且函数的参数必须要声明类型,而宏不需要,所以宏的范围更广。
宏的劣势:
每次使用宏,都要替换,如果宏比较长,会大幅的增加程序长度。
宏无法被调试。
宏没有类型,也就不够严谨。
宏可能带来优先级的问题,容易出错。
但是如果你的参数是类型名的话,函数是无法做到的,但是宏可以。比如:
7.#和##
7.1 #运算符
#运算符将宏的一个参数转换为字符串字面量。它仅允许出现在带有参数的宏的替换列表中。
#运算符所执行的操作可以理解为字符串化。
(为什么要有这个操作符,因为我们在使用宏的时候不是都想替换成值,而是替换之后的字符串)例如:
7.2 ##运算符
##可以把位于它两边的符号合成一个符号,它允许宏定义从分离的文本片段创建标识符。##被称为记号粘合,这样的链接必须产生一个合法的标识符,否则其结果就是未定义的。例如:
这种代码认识就好了,一般没人这么写
8.命名约定
习惯是:把宏名全部大写,函数名不要全部大写。
9.#undef
这条指令用来移除一个宏定义。
10.条件编译
满足条件参与编译,不满足条件不参与编译。(注意这里都是在预处理的时候处理的,创建的变量是还没有出现的)
#if 常量表达式
#elif 常量表达式
#elif......
#else 常量表达式
#endif (判断到此结束)
#ifdef ()等价于#if defined () 意思就是判断()中的符号是否被定义过了。
#ifndef()等价于#if !defined()判断()中的符号是否没有定义过。
注意:这里的if elif else 跟if else if else用法完全类似,可以嵌套使用。
11.头文件的包含
11.1本地文件的包含
#include " "
查找策略:现在源文件所在目录下查找,如果没有找到,就像查找库函数头文件一样在标准位置查找头文件。再找不到就编译报错。
11.2标准库中文件的包含
#include < >
注意包含可能会嵌套。
到这就结束了.......