文章**:
首先已知#define a 「hello」
#define b 「world」
如何使用巨集a,b表示出字串"helloworld"
答案1:#define c a b
答案2:#define c(a,b) a##b
#define c(a,b) c(a,b)
答案1驗證:
例如使用巨集預編譯案例:
#include
#define a "hello"
#define b "world"
#define str a b
intmain
(int argc,
char
*ar**)
預編譯:
gcc -e hell.c -o hello.i
cat hello.i
預編譯之後的資料檢視:
...
# 7 "hello.c"
int main(int argc,char *ar**)
可知答案一併不正確。
答案2驗證:
#include
#define a "hello"
#define b "world"
#define _c_(a,b) a##b
#define c(a,b) _c_(a,b)
intmain
(int argc,
char
*ar**)
首先為什麼要定義兩個巨集,乙個不能解決嗎?是的,不能。參見:(短小精悍的巨集)
按照上邊的編譯之後出現了錯誤資訊:
hello.c: in function 『main』:
hello.c:3:11: error: pasting ""hello"" and ""world"" does not give a valid preprocessing token
#define a "hello"
^...
解決,google之後,可以參見:問題
並且裡面說了,這種情況在vs裡面不會報錯,可以直接工作。
#include
#define a "hello"
#define b "world"
#define _c_(a,b) a##b
#define c(a,b) _c_(a,b)
int _tmain(int argc, _tchar* ar**)
果然給出了結果:menuosd
為什麼gcc和vs會對這個問題給出差異的結果呢?看這個問題:that』s why
根據c標準,用##操作之後的結果必須是乙個已經定義過的符號。否則是未定義的。所以gcc和vs對於這個未定義的行為表示了不同的看法,前者是給出了錯誤,後者是一笑而過。name為什麼是預定過的符號呢?它包含了這些內容:頭檔名,等式,預處理數學,字元常數,字串值,標點符號,單個非空字元等。
在給出的例子中,c(a,b)使用##連線之後,應該產生helloworld,但是這是乙個未預定的字串,所以產生了乙個未定義行為。再看乙個例子:
#include
#define a 2
#define _cons(a,b) (a##e##b)
#define cons(a,b) _cons(a,b)
intmain
(int argc,
char
*ar**)
C語言中關於巨集定義的一點總結
1 常見的巨集定義語句有不帶引數的巨集定義和帶引數的巨集定義兩種 2 帶引數的巨集定義,在比較複雜時,往往通過 字元進行換行分割,來使其更加清晰。比如 include include define func a,b printf the add of a and b is d n a b int m...
C語言中巨集函式定義的注意點
要寫好c語言,漂亮的巨集定義是非常重要的。巨集定義可以幫助我們防止出錯,提高 的可移植性和可讀性等。定義巨集函式handle error value define handle error value if cudastatus value 最近使用到巨集函式定義遇到兩個坑,以後要注意。首先 當巨集...
c語言中關於巨集
我們在寫c語言程式中,已經初步了解到了 define的用法,下面對 define做乙個詳細的用法說明。格式如下 define name stuff有了這條指令之後,每當有name出現,就會被預處理器替換為stuff。例 define reg register define do forever fo...