#define # ##使用

一:可变参数使用:

printf(fmt, ...)

#define DPRINTF(fmt, args...) printf(fmt, ##args)
args...表示fmt之后的参数可以是零个或者多个。

二:#和##只能在宏定义中使用
       #是把宏参数变为一个字符串,##是把两个宏参数连接在一起
1. 
 

#include <stdio.h>
#define f(a,b) a##b
#define g(a)  #a
#define h(a) g(a)
int main()
{
  printf("%s\n",h(f(1,2)));  // 输出:12
  printf("%s\n",g(f(1,2)));  // 输出:f(1,2)
  printf("%s\n",g(1));       // 输出:1
  printf("%d\n", f(1,2));    // 输出:12(数值)
  return 0;
}

分析:
第 9行:#1 将1转换为字符串输出
第10行:1##2 将1和2连接结果为12,12是数字,故输出时用%d。注意并没有将12转换为字符串,如果需要将12作为字符串输出,需要再次使用h(a)这个宏,即第7行。
第 7行:因为h(a)是普通的宏(即没有#和##的宏),所以h(f(1,2))即是h(12),然后调用g(12),结果是字符串12
第 8行:因为g(a)是直接将a转换为字符串,所以将f(1,2)转换为字符串

2.

#include <stdio.h>

#define f(a,b) a##b

#define h(a,b) f(a,b)

int main()
{
  printf("%s\n", h("hello", "world"));
  
  return 0;
}  

编译时错误信息:
error: pasting ""hello"" and ""world"" does not give a valid preprocessing token
   printf("%s\n", f("hello", "world"));

原因分析:
根据C标准,用##操作后的结果必须是一个已经预定义过的符号,否则就是未定义的。
预定义的符号:头文件名, 等式, 预处理数字, 字符常数, 字符串值, 标点符号, 单个非空字符
具体参考:https://www.cnblogs.com/wb-DarkHorse/p/3588787.html


3. 上面出错的场景是自己想象当参数是字符串时,宏函数调用结果是什么样,以下是可能的一种使用场景。

参考:http://gcc.gnu.org/onlinedocs/gcc-4.3.3/cpp/Concatenation.html#Concatenation

#include <stdio.h>

#define COMMAND(name) {#name, name##_command}

void quit_command(void) {
   return; 
}  

void help_command(void) {
    return;
}   
struct command
{
    char *name;
    void (*function) (void);
};  

int main()
{
    struct command commands[] = {
           COMMAND (quit),
           COMMAND (help),
           };
    return 0;
} 

程序正常运行。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值