C语言中宏定义(看一下是你了解的宏吗?)

一、宏定义

1.格式为 #define  宏名  常量,通常情况下宏名为大写。

使用宏定义,我们需要知道它是一个原样替换,下面这个示例会帮你明白宏定义的使用规则:

#include <stdio.h>
#define NUM 3+3
int main()
{
        printf("%d\n",NUM*NUM);
        return 0;
}

是你心中的那个答案吗?

在linux操作系统下,可以使用gcc -E 文件名.c -o 文件名.i 来生成预编译结果,vim 文件名.i  可以进入查看,翻到最下面,我们来看一下它预编译后的结果:

 可以看到,宏定义只是将原有的常量替换宏名,并没有做任何的计算,6*6=36的结果是不存在的! 

二、宏函数

1.顾名思义,就是在宏定义中实现了一个函数的功能,来看下面这个宏函数,实现的是一个相加的功能,将ADD后的参数,赋给了后面这个表达式,在这段代码中x =  5*5,然后将5*5传递给了后面的表达式,结果为5*5+5*5  = 50。注意前面是x,后面参数也需要一致,不然会报错。

#include <stdio.h>
#define ADD(x) (x+x)
int main()
{
        printf("%d\n",ADD(5*5));
        return 0;
}

 

再来看一下预编译后的结果:

没有问题。 

三、字符串转化运算符#

在编写宏函数的时候,我们可能需要将宏定义的参数转化为字符串,这时候就要用到转化运算符'#',来看示例:

#include <stdio.h>

#define ADD(x) printf("得到的运算式为"#x"=%d\n",x); 
int main()
{
        ADD(5+5);
        return 0;
}

注意,#x是在" "的外面,而不是两个'' "的中间。

四,不定参数宏

C99标准中规定,允许用户定义有省略号的宏。__VA_ARGS__,它表示可变参数列表。

#include <stdio.h>
#define dis(...) printf(__VA_ARGS__) 
//#define dis(format,...) printf(format,__VA_ARGS__)
//#define dis(format,...) printf(format,##__VA_ARGS__)
int main()
{
    dis("Hello world\n");
    return 0;                                                                                      
}

上面的我一共写了三种宏定义,第一种的话没什么可说的;第二种的很明显可变参数在逗号的后面,所以我们需要有格式的固定,使用dis宏定义的时候里面也应该有逗号,不然就会报错。第三种的话则可以避免第二种的问题,如果定义的宏有格式,但是没有去按照要求去写,依旧可以正常运行,避免了语法错误。 

总结:初学者的话上面的宏前两种是需要知道的,后面两种看的话了解一下即可。

### C语言宏定义重名的行为规则 在C语言中,宏定义是一种预处理指令,在源代码被实际编译之前由预处理器执行。当两个或多个宏定义具有相同的名字时,它们之间的行为遵循一定的规则。 #### 1. 后续定义覆盖先前定义 如果在同一作用域内多次定义相同的名称,则后续的定义会覆盖之前的定义[^1]。这意味着最后生效的是最后一次定义的内容。例如: ```c #define VALUE 10 #define VALUE 20 ``` 在这种情况下,`VALUE` 的最终值为 `20`,因为在第二次定义时,第一次定义已经被覆盖[^1]。 #### 2. 使用 `#undef` 删除宏定义 可以通过 `#undef` 预处理指令删除已存在的宏定义。一旦某个被取消定义,即使之后重新定义该,也不会保留旧的定义内容。例如: ```c #define VALUE 10 #undef VALUE #define VALUE 20 ``` 在此例子中,尽管最初定义了 `VALUE` 为 `10`,但在使用 `#undef` 取消定义后,再次定义时 `VALUE` 被设置为 `20`。 #### 3. 宏定义与函数同名的情况 虽然理论上允许宏定义与函数同名,但这可能导致混淆和潜在错误。如果没有正确实现对应的功能(如未定义相应的函数),而仅存在同名的宏定义,可能会引发编译错误,因为调用者期望找到一个真正的函数而非仅仅是替代[^2]。 #### 4. 不建议的做法 出于代码清晰性和维护性的考虑,应避免让名称与其他实体(如变量、类型或函数)冲突。这样做不仅降低了代码的可读性,还容易引起难以追踪的问题。因此,即便从技术角度讲这是可行的,但从实践角度看并不推荐这种做法[^2]。 #### 5. 特殊情况下的多重定义 对于某些特殊场景下使用的(比如条件编译中的保护机制),可能存在故意设计的重复定义情形。然而这些通常是经过深思熟虑并严格控制范围内的应用,并非随意为之[^3]。 综上所述,C语言允许多次定义同一个名,但每次新定义都会取代前一次的老版本;同时需要注意避免不必要的命名冲突以免影响程序质量及稳定性。 ```c // 示例代码展示如何处理重定义 #include <stdio.h> #define TEST_VALUE 100 #undef TEST_VALUE #define TEST_VALUE 200 int main() { printf("Final value of TEST_VALUE is %d\n", TEST_VALUE); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值