zoukankan      html  css  js  c++  java
  • 宏定义中的#和##

    参考:https://mazhuang.org/2014/05/10/numbersign/#标记连接操作-

    说明

    • C/C++ 中### 符号用于宏定义;
    • # 作用是将宏定义参数不经任何扩展地转换成字符串常量,所谓拓展包括:
      • 宏定义参数的两边的空格会被忽略;
      • 特殊字符会被加上转义字符;
    • ## 的作用是在宏定义中,将两个部分连接成一个部分,需要注意:
      • 用于连接,所以不能用在首尾;
      • 其前后的空格无意义;

    示例

    知识点准备:

    下面四组其实是等价的:

    char* p1 = "Hello," "World!";     // 一个空格
    char* p2 = "Hello,"    "World!";  // 多个空格
    char* p3 = "Hello,""World!";      // 没有空格
    char* p4 = "Hello,World!";        // 一个整串
    

    字符化操作(#)

    以MSDN上的例子说明:

    #define F abc
    #define B def
    #define FB(arg) #arg
    #define FB1(arg) FB(arg)
    
    qDebug()<<FB(F B);
    qDebug()<<FB1(F B);
    

    乍一看,两个输出应该是一样的,其实不然,这里的 # 操作符起作用的时间不一样,实际输出是:

    F B
    abc def
    

    宏定义在调用时就进行字符串的替换,这里的所谓的不经扩展 就是直接替换,所以,上例中的替换步骤是:

    FB(F B) => #F B => "F B"
    FB1(F B) => FB(abc def) => #abc def => "abc def"
    

    标记连接操作(##)

    以MSDN上的例子说明

    #define paster( n ) printf_s( "token" #n " = %d", token##n )
    int token9 = 8;//这里例子里是9,我为了区分,改成了8
    
    paster(9);
    

    最后的输出结果是:

    token9 = 8
    

    在编译的时候,宏定义替换字符串步骤如下:

    1. paster(9)
    2. printf_s( "token" #9 " = %d", token##9 )
    3. printf_s( "token" "9" " = %d", token9 )
    4. printf_s( "token9" " = %d", token9 )

    __VA_ARGS__

    __VA_ARGS__ 是一个可变参数宏,在宏中传递参数时,它可以表示传递的 ...,示例如下:

    #define test(...) qDebug(__VA_ARGS__)
    test(1, 2, 3)	//这里的参数至少有一个
    

    这里有个问题就是,可变参数至少有一个,因为当参数一个都没有时,有个 ,会导致编译错误

    ##__VA_ARGS__ 可以解决至少有一个参数的问题,其作用是,当参数数目为0时,去掉前面的逗号

    #define test(...) qDebug(##__VA_ARGS__)
    test()	//这里的不传参也可以
    
  • 相关阅读:
    小兔生仔和汽水换瓶的两个算法
    dpi 编程
    作者赠送的《我的第一本c++书》收到啦
    什么是程序员的优良品质
    如何把事情做对?
    学习应有的态度
    魔方数算法
    我的第二本c++教科书
    如何处理人际关系
    电动玩具的开发思路
  • 原文地址:https://www.cnblogs.com/sherlock-lin/p/11708151.html
Copyright © 2011-2022 走看看