for迴圈及其注意事項,C語言使用for迴圈的注意事項總結

2020-07-16 10:04:23
C 語言 for 迴圈語句的一般形式為:

for (<初始化>;<條件表示式>;<增量>)
{
    迴圈體語句;
}

一般情況下,初始化總是一個賦值語句,它用來為迴圈控制變數賦初值;條件表示式則是一個關係表示式,它決定什麼時候退出迴圈;而增量定義迴圈控制變數每迴圈一次後按什麼方式變化。這三個部分之間用分號“;”分割開來。

盡量使迴圈控制變數的取值採用半開半閉區間寫法

從功能上看,雖然半開半閉區間寫法和閉區間寫法的功能是完全相同的,但相比之下,半開半閉區間寫法更能夠直觀地表達意思,具有更高的可讀性。下面,我們就通過範例程式碼看看兩者之間的區別。

其中,閉區間的寫法範例如下面的程式碼所示:
for(i=0;i<=n-1;i++)
{
    /*處理程式碼*/
}
在上面的程式碼中,i 值屬於閉區間寫法。

半開半閉區間的寫法範例如下面的程式碼所示:
for(i=0;i<n;i++)
{
    /*處理程式碼*/
}
在上面的程式碼中,i 值屬於半開半閉區間寫法,即“0=<i<n”,起點到終點的間隔為 n,迴圈次數為 n。

從上面的兩段範例程式碼中可以看出,儘管它們的功能是完全相同的,但相比之下,第二個程式範例(半開半閉區間寫法)具有更高的可讀性。因此,在 for 迴圈中,我們應該盡量使迴圈控制變數的取值採用半開半閉區間寫法。

盡量使迴圈體內工作量達到最小化

我們知道,for 迴圈隨著迴圈次數的增加,會加大對系統資源的消耗。如果你寫的一個迴圈體內的程式碼相當耗費資源,或者程式碼行數眾多(一般來說迴圈體內的程式碼不要超過 20 行),甚至超過一顯示屏,那麼這樣的程式不僅可讀性不高,而且還會讓你的程式的執行效率大大降低。這個時候,我們通常可以通過如下兩種方法進行優化。

1) 重新設計這個迴圈,確認這些操作是否都必須放在這個迴圈裡,並仔細考慮迴圈體內的語句是否可以放在迴圈體之外,從而使迴圈體內工作量最小化,提高程式的時間效率。如下面的範例程式碼所示:
for (i = 0;i < n;i++)
{
    tmp += i;
    sum = tmp;
}
很顯然,在上面的程式碼中每執行一次 for 迴圈,就要執行一次“sum=tmp”語句來重新為變數 sum 進行賦值,這樣的寫法很浪費資源。因此,我們完全可以將“sum=tmp”語句放在 for 語句之後,如下面的範例程式碼所示:
for (i = 0;i < n;i++)
{
    tmp += i;
}
sum = tmp;
這樣,“sum=tmp”語句只執行一次,不僅可以提高程式執行效率,而且程式也具有更高的可讀性。

2) 可以考慮將這些程式碼改寫成一個子函數,在迴圈中只呼叫這個子函數即可。

避免在迴圈體內修改回圈變數

在 for 迴圈語句中,我們應該嚴格避免在迴圈體內修改回圈變數,否則很有可能導致迴圈失去控制,從而使程式執行違背我們的原意,如下面的範例程式碼所示:
for(i=0;i<10;i++)
{
    i=10;
}
在上面的程式碼中,在迴圈體內對迴圈變數i進行賦值之後,for 迴圈中止執行,從而使程式執行違背我們的原意,更嚴重的情況會給程式帶來災難性的後果。

盡量使邏輯判斷語句置於迴圈語句外層

一般情況下,我們應該盡量避免在程式的迴圈體內包含邏輯判斷語句。當迴圈體內不得已而存在邏輯判斷語句,並且迴圈次數很大時,我們應該盡量想辦法將邏輯判斷語句移到回圈語句的外層,從而使程式減少執行邏輯判斷語句的次數,提高程式的執行效率。如下面的範例程式碼所示:
for (i = 0;i < n;i++)
{
    if (condition)
    {
            DoSomething();
    }
    else
    {
            DoOtherthing();
    }
}
在上面的程式碼中,每執行一次 for 迴圈,都要執行一次 if 語句判斷。當 for 迴圈的次數很大時,執行多餘的判斷不僅會消耗系統的資源,而且會打斷迴圈“流水線”作業,使得編譯器不能對迴圈進行優化處理,降低程式的執行效率。因此,我們可以通過將邏輯判斷語句移到回圈語句的外層的方法來減少判斷的次數,如下面的程式碼所示:
if (condition)
{
    for (i = 0;i < n;i++)
    {
            DoSomething();
    }
}
else
{
    for (i = 0;i < n;i++)
    {
            DoOtherthing();
    }
}
雖然上面的程式碼沒有前面的看起來簡潔,但卻使程式執行邏輯判斷語句減少 n-1 次,在 for 迴圈次數很大時,這種優化顯然是值得的。

最後還需要注意的是,迴圈體中的判斷語句是否可以移到回圈體外,要視程式的具體情況而定。一般情況下,與迴圈變數無關的判斷語句可以移到回圈體外,而有關的則不可以。

盡量將多重回圈中最長的迴圈放在最內層,最短的迴圈放在最外層

在多重 for 迴圈中,如果有可能,應當儘量將最長的迴圈放在最內層,最短的迴圈放在最外層,以減少 CPU 跨切迴圈層的次數。如下面的範例程式碼所示:
for (i=0;i<100;i++)
{
    for (j=0;j<5;j++)
    {
            /*處理程式碼*/
    }
}
為了提高上面程式碼的執行效率,我們可以依照這條建議將上面的程式碼修改為如下形式:
for (j=0;j<5;j++)
{
    for (i=0;i<100;i++)
    {
            /*處理程式碼*/
    }
}
這樣,既不會失去程式原有的可讀性,同時也提高了程式的執行效率。

盡量將迴圈巢狀控制在 3 層以內

有研究資料表明,當迴圈巢狀超過 3 層,程式設計師對迴圈的理解能力會極大地降低。同時,這樣程式的執行效率也會很低。因此,如果程式碼回圈巢狀超過 3 層,建議重新設計迴圈或將迴圈內的程式碼改寫成一個子函數。