淺析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ù)名,類型名,變量名,但都需要有實(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++ min/max_element 函數(shù)用法詳解
這篇文章主要介紹了C++ min/max_element 函數(shù)用法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02
C++中sln,vcxproj,vcxproj.filters,lib,dll,exe的含義說明
這篇文章主要介紹了C++中sln,vcxproj,vcxproj.filters,lib,dll,exe的含義說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
win10+VS2017+Cuda10.0環(huán)境配置詳解
這篇文章主要介紹了win10+VS2017+Cuda10.0環(huán)境配置詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
C語言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表
這篇文章主要為大家詳細(xì)介紹了c語言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11

