淺析C++宏定義里#和##的使用
工作中如果是c開發(fā)的話,經(jīng)常會用到宏定義,而宏定義中的#和##也會時不時遇到,今天分享這兩個符號的作用。
1,# -- 轉(zhuǎn)換成字符串
直接看例子:
#include <stdio.h> #include <stdlib.h> #define VAL2STR(VAL) (#VAL) #define fun_call_rt(func) \ do \ { \ int ret = func; \ if(ret){printf("%d = %s\n", ret, #func);} \ } while (0); int func_for_test(int value); int main() { int val = 200; printf("%s\n", VAL2STR(200)); fun_call_rt(func_for_test(10)); return 0; } int func_for_test(int value) { if(value == 100) { return 0; } else { return -1; } }
我們可以直接用gcc -E 預(yù)編譯看看宏展開后是什么樣的?如用命令 gcc -E test_#.c -o preprocess_test 編譯后,我們看最后的代碼:
其中的 VAL2STR(200) 被替換成了 ("200"),fun_call_rt(func) 中的 #func 被替換成了 "func_for_test(10)",即都被替換成了字符串,在c語言中應(yīng)該稱為字符數(shù)組類型。
在一些公司中類似 fun_call_rt(func) 宏幾乎處處可見,在每個函數(shù)調(diào)用的地方都是這個宏括起來,一旦有錯誤發(fā)生,打印輸出一目了然。
2, ## -- 連接兩個語句為一個語句
這里所說的語句,可以是函數(shù)名,類型名,變量名,但都需要有實際意義,否則就會編譯不過,看代碼:
#include <stdio.h> #include <stdlib.h> #define NAME_JOIN(x,y) x##y int func_for_test_1(); int main() { printf("%p\n", NAME_JOIN(func_for_test, _1)); return 0; } int func_for_test_1() { return 10; }
假如我改成 printf("%p\n", NAME_JOIN(func_for_test1, _1)); 在編譯的時候會出現(xiàn)錯誤:
因為 NAME_JOIN(func_for_test1, _1) 只是簡單的把兩個短語連接為一個短語,而連接后的這個短語是否有效那就要做語法檢測了,如上面執(zhí)行的結(jié)果為:打印函數(shù)的地址
那如果改成這樣:printf("ret = %d\n", NAME_JOIN(func_for_test, _1)()); 就是一個函數(shù)調(diào)用了,其結(jié)果就是:
而有一種情況這個 ## 可能不會是你想要的結(jié)果,那就是宏定義里又包含宏定義,如:
#include <stdio.h> #include <stdlib.h> #define NUMBER_1 _1 //#define NAME_JOIN(x,y) NAME_JOIN2(x,y) #define NAME_JOIN(x,y) x##y int func_for_test(int value); int func_for_test_1(); int main() { printf("ret = %d\n", NAME_JOIN(func_for_test, NUMBER_1)()); return 0; } int func_for_test_1() { return 10; }
NAME_JOIN(func_for_test, NUMBER_1) 宏定義里又包含了宏 NUMBER_1,這樣編譯會出現(xiàn)什么問題呢?
可以看到 NUMBER_1 沒有被展開,我們想要的是它被展開為 -1,即 func_for_test_1。處理辦法就是再多加一個宏定義,如:
#include <stdio.h> #include <stdlib.h> #define NUMBER_1 _1 #define NAME_JOIN(x,y) NAME_JOIN2(x,y) #define NAME_JOIN2(x,y) x##y int func_for_test(int value); int func_for_test_1(); int main() { printf("ret = %d\n", NAME_JOIN(func_for_test, NUMBER_1)()); return 0; } int func_for_test_1() { return 10; }
這樣就能正確展開,編譯成功。
以上就是淺析C++宏定義里#和##的使用的詳細(xì)內(nèi)容,更多關(guān)于C++宏定義的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
c語言中malloc、realloc與calloc 的區(qū)別以及聯(lián)系
以下是對c語言中的malloc函數(shù),realloc函數(shù)與calloc函數(shù)的區(qū)別以及它們之間的聯(lián)系進(jìn)行了介紹,需要的朋友可以過來參考下2013-08-08