编译链接的过程:预处理——编译——汇编——链接
大家好,今天我来通过一篇博客带领大家深入探讨一下C语言当中的预处理。(预处理阶段完成)
一:预定义符号
C语言中设置了一些预定义符号,可以直接使用(C语言内部已经定义好了),预定义符号也是在预处理期间处理的。
使用举例:
需要注意的是
1.预处理符号在编译之前就会被替换,因此打印时间是打印的是文件被编译的时间,而不是程序运行的时间。
2.VS上的编译器实际上是不遵循ANST C的,编译时会报错。(gcc vscode支持,很多软件都集成了gcc)。
二:#define定义常量
基本语法:(核心:替换)
在预处理阶段,第14行的内容会消失并且把14行以下程序中所有的M全部替换成100(这个过程会在我的下一篇博客“C语言中的编译与链接”中详细讲解)
其实#define定义常量并不仅仅局限于字面常量
以下介绍几种你可能从来没有见过的#define使用方法:
再举一个实际生活上的例子:
某程序员在写程序的过程中经常在写switch case语句是忘记加上break,他想到了这样一个解决办法:
虽然提到了上述写法,但并不是指上述写法好,只是你要知道#define的用法多样
思考:#define定义标识符的时候,能不能在后面加上;?
其实如果应用得当也是可以的,但不推荐使用应为容易出错。(容易出现问题)
请看下面程序
如果不写{}的话,if后面只能跟一条语句,这样就没有与else匹配的if了。
三:#define定义宏
#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏
下面是宏的声名方式:
其中parament——list 是参数列表
注意:
参数列表的左括号必须与name紧邻,如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分
举例:
这个宏接收一个参数X,如果在上述声名后,你把SQUART(5);置于程序中,预处理器就会用5*5替换上面的表达式
警告:
这个宏在使用的过程中非常容易出现问题
请观察下面程序:
这里的a+1不会提前算出来等于6再把6往上面带入,因为对于宏定义的处理是在编译过程中的预处理阶段完成的,预处理阶段还没有a了,绝对不是先算出来。
宏书写技巧:多加小括号————!!!!一定要注意小括号!!!!
提示:所有用于对数值表达式进行求值的宏定义都应该用下面这种方式加上括号,避免在使用宏时由于参数中的操作符或临近操作符之间不可预料的相互作用。
#define DOUBLE(x) ((x)+(x))
宏的使用方式和函数有些类似,但也有不同点:
函数的参数有类型,宏的参数不关注类型(直接代入)。
函数有返回值,宏没有返回值。
未完待续I!