如果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;
}
答案 0 :(得分:10)
你不能 - 预处理器不知道变量以及当程序在预处理器执行完毕后的任意时间运行时你要分配给它们的值。
答案 1 :(得分:3)
hash-define宏是预编译时间,在编译之前进行预处理。预处理器无法访问变量值。 d=cat(a,b,c)
将由预处理器转换为d=abc
。
您需要使用itoa
或类似的东西并连接生成的字符串,然后再返回atoi。
或者只是做一些算术来计算结果。
答案 2 :(得分:1)
预处理器字符串化不能对变量起作用,它必须采用文字并在处理过程中将其转换为字符串;预处理器在您的a
调用中不知道b
,c
和cat()
等于什么。您需要编写一个实际使用C ++进行组合的宏。例如:
#define cat(a, b, c, d) \
do { \
std::stringstream ss; \
ss << a << b << c; \
ss >> d; \
} while(0)
(do/while(0)
是一种常见的黑客行为,可让您在cat
安全通话后添加分号
您将无法使用此“返回值”,但您可以这样做:
int a = 1, b = 2, c = 3, d;
cat(a, b, c, d);
// d == 123 now
答案 3 :(得分:1)
这可能是一个起点:
#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);
}
答案 4 :(得分:1)
如果在编译时完成此操作并不重要,您可以使用以下内容:
#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);
}
我不知道升级库中是否有任何东西可以在编译时使用TMP进行这样的数学运算。
答案 5 :(得分:0)
C预处理器只在编译时进行虚拟文本替换。
文字替换是什么意思?预处理器将输出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
,这意味着您的代码中没有任何内容。
答案 6 :(得分:0)
预处理器可以定义整数。
预处理器需要调用另一个函数来扩展
你这样做:
#define I_BASE_CONCAT(x,y) x ## y
#define I_CONCAT(x,y) I_BASE_CONCAT(x,y)
就是这样。现在,如果你调用I_CONCAT,它会将它扩展为x ## y,但是使用x和y的值。
答案 7 :(得分:0)
您也可以使用此函数来连接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);
}