文章目录
- 一、预定义符号
- 二、#define定义常量
- 三、#define定义宏
- 四、宏更函数的对比
- 五、#和##
- 1、#运算符
- 2、##运算符
一、预定义符号
C语言设置了一些预定义符号,可以直接使用,在预处理期间进行处理的。
__FILE__//进行编译的源文件
__LINE__//文件当前的行号
__DATE__//文件被编译的日期
__TIME__//文件被编译的时间
__STDC__//如果编译器遵循ANSI C,其值为1,否则未定义
测试结果:
二、#define定义常量
#define 用来定义常量时的定义的写法:
#define MAX 100
逻辑规则是帮后面代码中出现MAX直接替换成100,这个操作步骤是在预处理阶段完成的,一般在用#define定义常量时的名称用大写书写。
使用场景:
三、#define定义宏
#define用来定义宏时使用方法跟函数差不多,但逻辑是替换,在替换时要将变量都用括号括起来,以免发生操作符的优先级问题造成不是我们期望的结果。
使用方式:
#define MAX(x,y) ((x) > (y) ? (x) : (y))
这是写了一个完成判断两数直接较大值的宏,注意宏名称后面括号要紧贴宏。
使用用例:
通过上面两个案例可以发现宏在传参时没有限制类型,如果函数了话,函数的返回类型是固定的,宏的运行速度更快。
四、宏更函数的对比
宏的优势:
- 1.在完成代码量小的计算时,宏的工作时间要比函数小。
- 2.更重要的是函数的参数必须声明特定的类型。而宏可以适用于各种类型可以用>来比较的类型。宏的类型无关的。
宏的劣势:
- 每次使⽤宏的时候,⼀份宏定义的代码将插到程序中。除⾮宏⽐较短,否则可能⼤幅度增加程序的⻓度。
- 宏是没法调试的。
- 宏由于类型⽆关,也就不够严谨。
- 宏可能会带来运算符优先级的问题,导致程容易出现错。
宏和函数的对比表:
属性 | #define定义的宏 | 函数 |
---|---|---|
代码长度 | 每次使用时,宏都会被插入到程序中。除了非常小的宏之外,程序的长度会大幅度增长 | 函数代码只出现在一个地方;每次使用时,都调用那个地方的同一份代码 |
执行速度 | 更快 | 存在函数的调用和返回的额外开销,速度慢一些 |
操作符优先级 | 宏参数的求值是在所有周围表达式的上下文环境里,除非加上括号,否则邻近操作符的优先级可能会产生不可预料的后果,所以建议宏在书写的时候多些括号。 | 函数参数只在函数调用的时候求结果值传递给函数。表达式的求值可预测。 |
有副作用的参数 | 参数可能被替换到宏体中的多个位置,如果宏的参数被多次计算,带有副作用的参数求值可能会产生不可预料的结果。 | 函数参数只在传参的时候求值易控制。 |
参数类型 | 宏的参数与类型无关,只要对参数的操作是合法的,它就可以使用于任何参数类型。 | 函数的参数是与类型有关的,如不同,就需要不同的函数,任务是不同的。 |
调试 | 宏是不方便调试的 | 函数是可以逐语句调试的 |
递归 | 宏是不能递归的 | 宏是不能递归的 |
五、#和##
1、#运算符
#运算符将宏的⼀个参数转换为字符串字⾯量。它仅允许出现在带参数的宏的替换列表中。
#运算符所执⾏的操作可以理解为”字符串化“。
使用例子:
2、##运算符
##可以把位于它两边的符号合成⼀个符号,它允许宏定义从分离的⽂本⽚段创建标识符。为记号粘合
这样的连接必须产⽣⼀个合法的标识符。否则其结果就是未定义的。这⾥我们想想,写⼀个函数求2个数的较⼤值的时候,不同的数据类型就得写不同的函数。
使用例子: