宏定义和宏函数

宏定义

1
#define N 5

切记,宏定义的后面没有;

实际上任何以 # 开头的预定义后面都不能有分号,毕竟文本替换会把这个分号一并带过去,那么必然照成错误。

1
2
3
4
5
6
7
8
9
10
11
12
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#define N 5; // 测试如果添加 分号 会造成什么错误

int main(void) {

int num = N * N;

return 0;
}

测试结果:

宏定义.png

宏函数

宏函数要注意的地方就是,一定要学会添加括号()

  1. 参数要加括号
  2. 整个表达式要加括号
  3. 左括号要紧靠宏函数名称
1
2
3
4
5
6
7
8
9
10
11
12
13
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#define FUN(x) x * x

int main(void) {
int x = 10;
int y = 20;
printf("x * x = %d", FUN(x + y));

return 0;
}

查看预编译情况:

宏函数1.png

预处理语句就是单纯的文本替换,所有对于宏函数务必严格添加合适的括号来保证语句逻辑的合理性。

1
#define FUN(x) ((x) * (x))

再次查看预编译情况:

宏函数2.png

如果左括号没有紧靠宏函数,会如何?这其实很容易被人忽视,还是先看看现象:

宏函数3.png

没错,如果你左括号没有紧靠宏函数,那么这将是宏定义,而非一个宏函数了。

当然,前面写的宏函数都是一行代码,如果是多行的那种代码,注意分行。

1
2
3
4
5
6
#define MAX(a, b) \
({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a > _b ? _a : _b; \
})

除了最后一行不用添加 \,其余行都要添加。宏的每一行都以反斜杠(\)结尾,以指示宏定义的行继续到下一行。在宏定义的最后一行,反斜杠并不需要,因为没有更多的行继续定义宏。如果在最后一行添加反斜杠,它实际上是多余的,因为宏定义已经结束。