簡體   English   中英

如何使用宏連接兩個或多個整數?

[英]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()調用中不知道abc是什么等於。 您需要編寫一個實際使用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變量。

編譯時間是什么意思? 這意味着此文本替換是在源代碼上完成的,輸出忽略傳遞給宏的變量的內容。 換句話說,它是你沒有初始化事項abc123 :結果會是公正的級聯(由於##所傳遞的“標記粘貼”預處理操作符)值。 在您的情況下,結果是abc ,這意味着您的代碼中沒有任何內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM