C语言的编译期行为(三) #的妙用

本文详细解读了C语言中预处理器指令的用法,包括#符号在宏定义内部的‘字符串化’操作,以及宏函数定义的特殊书写方式以确保作用域正确。通过实例演示了#符号在宏函数中的应用,以及其对参数的字符串化处理过程,最终展示了代码运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在C语言中,所有以#开头的行被认为是需要预处理器处理的“预处理器指令”。#include、#define等常见的用法不再赘诉,可以参考任何一本C语言的书籍。这里仍然讲一些需要注意的用法。下面的代码主要说明#出现在宏定义内部作为“字符串化”操作符的用法,另外附带介绍一些特别的习惯和用法。

#include <stdio.h>

# //此行只包含一个#,被当作空行处理

#define PRINT_ADD(a, b)                               \
    do                                                \
    {                                                 \
        char fmt[] = "%s + %s = %d\n";                \
        printf(fmt, #a, #b, ((a)+(b)));               \
    } while (0)                                       \

int main(int argc, char** argv)
{
    int var_a = 6;
    int var_b = 9;

    PRINT_ADD(3, 5);
    PRINT_ADD(var_a, var_b);
    PRINT_ADD(var_a * 2 , var_b);

    return 0;
}

只包含一个#的行会被如何处理?

第3行:只包含一个#的行被标准C语言认为是空行,#会被预处理器用空行替换掉。

宏函数定义为什么要使用do while循环的格式书写?

第5行到第10行定义了一个宏函数PRINT_ADD(a, b)。

1. 在宏函数中我们希望能够定义局部变量,但是C99以前的标准C语言要求所有变量必须一个作用域开始处定义。而宏展开后即变成了普通的代码行,并不能保证满足满足这一点的要求,所以宏函数需要采用大括号的形式。

2. 我们希望在程序中尽量像调用普通函数那样使用宏函数,即要求其后有一个分号作为结尾。使用这种形式有效地要求了用户必须使用分号。

3. 编译器随后的处理中,会有效地优化掉这种注定只执行一次的循环语句。所以一般来说不会影响性能。

第9行中#的作用是什么?

#出现在宏定义内部被认为是“字符串化”操作符。它的作用是将传入的参数整体宏替换为相对应的字符串。

例如:

第17行传入的3和5: #a被替换为"3",#b被替换为"5", a被替换为3, b被替换为5

第18行传入的var_a和var_b: #a被替换为"var_a",#b被替换为"var_a", a被替换为var_a, b被替换为var_b

第19行传入的var_a * 2和var_b: #a被替换为"var_a * 2",#b被替换为"var_a", a被替换为var_a * 2, b被替换为var_b

所以,程序运行的结果为:

3 + 5 = 8

var_a + var_b = 15

var_a * 2 + var_b = 21


P.S.:以下是VS2008预处理器处理后输出的代码:

int main(int argc, char** argv)
{
    int var_a = 6;
    int var_b = 9;

    do { char fmt[] = "%s + %s = %d\n"; printf(fmt, "3", "5", ((3)+(5))); } while (0);
    do { char fmt[] = "%s + %s = %d\n"; printf(fmt, "var_a", "var_b", ((var_a)+(var_b))); } while (0);
    do { char fmt[] = "%s + %s = %d\n"; printf(fmt, "var_a * 2", "var_b", ((var_a * 2)+(var_b))); } while (0);

    return 0;
}



(■版权声明: 原创内容,转载仅限非商业用途,并需注明出处: http://blog.youkuaiyun.com/LoveASPDotNet




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值