代码之家  ›  专栏  ›  技术社区  ›  Sadique

如何使用宏连接两个或多个整数?

  •  2
  • Sadique  · 技术社区  · 14 年前

    如果a=1,b=2,c=3。。。我想写一个宏,像这样连接它们。 但是当我尝试这个的时候:

    #include<stdio.h>
    #define cat(a,b,c) a##b##c
    
    int main()
    {
    int a=1,b=2,c=3,d;
    d=cat(1,2,3); //Works
    d=cat(a,b,c); // Returns an error...How to make this work?
    return 0;
    }
    
    8 回复  |  直到 9 年前
        1
  •  10
  •   Jerry Coffin    14 年前

    你不能——预处理器不知道变量,也不知道在预处理器完成执行后,程序在任意时间运行时,你要给它们分配什么值。

        2
  •  3
  •   Aryabhatta Aryabhatta    14 年前

    hash define宏是预编译时的宏,在编译之前进行预处理。预处理器将无法访问变量值。 d=cat(a,b,c) 将转换为 d=abc

    你需要使用 itoa 或者类似的东西,并连接结果字符串,然后返回atoi。

    或者只是做一些算术来计算结果。

        3
  •  1
  •   Michael Mrozek    14 年前

    a , b ,和 c cat() 打电话。您需要编写一个宏,它实际上使用C++来进行组合。例如:

    #define cat(a, b, c, d) \
        do { \
            std::stringstream ss; \
            ss << a << b << c; \
            ss >> d; \
        } while(0)
    

    (the) do/while(0) cat 安全呼叫)

    您将无法使用此操作的“返回值”,但可以执行以下操作:

    int a = 1, b = 2, c = 3, d;
    cat(a, b, c, d);
    // d == 123 now
    
        4
  •  1
  •   pcent    14 年前

    #include <stdio.h>
    
    #define cat(x,a,b,c) snprintf(x, sizeof(x), "%d%d%d", a, b, c)
    
    main(int argc, char *argv[])
    {
        char s[20];
        cat(s, 4,5,6);
        printf("%s\n", s);
    }
    
        5
  •  1
  •   smerlin    14 年前

    如果在编译时执行此操作并不重要,可以使用以下方法:

    #include <math.h>
    unsigned intcat(unsigned a, unsigned b, unsigned c)
    {
        unsigned dlogc = 1 + (unsigned)(log(c)/log(10));
        unsigned dlogb = 1 + (unsigned)(log(b)/log(10));
        return (unsigned)(c + pow(10,dlogc) * b + pow(10,dlogb+dlogc) * a);
    }
    

    我不知道boost库中是否有任何东西可以在编译时使用TMP来做这样的计算。

        6
  •  0
  •   lornova    14 年前

    .

    文本替换 ? 预处理器将输出C代码,用传递的值替换宏的参数。不管你传递一个变量还是一个常量,你只会得到一个伪替换(也称为宏“扩展”)。

    让我们看看预处理器将如何“扩展” #define cat(a,b,c) a##b##c .

    d=cat(1,2,3); 扩展到: d=123; 这是有效的代码,因为您已经声明 int d

    d=cat(a,b,c); 扩展到: d=abc; 因为没有 int abc 变量。

    什么意思 ? 这意味着这个文本替换是在源代码上完成的,输出会忽略传递给宏的变量的内容。换言之,您是否已初始化并不重要 a , b ,和 c 1 2 ,和 3 ## “令牌粘贴”预处理器运算符)。对你来说结果是 abc ,这意味着代码中没有任何内容。

        7
  •  0
  •   Solocle    11 年前

    可以使用预处理器定义的整数。
    预处理器需要调用另一个函数来展开。
    具体操作如下:

    #define I_BASE_CONCAT(x,y) x ## y
    #define I_CONCAT(x,y) I_BASE_CONCAT(x,y)
    

        8
  •  0
  •   Christian Phillips    11 年前

    还可以使用此函数连接3个整数 (当0是第二位或第三位数字时,上面的另一个intcat函数不起作用。这是因为0的对数是负无穷大,当你通过0时,它从你的总数中减去1)。

    unsigned intcat(unsigned a, unsigned b, unsigned c)
    {
    
    uint8_t ax = a;
    
    uint8_t bx = b;
    
    uint8_t cx = c;
    
    ax = (ax * 100);
    
    bx = (bx * 10);
    
    cx = (cx * 1);
    
    return(ax + bx + cx);
    
    }