如果A = 1,B = 2,C = 3 ......我想写一个连接它们像这样的123 但宏,当我试试这个:如何使用宏连接两个或多个整数?
#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;
}
如果A = 1,B = 2,C = 3 ......我想写一个连接它们像这样的123 但宏,当我试试这个:如何使用宏连接两个或多个整数?
#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;
}
你不能 - 预处理器没有关于变量的想法和价值观是什么你要分配给他们当预处理完成后,在一些任意时间程序运行执行。
换句话说,预处理器只处理标记而已。 – GManNickG 2010-06-25 17:22:44
哈希定义宏预编译时间并在编译之前进行预处理。预处理器将无法访问变量值。预处理器会将d=cat(a,b,c)
转换为d=abc
。
您将需要使用itoa
或类似的东西,并连接所得到的字符串,然后atoi回来。
或者只是做一些算术来找出结果。
预处理器字符串化无法在变量上工作,它必须在处理期间采用文字并将其转换为字符串;预处理器不知道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
这可能是一个起点:
#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);
}
如果它不是重要的,这是在编译时完成,你可以使用这样的事情:
#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来做这样的数学运算。
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
,这意味着你的代码没有任何意义。
预处理器定义的整数是可能的。
预处理器需要调用另一个函数来扩展。
你做到这一点,如下所示:
#define I_BASE_CONCAT(x,y) x ## y
#define I_CONCAT(x,y) I_BASE_CONCAT(x,y)
就在那儿。现在,如果您调用I_CONCAT,它会将其扩展到x ## y,但是会使用x和y的值。
你也可以使用这个函数连接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);
}
这是比C++代码更多的C代码。 – GManNickG 2010-06-25 17:22:11
如果将“abc = 123”添加到您的变量列表中,这将工作得很好。 – 2010-06-25 17:49:29