C語言中文網 目錄

for的用法詳解,C語言for循環完全攻略

for 循環語句的一般形式為:

for (表達式1; 表達式2; 表達式3)
{
        語句;
}

首先要強調兩點:
1) 表達式1、表達式2和表達式3之間是用分號;隔開的,千萬不要寫成逗號。

2) for(表達式1;表達式2;表達式3)的后面千萬不要加分號,很多新手都會犯這種錯誤——會情不自禁地在后面加分號。

因為 for 循環只能控制到其后的一條語句,而在C語言中分號也是一個語句——空語句。所以如果在后面加個分號,那么 for 循環就只能控制到這個分號,下面大括號里面的語句就不屬于 for 循環了。

下面來看看它的執行過程:
  1. 求解表達式1。
  2. 求解表達式2。若其值為真,則執行 for 語句中指定的內嵌語句,然后執行第3步;若表達式2值為假,則結束循環,轉到第5步。
  3. 求解表達式3。
  4. 轉回上面第2步繼續執行。
  5. 循環結束,執行 for 語句下面的語句。

從這個執行過程中可以看出,“表達式1”只執行一次,循環是在“表達式2”“表達式3”和“內嵌語句”之間進行的。

for語句最簡單的形式是:

for (循環變量賦初值; 循環條件; 循環變量增值)
{
    語句;
}


下面給大家寫一個程序,求 1+2+3+4+…+100 的總和。
# include <stdio.h>
int main(void)
{
    int i;
    int sum = 0;  //sum的英文意思是“總和”
    for (i=1; i<=100; ++i)  //++是自加的意思, ++i相當于i = i + 1
    {
        sum = sum + i;  /*等價于sum += i;但是不建議這么寫, 因為sum = sum + i看起來更清楚、更舒服*/
    }
    printf("sum = %d\n", sum);
    return 0;
}
輸出結果是:
sum = 5050

這個程序的功能是實現求 1+2+3+4+…+100 的和,如果不用循環,加一次就要一條語句,加 100 次就要 100 條語句。這里是從 1 加到 100,要是從 1 加到 10000 那就要 10000 條語句。但有了循環就很方便了,你想加到多少就加到多少,只要改一個參數就可以了。所以循環很重要。

下面按照執行過程看看上面這個程序是怎樣執行的。

1) 首先定義一個循環變量 i。定義的時候可以不給它賦初值,在 for 循環里面再給它賦初值也行。但前面說過,最好在定義變量的時候就對它進行初始化,如果值不確定就初始化為 0。所以程序中也可以在定義 i 的時候就給它賦初值,那么 for 循環里的“表達式1”就可以省略了,但分號不可以省略。

這樣的話,執行的時候就跳過第1步,直接進入第2步,其他的不變。所以程序也可以像下面這樣寫:
# include <stdio.h>
int main(void)
{
    int i = 1;
    int sum = 0;
    for (; i<=100; ++i)
    {
        sum = sum + i;
    }
    printf("sum = %d\n", sum);
    return 0;
}
當然表達式1加上也行,大不了再重新賦一次值。

2) 然后定義一個用來存放“和”的變量 sum,并給它賦初值 0,然后進入 for 循環:
  1. 首先求解表達式1,即給變量i賦初值,i=1;表達式1只執行這一次,下面都不會再執行了。
  2. 然后求解表達式2,若 1<=100 成立,則執行 for 循環中的內嵌語句,即 sum=0+1。
  3. 然后執行第3步,變量 i 自加 1,即變量 i 由 1 變為 2。
  4. 然后再求解表達式2,2<=100 成立,則執行 for 循環中的內嵌語句,sum=0+1+2。
  5. 然后再執行第3步,變量 i 自加 1,即變量 i 由 2 變為 3。
  6. 然后再求解表達式2,即 3<=100 成立,則執行 for 循環中的內嵌語句,sum=0+1+2+3。
  7. ……

