前言:
熟悉C語言的朋友應該對宏不陌生, 宏在C語言程序開發中是經常使用的,使用其的主要目的是方便程序員的編程工作,並且能在一定程度上提高程序的效率。C語言中提供的宏定義命令是#define。下面就使用宏的幾個小細節進行一些討論。
1,宏中使用()
在宏中,盡量多使用(),不要覺得無所謂或者覺得使用不使用沒有什麼影響。請切記,在宏中盡量多使用(),這樣才能盡量的保證你的宏的正確性。
舉個例子:
#define CAL(x,y) x+y
CAL(2,4)×CAL(2,5)
程序員的本意可能是要計算(2+4)×(2+5),但是事與願違,這個宏展開來是這樣的 2+4×2+5,與所要的結果完全不相符。
比較合理的定義應該是 #define CAL(x,y) ((x)+(y)),以避免不必要的歧義。
2,重復宏定義
盡量不要重復的定義宏,那樣會另程序的可讀性變的很差,並且容易出錯,難以維護。重復的宏定義以最後一次定義為准。
例子:
#define PI 3.14
#define PI 10.48
那麼在程序中PI的值應該是10.48,因為這是最後的定義。
3,危險的宏定義
宏定義在使用不當的時候會很危險,胡亂的定義會混淆程序員的思維,例如:
#define int char
#define break continue
這樣的宏定義是相當的危險,會使程序變的相當的混亂,難以閱讀,難以維護。
4,宏中的#與##
宏中的#可以將字符轉變成字符串,而##則可以進行宏參數拼接。
例如:
#define SUM(a,b) printf(" a add b is %d \n ", ((a)+(b)));
在程序中這樣使用該宏:SUM(1,2) 則輸出為 a add b is 3
請注意引號中的a和b被當作了普通的文本,而不是可以被替換的符號。如果想讓a和b成為被替換的符號,可以這樣定義該宏:
#define SUM(a,b) printf(" #a add #b is %d \n ", ((a)+(b)));
在程序中這樣使用該宏:SUM(1,2) 則輸出為 1 add 2 is 3
和#運算符一樣,使用##也可以用於宏的替換部分,該符號可以把兩個符號拼接成一個符號。例子如下:
#define NAME(x,y) x##y
在程序中這樣使用該宏:NAME(Steve, Johnson) 則該宏會被展開成這樣: SteveJohnson
5,宏定義注意分號;的使用
宏定義中注意分號的使用,在宏定義中胡亂使用分號會使程序出現一些莫名其妙的錯誤。
例如:
#define SUM(a,b) ((a)+(b));
在程序中這樣使用該宏:SUM(a1,b1)+SUM(a2,b2)
這樣宏展開後就會變成((a1)+(b1));+((a2)+(b2)) 這樣程序就會出錯。
6,一個有趣的關於宏的測試題:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define num 10
#define f(x) #x
#define g(x) f(x)
int main()
{
printf("f(num)=%s g(num)=%s \n",f(num),g(num));
}
這是一個很有趣的關於宏的小題目,大家可以想想輸出結果是什麼。
我們可以使用命令 gcc -E marco.i marco.c > a.txt 去將預處理的結果存到a.txt文件裡去查看,main函數經過預處理的結果是:
int main()
{
printf("f(num)=%s g(num)=%s \n","num","10");
}
我們可以看到f(x) 由於有#符號,因此num沒有被替換成10,而g(x) 應該先被替換成f(x),於此同時將num替換成了10,變成了#10,因此結果是num 和 10。