天天看點

c語言goto語句用法_C語言程式開發中,多個if語句混在一起,代碼看起來很亂怎麼辦?...問題怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?小結

if 分支語句是C語言程式開發中不可缺少的控制結構之一,它廣泛存在于各個C語言程式中。甚至有程式員認為寫程式就是将各種情況都考慮到,然後使用if-else語句将這些情況描述出來。

c語言goto語句用法_C語言程式開發中,多個if語句混在一起,代碼看起來很亂怎麼辦?...問題怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?小結

怎樣避免C語言if語句鍊

問題

不過,在C語言程式開發中,濫用 if 語句常常會讓整個代碼變得啰嗦且不可讀,C語言初學者小明也發現了這一點。下面是一段C語言代碼示例,請看:

bool conditionA = executeStepA();if (conditionA){ bool conditionB = executeStepB(); if (conditionB){ bool conditionC = executeStepC(); if (conditionC){ ... } }}executeThisFunctionInAnyCase();           
c語言goto語句用法_C語言程式開發中,多個if語句混在一起,代碼看起來很亂怎麼辦?...問題怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?小結

C語言代碼示例

executeStepX() 函數隻有在前一個函數執行結果為真時才會執行,而 executeThisFunctionInAnyCase() 函數則無論如何都會執行。小明覺得雖然這樣寫C語言代碼可以實作需求,但是 if 語句鍊顯然不是一種優雅的寫法,他希望在自己的代碼中避免 if 語句鍊出現,是以嘗試對上述C語言代碼做了如下修改,請看:

bool conditionA = executeStepA();if (!conditionA) return;bool conditionB = executeStepB();if (!conditionB) return;bool conditionC = executeStepC();if (!conditionC) return;           
c語言goto語句用法_C語言程式開發中,多個if語句混在一起,代碼看起來很亂怎麼辦?...問題怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?小結

對上述C語言代碼做了修改

修改後的C語言代碼看起來簡潔多了,但是卻不能滿足需求——原先 executeThisFunctionInAnyCase() 函數無論如何都會執行,而現在它隻會在 executeStepX() 函數都成功才會執行。

怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?

按照小明的思路,其實隻要保證 executeThisFunctionInAnyCase() 函數無論如何都被執行就可以了,那完全可以多定義一個函數解決這個問題,相關的C語言代碼如下,請看:

void foo(){ bool conditionA = executeStepA(); if (!conditionA) return; bool conditionB = executeStepB(); if (!conditionB) return; bool conditionC = executeStepC(); if (!conditionC) return;}void bar(){ foo(); executeThisFunctionInAnyCase();}           
c語言goto語句用法_C語言程式開發中,多個if語句混在一起,代碼看起來很亂怎麼辦?...問題怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?小結

多定義一個函數解決這個問題

這樣就按照小明的思路解決了問題。當然了,問題的答案不止一個,另外一種非常推薦的做法是使用“短路表達式”,相關的C語言代碼如下,請看:

關于“短路表達式”的概念,可以參考我之前的文章《C語言的“短路表達式”》;
if (executeStepA() && executeStepB() && executeStepC()){ ...}executeThisFunctionInAnyCase();           
c語言goto語句用法_C語言程式開發中,多個if語句混在一起,代碼看起來很亂怎麼辦?...問題怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?小結

使用“短路表達式”

C語言程式的“短路表達式”決定了隻有 executeStepA() 函數成功才會接着執行 executeStepB() 函數,隻有 executeStepB() 函數也成功,才會執行 executeStepC() 函數。而無論如何,executeThisFunctionInAnyCase() 函數都會被執行,這樣就以較為簡潔的方式解決了小明遇到的問題。

另外,還有一種很多C語言程式員都鄙視的方法——使用 goto 語句。我知道很多學校很多教材都非常抵制 goto 語句的“使用”,這裡的“使用”打上了引号,是因為我認為他們反對的應該是 goto 語句的濫用,事實上,恰當的使用 goto 語句能夠在很多時候簡化C語言代碼,例如:

int foo() { int result = /*some error code*/; if(!executeStepA()) goto cleanup; if(!executeStepB()) goto cleanup; if(!executeStepC()) goto cleanup; result = 0;cleanup: executeThisFunctionInAnyCase(); return result;}           
c語言goto語句用法_C語言程式開發中,多個if語句混在一起,代碼看起來很亂怎麼辦?...問題怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?小結

恰當的使用 goto 語句

這樣的代碼風格在 Linux 核心代碼中相當常見。也有些程式員習慣使用 do{}while(0) 包裹代碼,并且通過 break 關鍵字提前跳出代碼塊,但實際上兩種方法是一緻的。如果還有其他的一些工作需要處理,goto 語句更友善,例如:

int foo() { int result = /*some error code*/; if(!executeStepA()) goto cleanupPart; if(!executeStepB()) goto cleanup; if(!executeStepC()) goto cleanup; result = 0;cleanup: innerCleanup();cleanupPart: executeThisFunctionInAnyCase(); return result;}           
c語言goto語句用法_C語言程式開發中,多個if語句混在一起,代碼看起來很亂怎麼辦?...問題怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?小結

goto 語句更友善

這種情況下如果使用 do{}while(0) 方法,就需要使用不止一個循環體,要是如此類推下去,循環體本身也會帶來代碼複雜度,這樣的技巧就顯得有些雞肋了。

小結

本節通過一個例子,簡要的讨論了在C語言代碼中避免 if 語句鍊的幾種常用方法。當然了,本節隻是抛磚引玉,相信讀者肯定也有自己的技巧,歡迎在評論區讨論。同時,我們也能看出,C語言程式開發并不隻是使用計算機語言描述“流水賬”,多思考,總是能寫出更加簡潔優雅的代碼的。

c語言goto語句用法_C語言程式開發中,多個if語句混在一起,代碼看起來很亂怎麼辦?...問題怎樣才能避免 if 語句鍊,并且完美實作小明的需求呢?小結

點個贊再走吧

歡迎在評論區一起讨論,質疑。文章都是手打原創,每天最淺顯的介紹C語言、linux等嵌入式開發,喜歡我的文章就關注一波吧,可以看到最新更新和之前的文章哦。

未經許可,禁止轉載。

繼續閱讀