一道C面試題的思考

一、前言

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語言真的有很多東西可以讓我們去琢磨!我們也還有很長的路要走。

歡迎大家關注我的微信公衆號!!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章