一、前言
C語言真的是學無止境的感覺,大部分同學大學都會開設C語言課程。很多人把C語言二級過了就感覺入門了;對於那些在做嵌入式開發的工程師,幾乎每天都要接觸C語言,很多人會感覺自己C語言學得很溜了。那好,咱們用一道C語言面試題來測試一下。
二、面試題
首先給出題目:
定義一個宏,求兩個數中的最大數
OK,很多人應該能很快寫出
#define MAX(x,y) x > y ? x : y
接下來我們寫一個測試程序
#define MAX(x,y) x > y ? x : y
int main(void)
{
printf("max=%d",MAX(1,3)); //測試通過
printf("max=%d",MAX(4,1));//測試通過
printf("max=%d",MAX(2,2));//測試通過
printf("max=%d",MAX(3!=3,1!=2)); //好像不是我們要的結果
return 0;
}
我們會發現第四個測試不是我們的要結果了。這是因爲宏展開後,就變成了這個樣子:
printf("max=%d",3!=3>1!=2?3!=3:1!=2);
這個時候大於號(>)的優先級更高,所以就出現了問題了。
優化上面的代碼
可能很多人已經想到了解決方法了,比較有經驗的工程師基本也比較少犯上面的錯誤。
加上括號就可以解決上面的問題了。
#define MAX(x,y) (x) > (y) ? (x) : (y)
OK,接下來我們再寫一個測試程序
#define MAX(x,y) (x) > (y) ? (x) : (y)
int main(void)
{
printf("sum =%d", 7 + MAX(3,4));
return 0;
}
運行結果:
並不是我們所期望的11。我們將其展開後爲:
7 + (3) > (4) ? (3) : (4);
這個時候加號(+)的優先級又比大於號(>)高,所以就出現了這種結果。
那我們就繼續加個括號
#define MAX(x,y) ((x) > (y) ? (x) : (y))
到這裏算是比較完整的了,在面試中要是能寫出這個,那算基本功還是比較紮實的了。
那我們再寫一個測試程序
#define MAX(x,y) ((x) > (y) ? (x) : (y))
int main(void)
{
int i = 3;
int j = 4;
printf("max=%d",MAX(i++,j++));
return 0;
}
運行結果:
這裏面的j會做兩次自增運算, 所以打印出來的結果是做了一次自增後的結果。
繼續優化
#define MAX(type,x,y)({ \
type _x = x; \
type _y = y; \
_x > _y ? _x : _y; \
})
int main(void)
{
int i = 4;
int j = 5;
printf("max=%d\n",MAX(int,i++,j++));
printf("max=%f\n",MAX(float,3.2,3.4));
return 0;
}
到這裏基本算比較完美了!是不是很折騰, 程序的bug就是這樣一步一步修復的過程。
三、總結
如果你能一下就寫出最後的代碼,那說明你確實是666了,通過上面的一步一步分析是爲了告訴大家,C語言真的有很多東西可以讓我們去琢磨!我們也還有很長的路要走。