C语言中的宏定义主要用于替换代码中的特定内容,以简化代码和提高可读性。以下是C语言中宏定义的一些常见用法:
1.定义常量:
可以使用宏定义来定义常量,例如:
#define PI 3.14159
在后续的代码中,可以使用PI来代替3.14159。
2. 定义函数形式的宏:
可以使用宏定义来定义一段代码片段,例如:
#define SQUARE(x) ((x) * (x))
在后续的代码中,可以使用SQUARE(x)来代替(x) * (x),其中x是一个参数。
3. 条件编译:
可以使用#if、#ifdef、#ifndef、#else 和 #elif 等指令,根据宏是否被定义来选择性地编译某些代码。
#if 整型常量表达式
程序段
#endif
如果“整型常量表达式”的值为真(非0),则编译“程序段”。
#if 整型常量表达式1
程序段1
#elif 整型常量表达式2
程序段2
#elif 整型常量表达式3
程序段3
#else
程序段4
#endif
如果“整型常量表达式1”的值为真,则编译“程序段1”,否则继续判断“整型常量表达式2”,依此类推。如果没有任何表达式为真,则编译“程序段4”。
在这种情况下,0和1可以当作普通表达式来看待。0表示假,1表示真。有时候可以使用#if 0来作为注释,例如:
#include <stdio.h>
int main() {
// #if 0
// 这部分代码被注释掉了,不会编译
int x = 5;
printf("%d\n", x);
// #endif
return 0;
}
如果你想让被注释掉的代码生效,只需把#if 0改成#if 1。
可以与宏定义结合使用,例如:
#define MAX 100
#if MAX > 50
printf("MAX is greater than 50\n");
#else
printf("MAX is less than or equal to 50\n");
#endif
在这个例子中,如果宏MAX被定义为大于50的数,则会输出“MAX is greater than 50”,否则输出“MAX is less than or equal to 50”。
4. 命令行参数:
通过 -D 选项,可以在编译时定义宏。例如:
gcc -DDEBUG myfile.c -o myprogram
这将在编译时定义DEBUG宏。
5. 取消宏定义:使用 #undef 指令可以取消先前定义的宏。例如:
#undef DEBUG
这将取消DEBUG宏的定义。注意,这不会影响使用 #ifdef 或 #ifndef 等指令进行的条件编译。只有当这些指令在取消宏定义之后被评估时,它们才会看到宏未被定义的状态。
我们在做项目时会经历版本更新,通常我们也是通过在KEILDefine中定义宏来确定当前代码的版本。
6.字符串#
#define STR(x) #x
int main() {
printf(STR(hello)); // 输出 "hello"
return 0;
}
在这个例子中,STR(hello)会被替换成"hello",因此printf(STR(hello));等价于printf(“hello”);。
#的另一个作用是连接符号,用于将两个参数连接起来。例如:
#define CONCAT(a, b) a ## b
int main() {
int CONCAT(var, 1) = 5; // 定义了一个名为var1的变量,值为5
return 0;
}
在这个例子中,CONCAT(var, 1)会被替换成var1,因此int CONCAT(var, 1) = 5;等价于int var1 = 5;。
7.可变宏:… 和 VA_ARGS
#define pr(...) printf(__VA_ARGS__)
pr("1");
output : 1
需要注意的是,由于宏只是简单的文本替换,不进行语法检查,因此在使用带参数的宏时需要特别小心,以避免出现替换错误或逻辑错误。另外,嵌套定义的宏过多可能会影响程序的可读性和调试性,应尽量避免。
如:
#define MAX(a,b) a*b
printf("%d\r\n",MAX(2,3-1));
target : 4
output : 5
可以看到实际输出与目标有区别,这是因为我们将其带入宏中展开是2*3-1,根据运算优先级就为5了,为了解决这个问题只需要将宏定义写成以下格式即可。
#define MAX(a,b) ((a)*(b))
printf("%d\r\n",MAX(2,3-1));
target : 4
output : 4
有补充的可以发到评论区,我会加上的👍。