很多時候當你完成了c語言語法的學習,特別適合一些擴充套件用法之後,自身會陷入乙個自滿的大坑,以為自己啥都會了,但其實自己水平到底怎樣,你自己也不知道。那麼今天我就帶著大家測一測你的嵌入式c學的到底有多牛(low)。
自測題:請定義乙個巨集,求兩個數中的最大數。
對於學過c語言的同學,寫出這個巨集基本上不是什麼難事,使用條件運算子就能完成:
#define max(x,y) x > y ? x : y
這是最基本的c語言語法,如果連這個也寫不出來,估計你還沒進c的大門。但一般這種水平,公司是不會要你的,因為你還是門外漢!
不信?舉個反例,驗證一下我們定義的巨集是否正確:
#define max(x,y) x > y ? x : y
int main(void)
當巨集的引數是乙個表示式,發現實際執行結果為max=0,跟我們預期結果max=1不一樣。這是因為,巨集展開後,就變成了這個樣子:
printf("max=%d",1!=1>1!=2?1!=1:1!=2);
因為比較運算子 > 的優先順序為6,大於 !=(優先順序為7),所以展開的表示式,運算順序發生了改變,結果就跟我們的預期不一樣了。
為了避免這種展開錯誤,我們可以給巨集的引數加乙個小括號()來防止展開後,表示式的運算順序發生變化。這樣的巨集才能算乙個合格的巨集:
#define max(x,y) (x) > (y) ? (x) : (y)
但上面的巨集還是存在漏洞。
比如,我們使用下面的**測試:
#define max(x,y) (x) > (y) ? (x) : (y)
int main(void)
在程式中,我們列印表示式 3 + max(1, 2) 的值,預期結果應該是5,但實際執行結果卻是1。我們展開後,發現同樣有問題:
3 + (1) > (2) ? (1) : (2);
因為運算子 + 的優先順序大於比較運算子 >,所以這個表示式就變為4>2?1:2,最後結果為1也就見怪不怪了。
我們繼續修改這個巨集:
#define max(x,y) ( (x) > (y) ? (x) : (y) )
使用小括號將巨集定義包起來,這樣就避免了當乙個表示式同時含有巨集定義和其它高優先順序運算子時,破壞整個表示式的運算順序。
上面的巨集,雖然解決了運算子優先順序帶來的問題,但是仍存在一定的漏洞。
比如:
#define max(x,y) ((x) > (y) ? (x) : (y))
int main(void)
在程式中,我們定義兩個變數 i 和 j,然後比較兩個變數的大小,並作自增運算。實際執行結果發現max = 7,而不是預期結果max = 6。這是因為變數 i 和 j 在巨集展開後,做了兩次自增運算,導致列印出 i 的值為7。
遇到這種情況,語句表示式就該上場了。我們可以使用語句表示式來定義這個巨集,在語句表示式中定義兩個臨時變數,分別來暫儲 i 和 j 的值,然後進行比較,這樣就避免了兩次自增、自減問題。
#define max(x,y)()
int main(void)
在語句表示式中,我們定義了2個區域性變數_x、_y來儲存巨集引數 x 和 y 的值,然後使用 _x 和 _y 來比較大小,這樣就避免了 i 和 j 帶來的2次自增運算問題。
如果你能堅持到了這一關,並寫出這樣自帶bgm的巨集,說明你有了比較好的語言基礎,是可雕琢一塊木頭,面試官心裡可能已經有了給你offer的意願了。
在上面這個巨集中,我們定義的兩個臨時變數資料型別是int型,只能比較兩個整型的資料。那對於其它型別的資料,就需要重新再定義乙個巨集了,這樣太麻煩了!我們可以基於上面的巨集繼續修改,讓它可以支援任意型別的資料比較大小:
#define max(type,x,y) ( )
int main(void)
在這個巨集中,我們新增乙個引數:type,用來指定臨時變數 _x 和 _y 的型別。這樣,我們在比較兩個數的大小時,只要將2個資料的型別作為引數傳給巨集,就可以比較任意型別的資料了。如果你能寫出這樣的巨集,說明你是可雕琢的一塊玉,試官肯定會非常高興他遇到了你。
上面的巨集定義中,我們增加了乙個type型別引數,來相容不同的資料型別,此時此刻,為了這個超,我們應該把這個也省去。
如何做到?使用typeof就可以了,typeof是gnu c新增的乙個關鍵字,用來獲取資料型別,我們不用傳參進去,讓typeof直接獲取!
#define max(x, y) ()
在這個巨集定義中,使用了typeof關鍵字用來獲取巨集的兩個引數型別。乾貨在(void) (&x == &y);這句話,簡直是天才般的設計!一是用來給使用者提示乙個警告,對於不同型別的指標比較,編譯器會給乙個警告,提示兩種資料型別不同;二是,當兩個值比較,比較的結果沒有用到時,有些編譯器可能會給出乙個warning,加個(void)後,就可以消除這個警告 你的c 學的怎麼樣?
1.基本型別 各種型別是怎麼進行預設轉換的,強制轉換和各種cast都有什麼區別,編譯器如何對齊,pack和align是什麼東西 2.運算子 所有運算子的優化級都弄明白了麼?什麼能過載,什麼不能過載,什麼能運算子不會自動繼承交類?templateoperator const a const b 這樣的...
你的大學時光怎麼樣?
如果你已經畢業,請先想想你的大學時光是如何度過的,如果你正在上大學,請繼續看看吧!回想我的大學,基本上等於是遊戲大學,天天在網咖,在網遊中度過,最後兩年倒是稍微好了點,起碼交到了女朋友,現在已然快成為媳婦兒了。似乎普通大學裡多數人都是以網咖為家,考試以及格為準,當一天和尚撞一天鐘的活法。等到就業的時...
你的小學作文怎麼樣???(巨搞笑!
1 一同學上課打牌被發現後被要求寫檢查。第二天,其他打牌的人在班上念過檢查後,他走上講台 俗話說 天有不測風雲,人有禍福旦夕 我昨天上課打牌被老師發現了 我們老師當場悶掉!2 我和同學某某某一起騎車出門玩,他的氣門芯壞了,我就把我的拔下來給他裝上,我倆一起高高興興騎車回家了。3 運動會 公尺終於開始...