就這樣一直循環下去,直到 ++i 等于 100 的時候,求解表達式2,即 100<=100 成立,則執行 for 循環中的內嵌語句,sum=0+1+2+3+…+100。

然后再執行第3步,變量 i 自加 1,即變量 i 由 100 變為 101。然后再求解表達式2,即 101<=100 不成立,則結束循環,執行 for 循環下面的語句即 printf。

以上就是這個程序的執行過程。關于 for 語句的代碼規范化問題,有兩點要再跟大家強調一下:
1)if、else、for、while、do 都只能控制到其后的一條語句,如果要控制多條語句必須加大括號{}。但基于代碼規范化,if、else、for、while、do 后面的執行語句不論有多少行,就算只有一行也要加{}

2) 像 if、for、while 等關鍵字之后應留一個空格再跟左括號(,以突出關鍵字。

此外上面的程序還有一個知識點要跟大家說一下:從功能上講,for(i=1; i<=100;++i)完全可以寫成for(i=1; i<101; ++i),而且建議大家盡量使用這種寫法。也就是說,循環語句的循環條件盡量寫成半開半閉的,不管是 for 循環還是 while 循環。

for(i=1; i<101; ++i)實際上是 1≤i<101,是半開半閉的;而for(i=1; i<=100; ++i)實際上是 1≤i≤100,是全閉的。那么為什么建議使用半開半閉的呢?因為如果寫成 i<=100 的話,那么每次判斷的時候都要判斷兩次,即 i<100 和 i==100,而寫成 i<101 的話每次只需要判斷一次。

也許有人說:程序在執行 i<=100 的時候不是將它轉換成 i<100||i==100 嗎?這樣由“短路或”的知識可知,如果前面的為真那么后面的不就不會執行了嗎?這樣不也是判斷一次嗎?不是這樣的,系統是不會將 i<=100 轉換成 i<100||i==100 的,每次判斷的時候 i<100 和 i==100 都要判斷。

但是寫成半開半閉也有一個問題,就是會影響對代碼的理解。有時候寫成全閉的區間理解起來才順暢,而寫成半開半閉反而不易理解,比如<=右邊是變量或表達式的時候。這時候要以可讀性為第一要素,即哪種好理解就使用哪種。現在 CPU 速度那么快,也不在乎那點效率。所以前面說“盡量”,沒有要求一定要那樣寫。

下面再給大家寫一個程序,求 1 到 100 之間所有奇數的和。
# include <stdio.h>
int main(void)
{
    int i;
    int sum = 0 ;
    for (i=1; i<100; i+=2)  //i+=2;等價于i = i + 2;
    {
        sum = sum + i;
    }
    printf("sum = %d\n", sum);
    return 0;
}
輸出結果是:
sum = 2500

關于自增和自減

一直以來,++ 和 –– 語法浪費了太多人的時間。說句實在話,++ 和 –– 在C語言中根本就不重要,除了表達簡練外,真的沒有什么其他好處了。

簡單地說:++i 和 i++ 在單獨使用時,都表示 i=i+1;––i 和 i–– 在單獨使用時,都表示 i=i–1。

而 a=++i 就相當于 i=i+1,a=i;a=i++ 就相當于 a=i,i=i+1。
同理,a=––i 就相當于 i=i–1,a=i;a=i–– 就相當于 a=i,i=i–1。

如果實在搞不明白 ++ 和 –– 是怎么回事,那也不是什么天塌下來的事情。因為a=++i;完全可以寫成i++; a=i;。而a=i++;也完全可以寫成a=i; i++;。而且,這也是一種很好的程序風格。

作為一個優秀的程序員,在你的程序中就不應該體現出 ++i 和 i++ 的區別,要么都用 ++i,要么都用 i++,不要一會兒用 ++i 一會兒用 i++。

對于自增和自減還有一點需要強調的是:只有“變量”才能進行自增和自減!你認為 3++ 等于多少?C語言中沒有這種寫法,常量是不能進行自增和自減的。

for循環練習

1) 求 1! + 2! + 3! + ... + n!
# include <stdio.h>
int main(void)
{
    int n = 0;
    int i = 0;
    int m = 1;
    int sum=0;
    printf("請輸入n的值:");
    scanf("%d", &n);
    for (i=1; i<=n; ++i)
    {
        m = m * i;
        sum = sum +m;
    }
    printf ("sum = %d\n", sum);
    return 0;
}
這個程序雖然短,但邏輯性很強,算法很好,所以建議讀者記住。因為邏輯性強,所以只看是很難明白的,自己在紙上試一下,將自己當成計算機一步步地計算就明白了。

