[英]How to concatenate two or more Integers using Macros?
如果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;
}
你不能 - 當預處理器完成執行后程序在任意時間運行時,預處理器不知道變量以及要分配給它們的值。
hash-define宏是預編譯時間,在編譯之前進行預處理。 預處理器無法訪問變量值。 d=cat(a,b,c)
將被預處理器轉換為d=abc
。
您需要使用itoa
或類似的東西並連接生成的字符串然后atoi返回。
或者只是做一些算術來弄清楚結果。
預處理器字符串化不能對變量起作用,它必須采用文字並在處理過程中將其轉換為字符串; 預處理器在你的cat()
調用中不知道a
, b
和c
是什么等於。 您需要編寫一個實際使用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);
}
我不知道升級庫中是否有任何東西可以在編譯時使用TMP進行這樣的數學運算。
預處理器定義的整數是可能的。
預處理器需要調用另一個函數來擴展。
你這樣做:
#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代碼,用傳遞的值代替宏的參數。 如果傳遞變量或常數並不重要,您將獲得虛擬替換(也稱為宏“擴展”)。
讓我們來看看預處理器如何“擴展” #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
,這意味着您的代碼中沒有任何內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.