美文网首页
C++ #define宏定义和特殊操作符

C++ #define宏定义和特殊操作符

作者: 啊呀哟嘿 | 来源:发表于2020-03-03 14:50 被阅读0次

    主要例子来源于:https://docs.microsoft.com/en-us/cpp/preprocessor/,另外菜鸟教程上也有相关的介绍。感觉有些网络文档对于操作符的说明不是很清晰,所以援引了一些自己觉得比较好的例子。

    #define是一个与处理命令,会在编译的预处理阶段进行处理。我们可以用该命令来定义宏并替换掉源码中的特定部分。

    无参数宏

    #define macro-name replacement-text 
    

    有参数宏

    #define ADD(x,y) (x+y)
    

    要注意边际效应,尽量添加括号。

    特殊操作符

    • #
      # 运算符将参数作为字符串处理,会把 replacement-text 令牌转换为用引号引起来的字符串。具体的例子,可以参考如下代码:
    // stringizer.cpp
    #include <stdio.h>
    #define stringer( x ) printf_s( #x "\n" )
    int main() {
       stringer( In quotes in the printf function call );
       stringer( "In quotes when printed to the screen" );
       stringer( "This: \"  prints an escaped double quote" );
    }
    

    这段代码在预处理过后会变成

    int main() {
       printf_s( "In quotes in the printf function call" "\n" );
       printf_s( "\"In quotes when printed to the screen\"" "\n" );
       printf_s( "\"This: \\\" prints an escaped double quote\"" "\n" );
    }
    
    • ##
      符号拼接。
      直接上例子:
    #define paster( n ) printf_s( "token" #n " = %d", token##n )
    int token9 = 9;
    paster( 9 );
    

    预处理过后变成:

    int token9 = 9;
    printf_s( "token" "9" " = %d", token9 );
    

    也就是:

    int token9 = 9;
    printf_s( "token9 = %d", token9 );
    

    有些同学可能有疑惑:本身宏就可以进行文本替换,那不使用##应该也能实现上面的功能,得到一个部分自定义的变量。其实如果要让预处理器进行替换,需要在前面有个空格。另外##也不能作为替换序列的开头,否则会报错(error: '##' cannot appear at start of macro expansion)。

    #define test1(x,y) xy
    #define test2(x,y) x ## y
    #define test3(x) x
    //#define test4(x) ##x // '##' cannot appear at start of macro expansion`
    
    using namespace std;
    void main(){
        int i_1=0;
        test1(i_,1);
        test2(i_,1);
        i_test3(1);
        i_ test3(1);
        //i_test4(1);
    }
    

    在使用预处理命令处理后,会得到:

    using namespace std;
    void main(){
        int i_1=0;
        xy;
        i_1;
        i_test3(1);
        i_ 1;
    
    }
    

    (回顾:预处理命令为g++ -E main.cpp -o main.i

    • 可变参数宏(Variadic macros)
      使用...与VA_ARGS可以处理不定数量(至少一个)的参数。
    // variadic_macros.cpp
    #include <stdio.h>
    #define EMPTY
    
    #define CHECK1(x, ...) if (!(x)) { printf(__VA_ARGS__); }
    #define CHECK2(x, ...) if ((x)) { printf(__VA_ARGS__); }
    #define CHECK3(...) { printf(__VA_ARGS__); }
    #define MACRO(s, ...) printf(s, __VA_ARGS__)
    
    int main() {
        CHECK1(0, "here %s %s %s", "are", "some", "varargs1(1)\n");
        CHECK1(1, "here %s %s %s", "are", "some", "varargs1(2)\n");   // won't print
    
        CHECK2(0, "here %s %s %s", "are", "some", "varargs2(3)\n");   // won't print
        CHECK2(1, "here %s %s %s", "are", "some", "varargs2(4)\n");
    
        // always invokes printf in the macro
        CHECK3("here %s %s %s", "are", "some", "varargs3(5)\n");
    
        MACRO("hello, world\n");
    
        MACRO("error\n", EMPTY); // would cause error C2059, except VC++
                                 // suppresses the trailing comma
    }
    

    相关文章

      网友评论

          本文标题:C++ #define宏定义和特殊操作符

          本文链接:https://www.haomeiwen.com/subject/rxgflhtx.html