如果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