循環(huán)里Continue,Break,Return經(jīng)常會(huì)用到,也是很容易出錯(cuò)的一個(gè)坑,之前在循環(huán)里continue,break,return的作用,你知道嗎? 說(shuō)到過(guò)各自的用法,存在即合理,說(shuō)能使用或者堅(jiān)決不用沒(méi)意義,這不是教條主義,但也有需要注意的地方,來(lái)打自己臉了。 循環(huán)語(yǔ)句(for,while)里面出現(xiàn)return是沒(méi)什么問(wèn)題的,但是如果使用了continue或者break語(yǔ)句,那么就會(huì)使得循環(huán)的邏輯和終止條件變得有些復(fù)雜起來(lái)了,尤其是在一些裸機(jī)比較繞的地方,難以保證其正確性。 為什么需要用continue或者break?
那怎么辦呢?有些邏輯確實(shí)也是需要,這種情況如果循環(huán)里出現(xiàn)了continue或者break,我們就應(yīng)該考慮改寫(xiě)這個(gè)循環(huán),讓代碼看著更簡(jiǎn)單易懂。 怎么改寫(xiě)continue或者break?下面我對(duì)這些情況舉一些例子。 情況1 下面這段代碼里面有一個(gè)continue: 解釋?zhuān)喝绻渲幸粋€(gè)事件等于一個(gè)壞的事件數(shù),那么將跳過(guò)去,執(zhí)行下一個(gè)狀態(tài)。為了知道它到底在干什么,這里continue會(huì)導(dǎo)致一些語(yǔ)句被跳過(guò)了。 含有continue和break的循環(huán)不是那么容易理解,它們依靠控制流來(lái)描述邏輯,結(jié)果到最后很容易導(dǎo)致我們不能充分理解其中的涵義。 其實(shí),我們只需要把continue的條件反向,這段代碼就可以很容易的被轉(zhuǎn)換成等價(jià)的,不含continue的代碼: 解釋?zhuān)喝绻渲幸粋€(gè)事件等于一個(gè)壞的事件數(shù),那么將跳過(guò)去,執(zhí)行下一個(gè)狀態(tài)。為了知道它到底在干什么,這里continue會(huì)導(dǎo)致一些語(yǔ)句被跳過(guò)了。 pTrans = findTranss(pSM, evt); for(evt=0;evt<StateNum;evt ) { if (evt == BadNum) { continue; } pSM->state = pTrans->nextState; ... } 含有continue和break的循環(huán)不是那么容易理解,它們依靠控制流來(lái)描述邏輯,結(jié)果到最后很容易導(dǎo)致我們不能充分理解其中的涵義。 其實(shí),我們只需要把continue的條件反向,這段代碼就可以很容易的被轉(zhuǎn)換成等價(jià)的,不含continue的代碼: pTrans = findTranss(pSM, evt);for(evt=0;evt<StateNum;evt ){ if (evt != BadNum) { pSM->state = pTrans->nextState; ... }} 我們只需要把condition2反轉(zhuǎn)之后,放到while頭部的終止條件,就可以去掉這種break語(yǔ)句。更改后的代碼如下: while (condition1 && !condition2) { ... } 表面上這種情況只適用于break出現(xiàn)在循環(huán)開(kāi)頭或者末尾的時(shí)候,然而在大部分時(shí)候,break都可以通過(guò)某種方式,移動(dòng)到循環(huán)的開(kāi)頭或者末尾。 情況2當(dāng) break 語(yǔ)句出現(xiàn)在一個(gè)for和while循環(huán)內(nèi)時(shí),循環(huán)會(huì)立即終止,且程序流將繼續(xù)執(zhí)行緊接著循環(huán)的下一條語(yǔ)句,break其實(shí)是給這個(gè)循環(huán)增加了一個(gè)退出條件。往往只需要把這個(gè)條件合并到循環(huán)頭部,就可以去掉break。 比如下面這段代碼,當(dāng)condition2成立的時(shí)候,break就會(huì)退出循環(huán): while (condition1) { ... if (condition2) { break; }} 情況3 很多break退出循環(huán)之后,其實(shí)接下來(lái)就是一個(gè)return。這種break往往可以直接換成return。比如下面這個(gè)例子: _Bool eventState{ _Bool result = false; pTrans = findTranss(pSM, evt); for(evt=0;evt<StateNum;evt ) { if (evt == BadNum) { result = true; break; } } return result; } 這個(gè)函數(shù)檢查names鏈表里是否存在一個(gè)名字,包含“bad”這個(gè)詞。它的循環(huán)里包含一個(gè)break語(yǔ)句。這個(gè)函數(shù)可以被改寫(xiě)成: _Bool eventState{ _Bool result = false; pTrans = findTranss(pSM, evt); for(evt=0;evt<StateNum;evt ) { if (evt == BadNum) { return true; } } return false;} 改進(jìn)后的代碼,當(dāng)事件是壞的序號(hào)時(shí),直接用return true返回,如果循環(huán)結(jié)束了還沒(méi)有return,那就返回false。使用return來(lái)代替break,這樣break語(yǔ)句和result這個(gè)變量,都一并被消除掉了。 可以說(shuō)絕大部分的break和continue,都可以通過(guò)替換成return語(yǔ)句,或者翻轉(zhuǎn)if條件的方式來(lái)消除掉,變換后的代碼也會(huì)變得清晰很多。而一些含有復(fù)雜的邏輯的代碼,也可以通過(guò)提取一個(gè)幫助函數(shù)來(lái)消除掉。 總結(jié) 經(jīng)驗(yàn)總結(jié)幾個(gè)點(diǎn),去掉break和continue的代碼變得容易理解,確保正確。
|
|