假如 n=4:
  1. 當 i=1 時,m=1,sum=1。
  2. 當 i=2 時,m=1×2,sum=1+1×2。
  3. 當 i=3 時,m=1×2×3,sum=1+1×2+1×2×3。
  4. 當 i=4 時,m=1×2×3×4,sum=1+1×2+1×2×3+1×2×3×4。

看出規律來了嗎?m 的值是一直往下乘,乘以 i 之前 m 的值是(i–1)的階乘,乘以 i 之后 m 的值就是 i 的階乘了。這樣 i 循環到多少,m*i 就立刻將這個數的階乘計算出來,然后加到 sum 中。

2) for 和 if 的嵌套使用。求 1 到 100 之間所有能被 3 整除的數之和。
# include <stdio.h>
int main(void)
{
    int i;
    int sum = 0;
    for (i=3; i<100; ++i)
    {
        if (0 == i%3)
        {
            sum = sum +i;
        }
    }
    printf("sum = %d\n", sum);
    return 0;
}
輸出結果是:
sum = 1683

大家想想如果不用 if,這個程序能不能寫出來?當然能,能被 3 整除的數肯定是 3 的倍數,只要 i 每次自加 3 就行了。我們將這個程序寫一下:
# include <stdio.h>
int main(void)
{
    int i;
    int sum = 0;
    for (i=3; i<100; i+=3)
    {
        sum = sum +i;
    }
    printf("sum = %d\n", sum);
    return 0;
}
因為 ++i 每次只加 1,而 i+=3 每次加 3,所以這種寫法與第一種寫法比較起來計算機少執行很多步,所以執行起來更快。由此可知,完成相同的功能,算法不一樣則效果就不一樣。對計算機而言當然是執行得越快越好。

3) 編寫程序,輸出 1~1000 之間所有的完全平方數。
# include <stdio.h>
# include <math.h>  //要用sqrt()
int main(void)
{
    int i;  //循環變量
    int x;  //存儲每個數的二次方根
    for (i=1; i<1000; ++i)
    {
        x = sqrt(i);  /*如果i不是完全平方數, 那么sqrt(i)肯定是小數, 而i是int型, 所以x是sqrt(i)取整后的值, 這樣x*x肯定不等于i*/
        if (x*x == i)
        {
            printf("%d\t", i);  // \t是跳到下一個Tab位置
        }
    }
    printf("\n");
    return 0;
}
輸出結果是:
1       4       9       16      25      36      49      64      81    100
121     144     169     196     225     256     289     324     361   400
441     484     529     576     625     676     729     784     841   900
961

其實這個程序還有更簡單的算法,不需要使用 sqrt()。下面將這個程序也寫下來:
# include <stdio.h>
int main(void)
{
    int i;  //循環變量
    for (i=1; i*i<1000; ++i)
    {
        printf("%d\t", i * i);  // \t是跳到下一個Tab位置
    }
    printf("\n");
    return 0;
}
輸出結果是:
1       4       9       16      25      36      49      64      81    100
121     144     169     196     225     256     289     324     361   400
441     484     529     576     625     676     729     784     841   900
961

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo