詳解C語言中for循環(huán)與while循環(huán)的用法
一、單層for循環(huán)
引例:C語言實現(xiàn)求1到10的和(用for循環(huán)實現(xiàn))
#include <stdio.h>
int main()
{
int i, sum = 0;
for (i = 1; i <= 10; i++)
sum = sum + i;
printf("sum = %d\n", sum);
return 0;
}
單層for循環(huán)執(zhí)行的順序:

第一次循環(huán)先執(zhí)行語句①,執(zhí)行完語句①執(zhí)行語句②,如果語句②成立則執(zhí)行語句④,執(zhí)行完語句④執(zhí)行語句③,執(zhí)行完語句③標(biāo)志著第一次循環(huán)結(jié)束;第二次循環(huán)先執(zhí)行語句②,如果語句②成立則執(zhí)行語句④,執(zhí)行完語句④執(zhí)行語句③,執(zhí)行完語句③標(biāo)志著第二次循環(huán)執(zhí)行結(jié)束,隨后循環(huán)中語句的執(zhí)行順序與第二次循環(huán)一致。如果在循環(huán)過程中語句②不成立,則整個循環(huán)就結(jié)束了。直到整個循環(huán)結(jié)束后才會執(zhí)行語句⑤,因為,for語句與if語句所能控制的范圍相同,只能控制其接下來的第一條語句,言下之意是,語句⑤并不在for循環(huán)的內(nèi)部。需要注意的是,語句①僅在第一次循環(huán)中執(zhí)行,在其它循環(huán)過程中不執(zhí)行。換句話說,語句①只會在整個循環(huán)過程中執(zhí)行一次。語句①的作用其實是給變量進(jìn)行初始化,所以它僅參與了第一次循環(huán)。還有值得注意的是,初學(xué)時容易在for (①; ②; ③)后加分號,這個情況我已經(jīng)在《C語言if語句中常見的問題》這篇文章中的空語句問題中詳細(xì)敘述了其中的道理,并且在for語句中依然適用,有興趣的話可以一看。
練習(xí)
C語言實現(xiàn)求1到10中奇數(shù)的和
#include <stdio.h>
int main()
{
int i, sum = 0;
for (i = 1; i <= 10; i = i +2)
sum = sum + i;
printf("sum = %d\n", sum);
return 0;
}
C語言實現(xiàn)求1+1/2+1/3+…+1/99+1/100
初學(xué)時的錯誤代碼:
#include <stdio.h>
int main()
{
int i;
float sum = 0; // 考慮到和是小數(shù),所以定義sum為float類型
for (i = 1; i <= 100; i++)
sum = sum + 1/i;
printf("sum = %f\n", sum); // float類型的變量用%f輸出
return 0;
}
錯誤原因:沒有考慮到1/i的數(shù)據(jù)類型。在C語言中,整型除以整型得到的結(jié)果只有整數(shù)位。例如,16/3 = 5。上述程序中i是整型變量,所以1/i也是整型,故從i大于等于2時,1/i的值永遠(yuǎn)為0。
因此需要將1/i的值想辦法變?yōu)楦↑c數(shù)才可以實現(xiàn)想要的功能。C語言規(guī)定,只要被除數(shù)與除數(shù)其中的一個為浮點數(shù),則商為浮點數(shù)。故解決的辦法有兩種,第一種是將1/i寫為1.0/i,第二種是將整型變量i強(qiáng)制類型轉(zhuǎn)化為float類型,正確的代碼如下:
#include <stdio.h>
int main()
{
int i;
float sum = 0;
for (i = 1; i <= 100; i++)
sum = sum + 1.0/i;// 或 sum = sum + 1/(float)(i);
printf("sum = %f\n", sum);
return 0;
}
思考1:如果將上述代碼中的sum = sum + 1/(float)(i);改為sum = sum + (float)(1/i);后能否正確輸出sum的值?
思考2:能否將i直接定義為浮點型變量?
答案是不能,因為浮點型數(shù)據(jù)是以IEEE754標(biāo)準(zhǔn)來存儲的,但I(xiàn)EEE754標(biāo)準(zhǔn)無法確保精確存儲每一個浮點數(shù),例如,6.234在存儲過程中很可能存的不是6.234而是6.23399999,這是IEEE754標(biāo)準(zhǔn)的缺陷。所以即便在該程序中將i定義為浮點型變量后輸出的結(jié)果是正確的,也不能確保在其他程序中依然正確,因為i不一定是準(zhǔn)確的數(shù)字。需要注意的是,我們一般不會把循環(huán)中不斷發(fā)生更新的變量定義為浮點型變量,因為浮點型數(shù)據(jù)存儲過程屬于非精確存儲。
二、for循環(huán)與if選擇的嵌套
引例:C語言實現(xiàn)求1到100之間所有可以被3整除的數(shù)字之和
#include <stdio.h>
int main()
{
int i, sum = 0;
for (i = 1; i <= 100; i++)
{
if (i % 3 == 0)
sum = sum + i;
}
printf("sum = %d\n", sum);
return 0;
}
思考:下面的程序輸出結(jié)果是什么?
#include <stdio.h>
int main()
{
int i, sum = 0;
for (i = 1; i <= 12; i++)
{
if (i % 3 == 0)
sum = sum + i;
printf("sum = %d\n", sum);
}
return 0;
}
練習(xí)(以下題目均要求使用for循環(huán)和if選擇的嵌套來完成)
編寫C語言程序求1到100之間的奇數(shù)之和
#include <stdio.h>
int main()
{
int i;
int sum = 0;
for (i = 1; i <= 100; i++)
{
if (i % 2 == 1)
sum += i;
}
printf("奇數(shù)之和為%d\n", sum);
return 0;
}
編寫C語言程序求1到100之間的奇數(shù)的個數(shù)
#include <stdio.h>
int main()
{
int i;
int count = 0;
for (i = 1; i <= 100; i++)
{
if (i % 2 == 1)
count++;
}
printf("個數(shù)為%d\n", count);
return 0;
}
編寫C語言程序求1到100之間的奇數(shù)的平均值
#include <stdio.h>
int main()
{
int i;
int count = 0;
int sum = 0;
float average; // 考慮到平均值可能帶有小數(shù)位,所以將平均值定義為float類型
for (i = 1; i <= 100; i++)
{
if (i % 2 == 1)
{
count++;
sum += i;
}
}
average = 1.0 * sum / count; //也可以運用強(qiáng)制類型轉(zhuǎn)換寫成average = (float)(sum)/count;
printf("平均數(shù)為%f\n", average);
return 0;
}
編寫C語言程序求1到100之間的奇數(shù)之和與1到100之間的偶數(shù)之和
#include <stdio.h>
int main()
{
int i;
int sum1 = 0; // 奇數(shù)和
int sum2 = 0; // 偶數(shù)和
for (i = 1; i <= 100; i++)
{
if (i % 2 == 1)
sum1 += i;
else
sum2 += i;
}
printf("奇數(shù)之和為%d,偶數(shù)之和為%d\n", sum1, sum2);
return 0;
}
三、多層for循環(huán)的嵌套
多層for循環(huán)執(zhí)行的順序:

第一次循環(huán)先執(zhí)行語句①,執(zhí)行完語句①執(zhí)行語句②,如果語句②成立則跳入內(nèi)部循環(huán)執(zhí)行語句④,執(zhí)行完語句④執(zhí)行語句⑤,如果語句⑤成立則執(zhí)行語句⑦,執(zhí)行完語句⑦執(zhí)行語句⑥,執(zhí)行完語句⑥執(zhí)行語句⑤,如果如果語句⑤不成立,則標(biāo)志著內(nèi)部循環(huán)執(zhí)行完畢,接下來跳出內(nèi)部循環(huán)執(zhí)行語句③,執(zhí)行完語句③標(biāo)志著第一次整個循環(huán)結(jié)束;第二次循環(huán)先執(zhí)行語句②,如果語句②成立,則再次跳入內(nèi)部循環(huán)執(zhí)行語句④,以此類推;如果語句②不成立,整個循環(huán)就結(jié)束了。由于⑧不屬于任何一個for循環(huán)內(nèi)部的語句,所以要在整個循環(huán)執(zhí)行完畢后才會執(zhí)行語句⑧。
換個方式:

因為for語句與if語句所能控制的范圍相同,只能控制其接下來的第一條語句,所以語句⑦屬于內(nèi)部for循環(huán),而語句⑦與內(nèi)部的for循環(huán)語句構(gòu)成的語句整體是一個語句,也就是上圖中的綠色方框部分,這個整體語句又是外層for循環(huán)內(nèi)部的第一個語句,所以,外層for循環(huán)所控制的語句就是綠色方框部分,而外層for循環(huán)完整的結(jié)構(gòu)就是上圖中的橙色方框部分。所以按照for循環(huán)的大體執(zhí)行順序,首先會執(zhí)行語句①,執(zhí)行完語句①執(zhí)行語句②,如果語句②成立則會執(zhí)行綠色方框部分,綠色方框部分是單層for循環(huán),所以執(zhí)行過程按照單層for循環(huán)的執(zhí)行循序執(zhí)行,當(dāng)內(nèi)部的綠色方框部分執(zhí)行完畢后,則會執(zhí)行語句③,語句③執(zhí)行完標(biāo)志著整體一次循環(huán)結(jié)束,下一次循環(huán)又從判斷語句②是否成立開始,如果成立,則執(zhí)行綠色方框部分;如果不成立,則整個循環(huán)結(jié)束。整個循環(huán)結(jié)束后才會執(zhí)行語句⑧,因為語句⑧并不屬于這兩層for循環(huán)中的任何一層。
思考1:下面的for循環(huán)的執(zhí)行順序是什么樣的?

思考2:下面的for循環(huán)的執(zhí)行順序是什么樣的?

思考3:下面的for循環(huán)的執(zhí)行順序是什么樣的?

思考4:下面的程序輸出結(jié)果是什么?
#include <stdio.h>
int main()
{
int i, j;
for (i = 0; i <3; i++)
for (j = 2; j < 5; j++)
printf("AAAA\n");
printf("BBBB\n");
return 0;
}
思考5:下面的程序輸出結(jié)果是什么?
#include <stdio.h>
int main()
{
int i, j;
for (i = 0; i <3; i++)
printf("AAAA\n");
for (j = 2; j < 5; j++)
printf("BBBB\n");
printf("CCCC\n");
return 0;
}
思考6:下面的程序輸出結(jié)果是什么?
#include <stdio.h>
int main()
{
int i, j;
for (i = 0; i <3; i++)
{
printf("AAAA\n");
for (j = 2; j < 5; j++)
printf("BBBB\n");
printf("CCCC\n");
}
return 0;
}
四、while循環(huán)
引例:C語言實現(xiàn)求1到10的和(用while循環(huán)實現(xiàn))
#include <stdio.h>
int main()
{
int i, sum = 0;
i = 1;
while (i <= 10)
{
sum += i;
i++;
}
printf("sum = %d\n", sum);
return 0;
}
對比:C語言實現(xiàn)求1到10的和(用for循環(huán)實現(xiàn))
#include <stdio.h>
int main()
{
int i, sum = 0;
for (i = 1; i <= 10; i++)
sum = sum + i;
printf("sum = %d\n", sum);
return 0;
}
while循環(huán)與for循環(huán)的相互轉(zhuǎn)換:
從上述兩個程序可知,while循環(huán)和for循環(huán)可以進(jìn)行互相轉(zhuǎn)換,言下之意是,所有能用for循環(huán)實現(xiàn)的功能,就可以用while循環(huán)實現(xiàn),反之同理。但是,while循環(huán)和for循環(huán)在寫法上有一定的差別。

五、總結(jié)
循環(huán)結(jié)構(gòu)在學(xué)習(xí)編程中起到至關(guān)重要的作用,幾乎每個有用的程序中都有循環(huán)結(jié)構(gòu)的身影,循環(huán)結(jié)構(gòu)是我們以后編程中的重中之重,掌握其執(zhí)行順序是理解程序的不二法門.
以上就是詳解C語言中for循環(huán)與while循環(huán)的用法的詳細(xì)內(nèi)容,更多關(guān)于C語言 for while循環(huán)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
淺談Windows系統(tǒng)下C語言編程中Glib庫的使用
這篇文章主要介紹了Windows系統(tǒng)下C語言編程中Glib庫的使用,Glib庫在多線程編程中經(jīng)??梢杂玫?需要的朋友可以參考下2016-02-02
使用MinGW使Windows通過gcc實現(xiàn)C或C++程序本地編譯執(zhí)行的方法
這篇文章主要介紹了使用MinGW使Windows通過gcc實現(xiàn)C或C++程序本地編譯執(zhí)行的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
C++中實現(xiàn)保存數(shù)據(jù)到CSV文件
這篇文章主要介紹了C++中實現(xiàn)保存數(shù)據(jù)到CSV文件方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
C語言數(shù)據(jù)結(jié)構(gòu)中約瑟夫環(huán)問題探究
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)中約瑟夫環(huán)問題,總的來說這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過程。希望通過這道題能給你帶來一種解題優(yōu)化的思路2023-01-01
opengl實現(xiàn)直線掃描算法和區(qū)域填充算法
這篇文章主要為大家詳細(xì)介紹了opengl實現(xiàn)直線掃描算法和區(qū)域填充算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-04-04
C語言中獲取進(jìn)程識別碼的相關(guān)函數(shù)
這篇文章主要介紹了C語言中獲取進(jìn)程識別碼的相關(guān)函數(shù),分別為getpid()函數(shù)和getppid()函數(shù)的使用,需要的朋友可以參考下2015-08-08

