用一個(gè)宏實(shí)現(xiàn)求兩個(gè)數(shù)中的最大數(shù)最常見的實(shí)現(xiàn)方法??在面試或者筆試中,經(jīng)常會(huì)碰到“用一個(gè)宏實(shí)現(xiàn)求兩個(gè)數(shù)中的最大數(shù)”這個(gè)題目,大家看到這個(gè)問題,覺得很容易實(shí)現(xiàn),認(rèn)為這有什么難度呢,隨手就是一個(gè):
注:用括號(hào)將宏定義整個(gè)括起來,在任何時(shí)候,都是一個(gè)好習(xí)慣。 ??上邊那個(gè)宏定義,一般情況下,是可以滿足需求的,但是對(duì)于一些參數(shù)具有副作用的情況,就很容易出現(xiàn)意想不到的結(jié)果了。比如:
??以上例子,結(jié)果會(huì)根據(jù)編譯器的差異,產(chǎn)生一些意外的結(jié)果,這些絕對(duì)不會(huì)是程序開發(fā)者想要的結(jié)果,自己可以思考下... 防止參數(shù)副作用的實(shí)現(xiàn)方法??為了防止宏定義的兩個(gè)參數(shù)存在副作用的情況,可以將傳遞給宏定義的參數(shù),在對(duì)比之前,保留一份備份,用備份參數(shù)來進(jìn)行對(duì)比,總不會(huì)錯(cuò)了吧,并且這樣實(shí)現(xiàn),參數(shù)的副作用僅計(jì)算一次,不會(huì)影響對(duì)比的結(jié)果,實(shí)現(xiàn)方式如下MAX_2:
??然而,很快就發(fā)現(xiàn),以上MAX_2宏定義,僅僅是用在對(duì)比兩個(gè)int型參數(shù)時(shí),實(shí)際情況可能對(duì)比的是unsigned char,或者其他的類型,那么這個(gè)宏定義也不能很好地實(shí)現(xiàn)預(yù)期效果。 指定參數(shù)類型的實(shí)現(xiàn)方法??繼續(xù)改進(jìn),將要對(duì)比的參數(shù)類型以一個(gè)參數(shù)的形式傳遞給宏定義,比如下面MAX_3:
??這樣,宏定義要對(duì)比的兩個(gè)參數(shù)的參數(shù)類型,以參數(shù)的形式傳遞給宏定義,在宏定義中,type參數(shù),將是宏定義中傳遞的那個(gè)參數(shù)類型,使用方法如下:
??MAX_3宏定義,很好地實(shí)現(xiàn)了對(duì)于不同類型的兩個(gè)參數(shù)求最大值的功能,但是先不要太高興,因?yàn)镸AX_3還是存在些缺點(diǎn)的,比如,對(duì)于一些粗心大意,導(dǎo)致傳遞的兩個(gè)參數(shù),存在和第一個(gè)參數(shù)類型不一致的情況,如下:
??以上情況,可能只是手誤,但是這個(gè)意外確實(shí)存在了,而MAX_3宏定義也確實(shí)會(huì)正常執(zhí)行,但是結(jié)果可能就不是實(shí)現(xiàn)者的本意,而在代碼中也很難被查出來,大家應(yīng)該都有花費(fèi)大量時(shí)間查Bug,最后發(fā)現(xiàn)是一個(gè)小符號(hào)錯(cuò)誤的情況,太無奈,不再多說... 相對(duì)最安全的實(shí)現(xiàn)方法??以上情況,也是有方法的,比如下面這個(gè)MAX_4宏定義:
??MAX_4宏定義,通過typeof關(guān)鍵字,來獲取參數(shù)的類型,并保存參數(shù)的一份拷貝,防止參數(shù)副作用影響對(duì)比結(jié)果,再通過(void)(&_x == &_y);來對(duì)比兩個(gè)參數(shù)類型,如果不是同一種類型,在編譯階段就會(huì)報(bào)出warning,引起開發(fā)者注意,提前消滅隱患。 總結(jié)??經(jīng)過以上幾種寫法的對(duì)比,會(huì)發(fā)現(xiàn)最后一種MAX_4宏定義的使用還是很安全的。如果應(yīng)試者能夠在筆試中很快地寫出MAX_4宏定義的實(shí)現(xiàn)方式,我相信絕對(duì)會(huì)給考官們眼前一亮,甚至是驚艷的效果。 |
|