日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言再学习 -- 循环语句

發(fā)布時(shí)間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言再学习 -- 循环语句 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C語言有三種循環(huán)結(jié)構(gòu):while、for和do while。下面依次講解

一、while循環(huán)

1、while介紹

while(邏輯表達(dá)式) //布爾值為1 真
{
反復(fù)執(zhí)行的語句
}? ? ? ? ? ? ? ? ? ? ? ? ? ??

只要邏輯表達(dá)式結(jié)果為真就反復(fù)不停執(zhí)行大括號(hào)里的語句,直到邏輯表達(dá)式結(jié)果為假循環(huán)結(jié)束
只要把邏輯表達(dá)式寫成1則循環(huán)成為死循環(huán),while(1)
while循環(huán)里可以使用break和continue;

break 關(guān)鍵字很重要,表示終止本層循環(huán)?,F(xiàn)在這個(gè)例子只有一層循環(huán),當(dāng)代碼執(zhí)行到break 時(shí),循環(huán)便終止。
如果把 break 換成 continue 會(huì)是什么樣子呢? continue 表示終止本次(本輪) 循環(huán)。當(dāng)代碼執(zhí)行到 continue 時(shí),本輪循環(huán)終止,進(jìn)入下一輪循環(huán)。while( 1)也有寫成 while(true) 或者 while(1==1) 或者 while((bool) 1)等形式的,效果一樣。


還需注意:任何非零值都是真.比如,while (-1) == while (true)

2、while復(fù)合語句

復(fù)合語句是使用花括號(hào)組織起來的兩個(gè)或更過的語句,它也被稱為一個(gè)代碼塊。

例如:

/*程序1*/

index = 0; while (index++ < 10)sam = 10 *index +2; printf ("sam = %d\n", sam); /*程序2*/

index = 0; while (index++ < 10) {sam = 10 *index +2;printf ("sam = %d\n", sam); } 說明:在沒有花括號(hào)的情況下,while循環(huán)語句的范圍是從while到下一個(gè)分號(hào)。

3、技巧

A、假如你想要跳過輸入直到第一個(gè)不為空格或者數(shù)字的字符,你可以使用這樣的循環(huán):

while (scanf ("%d", &num) == 1) {....}

只要scanf()輸入一個(gè)整數(shù),它就返回1,循環(huán)就會(huì)繼續(xù)。

B、while ((ch = getchar ()) != '\n') {....}

只要輸入不為換行符'\n',它就返回1,循環(huán)就會(huì)繼續(xù)。

C、while循環(huán)內(nèi)只執(zhí)行一次的語句

int i = 0;

while (1)?

{

if (0 == i)

{只執(zhí)行一次該語句};

i == 1;

}

4、空語句

while ((ch = getchar ()) != EOF && ch != '\n') ; while語句之后的單獨(dú)一個(gè)分號(hào)稱為空語句,它就是應(yīng)用于目前這個(gè)場(chǎng)合,也就是語法要求這個(gè)地方出現(xiàn)一條語句但又無需執(zhí)行任何任務(wù)的時(shí)候,這個(gè)分號(hào)獨(dú)占一行,這是為了防止讀者錯(cuò)誤地以為接下來的語句也是循環(huán)的一部分。

二、do while循環(huán)

1、do while介紹

do{
} ?while(為真的邏輯);

do while為退出條件循環(huán),判斷條件在執(zhí)行循環(huán)之后進(jìn)行檢查,這樣就可以保證循環(huán)體中的語句至少被執(zhí)行一次。

2、do while復(fù)合語句

例如:

do scanf ("%d", &num); while (num != 20); /*注意while后面有分號(hào) ;*/

3、do while的常規(guī)用法

[cpp]?view plaincopy
  • //限制輸入,必須輸入0到10的數(shù),否則重新輸入。??
  • #include"stdio.h"??
  • int?main()??
  • {??
  • ????int?num;??
  • ????do??
  • ????{??
  • ????????printf("請(qǐng)輸入0到10的整數(shù):");?//先進(jìn)行輸入提示??
  • ????????scanf("%d",&num);?//從鍵盤讀取一個(gè)數(shù)??
  • ????????getchar();??
  • ????}while?(num?>?10?||?num?<?0);??//如果這個(gè)數(shù)不再0~10內(nèi),也就是小于0或者大于10,重新輸入??
  • ????printf("輸入正確,輸入的數(shù)為:%d\n",?num);?//輸入正確則跳出循環(huán)并給出提示,\n表示換行??
  • }??
  • 4、do {}while(0)的用法

    參看:do while的使用 linux內(nèi)核中 do{}while(0)用法分析

    linux內(nèi)核和其他一些開源的代碼中,經(jīng)常會(huì)遇到這樣的代碼:

    do{... }while(0)

    這樣的代碼一看就不是一個(gè)循環(huán),do..while表面上在這里一點(diǎn)意義都沒有,那么為什么要這么用呢?

    實(shí)際上,do{...}while(0)的作用遠(yuǎn)大于美化你的代碼,while(0)的好處在于在編譯的時(shí)候,編譯器基本都會(huì)為你做好優(yōu)化,把這部分內(nèi)容去掉,最終編譯的結(jié)果不會(huì)因?yàn)檫@個(gè)do while而導(dǎo)致運(yùn)行效率上的差異。。查了些資料,總結(jié)起來這樣寫主要有以下幾點(diǎn)好處:

    1、輔助定義復(fù)雜的宏,避免引用的時(shí)候出錯(cuò):

    舉例來說,假設(shè)你需要定義這樣一個(gè)宏:

    #define DO_SOMETHING()\foo1();\foo2();

    這個(gè)宏的本意是,當(dāng)調(diào)用DO_SOMETHING()時(shí),函數(shù)foo1()和foo2()都會(huì)被調(diào)用。但是如果你在調(diào)用的時(shí)候這寫:

    if(a>0)DO_SOMETHING();

    因?yàn)楹暝陬A(yù)處理的時(shí)候會(huì)直接被展開,你實(shí)際上寫的代碼是這個(gè)樣子的:

    if(a>0)foo1(); foo2();

    這就出現(xiàn)了問題,因?yàn)闊o論a是否大于0,foo2()都會(huì)被執(zhí)行,導(dǎo)致程序出錯(cuò)

    那么僅僅使用{}將foo1()和foo2()包起來行么

    我們?cè)趯懘a的時(shí)候都習(xí)慣在語句右面加上分號(hào),如果在宏中使用{},代碼里就相當(dāng)于這樣寫了:“{...};”,展開后就是這個(gè)樣子:

    if(a>0) {foo1();foo2(); };

    注意if{};后面的";",如果if后面還有else等語句則編譯不會(huì)通過。所以,很多人才采用了do{...}while(0);

    #define DO_SOMETHING() \do{ \foo1();\foo2();\}while(0)\ ...if(a>0)DO_SOMETHING();...

    這樣,宏被展開后,才會(huì)保留初始的語義。GCC提供了Statement-Expressions用以替代do{...}while(0); 所以你也可以這樣定義宏:

    #define DO_SOMETHING() ({\foo1(); \foo2(); \ })

    http://www.spongeliu.com/?
    2、避免使用goto對(duì)程序流進(jìn)行統(tǒng)一的控制:

    有些函數(shù)中,在函數(shù)return之前我們經(jīng)常會(huì)進(jìn)行一些收尾的工作,比如free掉一塊函數(shù)開始malloc的內(nèi)存,goto一直都是一個(gè)比較簡(jiǎn)便的方法:

    int foo() {somestruct* ptr = malloc(...);dosomething...;if(error){goto END;}dosomething...;if(error){goto END;}dosomething...;END:free(ptr);return 0;}

    由于goto不符合軟件工程的結(jié)構(gòu)化,而且有可能使得代碼難懂,所以很多人都不倡導(dǎo)使用,那這個(gè)時(shí)候就可以用do{}while(0)來進(jìn)行統(tǒng)一的管理:

    int foo() {somestruct* ptr = malloc(...);do{dosomething...;if(error){break;}dosomething...;if(error){break;}dosomething...;}while(0);free(ptr);return 0;}

    這里將函數(shù)主體使用do()while(0)包含起來,使用break來代替goto,后續(xù)的處理工作在while之后,就能夠達(dá)到同樣的效果。

    3、避免空宏引起的warning

    內(nèi)核中由于不同架構(gòu)的限制,很多時(shí)候會(huì)用到空宏,在編譯的時(shí)候,空宏會(huì)給出warning,為了避免這樣的warning,就可以使用do{}while(0)來定義空宏:

    #define EMPTYMICRO do{}while(0)

    4、定義一個(gè)單獨(dú)的函數(shù)塊來實(shí)現(xiàn)復(fù)雜的操作:

    當(dāng)你的功能很復(fù)雜,變量很多你又不愿意增加一個(gè)函數(shù)的時(shí)候,使用do{}while(0);,將你的代碼寫在里面,里面可以定義變量而不用考慮變量名會(huì)同函數(shù)之前或者之后的重復(fù)。


    5、do {}while(0)的簡(jiǎn)化

    #define st(x) do { x } while (__LINE__ == -1)

    1, __LINE__ 是個(gè)宏,它代表當(dāng)前代碼在源文件的行號(hào),它是大于0的,所以__LINE__ == -1 等同于0,化簡(jiǎn)為:
    #define st(x) do { x } while (0)
    2,do {} while (0)通常用于宏中, 為的是避免如下情況:
    #define st(x) x
    那么我們?cè)谡{(diào)用 if (0) st(a = b; b = c;) 時(shí)會(huì)被解釋成
    if(0)
    a = b;
    b = c;
    可見 if 只對(duì)a = b;起作用。

    三、for循環(huán) 1、for介紹 for(num=1; num <10; num++); 在關(guān)鍵字for之后的圓括號(hào)中包含了由兩個(gè)分號(hào)分開的三個(gè)表達(dá)式。 第一個(gè)表達(dá)式進(jìn)行初始化,它在for循環(huán)開始的時(shí)候執(zhí)行一次。 第二個(gè)表達(dá)式是判斷條件,在每次執(zhí)行循環(huán)之前都要對(duì)它進(jìn)行求值。當(dāng)表達(dá)式為假時(shí),循環(huán)結(jié)束。 第三個(gè)表達(dá)式進(jìn)行改變或者稱為更新,它在每次循環(huán)結(jié)束時(shí)進(jìn)行計(jì)算。
    2、for復(fù)合語句 例如: for (n = 0; n < 10; n+)printf ("%d %d\n", n, 2 * n + 1);
    3、for循環(huán)的靈活性 A、可以讓一個(gè)或多個(gè)表達(dá)式為空(但是不要遺漏分號(hào))。只須確保在循環(huán)中包含一些能是循環(huán)最終結(jié)束的語句。
    B、順便說一句,中間的那個(gè)控制表達(dá)式為空會(huì)被認(rèn)為是真,所以下面的循環(huán)會(huì)永遠(yuǎn)執(zhí)行: for (; ;) printf ("hello world\n");
    C、第一個(gè)表達(dá)式不必初始化一個(gè)變量,它也可是某種類型的printf()語句,要記住第一個(gè)表達(dá)式只在執(zhí)行循環(huán)的其他部分之前被求值或執(zhí)行一次。
    D、for循環(huán)可使用逗號(hào)運(yùn)算符把兩個(gè)表達(dá)式鏈接為一個(gè)表達(dá)式,并保證最左邊的表達(dá)式最先計(jì)算。 例如: for (n = 2, m = 0; m < 1000; n *=2)m +=n;
    E、在for循環(huán)中使用數(shù)組,使用#define來指定數(shù)組大小 例如: #define SIZE 10 for (int n = 0; n < SIZE; n++)printf ("hello world\n");
    4、嵌套循環(huán) A、嵌套循環(huán)是指在另一個(gè)循環(huán)之內(nèi)的循環(huán)。通常使用嵌套循環(huán)來按行按列顯示數(shù)據(jù)。也就是說一個(gè)循環(huán)處理一行中的所有列,而另一個(gè)循環(huán)處理所有的行。
    B、外層for循環(huán)為外部循環(huán),按行顯示數(shù)據(jù);內(nèi)層for循環(huán)為內(nèi)部循環(huán)。按列顯示數(shù)據(jù)。 在多重循環(huán)中,如果有可能,應(yīng)當(dāng)將最長(zhǎng)的循環(huán)放在最內(nèi)層,最短的循環(huán)放在最外層,以減少 CPU 跨切循環(huán)層的次數(shù)。例如:
    長(zhǎng)循環(huán)在最內(nèi)層,效率高 for (col=0; col<5; col++ ) {for (row=0; row<100; row++){sum = sum + a[row][col];} }長(zhǎng)循環(huán)在最外層,效率低 for (row=0; row<100; row++) {for ( col=0; col<5; col++ ){sum = sum + a[row][col];} }
    C、建議 for 語句的循環(huán)控制變量的取值采用“半開半閉區(qū)間”寫法。半開半閉區(qū)間寫法和閉區(qū)間寫法雖然功能是相同,但相比之下,半開半閉區(qū)間寫法寫法更加直觀。 半開半閉區(qū)間寫法:for (n = 0; n < 10; n++) {....} 閉區(qū)間寫法:for (n = 0; n <= 9; n++) {....}

    D、不能在 for 循環(huán)體內(nèi)修改循環(huán)變量,防止循環(huán)失控。 for (n = 0; n < 10; n++) {…n = 8;//不可,很可能違背了你的原意… }
    E、循環(huán)要盡可能的短,要使代碼清晰,一目了然。 如果你寫的一個(gè)循環(huán)的代碼超過一顯示屏,那會(huì)讓讀代碼的人發(fā)狂的。解決的辦法由兩個(gè):第一,重新設(shè)計(jì)這個(gè)循環(huán),確認(rèn)是否這些操作都必須放在這個(gè)循環(huán)里;第二,將這些代碼改寫成一個(gè)子函數(shù), 循環(huán)中只調(diào)用這個(gè)子函數(shù)即可。 一般來說循環(huán)內(nèi)的代碼不要超過 20行。
    F、把循環(huán)嵌套控制在 3 層以內(nèi)。 國(guó)外有研究數(shù)據(jù)表明,當(dāng)循環(huán)嵌套超過 3 層,程序員對(duì)循環(huán)的理解能力會(huì)極大的降低。如果你的循環(huán)嵌套超過 3 層,建議你重新設(shè)計(jì)循環(huán)或是將循環(huán)內(nèi)的代碼改寫成一個(gè)字函數(shù)。
    G、擴(kuò)展 1、編程實(shí)現(xiàn)打印一個(gè)空心的菱形和實(shí)心的菱形:
    ? ? ? ? ?*
    ? ? ? *****
    ? ?*********
    *************
    ? ?*********
    ? ? ? *****
    ? ? ? ? ?*
    #include <stdio.h> int main() {int i=0,j=0,k=0;for(i=0;i<=3;i++){for(j=0;j<=5-2*i;j++){printf(" ");}for(k=0;k<=4*i;k++){printf("*");}printf("\n");}for(i=0;i<=2;i++){for(j=0;j<=2*i+1;j++){printf(" ");}for(k=0;k<=8-4*i;k++){printf("*");}printf("\n");}return 0; }
    2、請(qǐng)簡(jiǎn)述以下兩個(gè) for 循環(huán)的優(yōu)缺點(diǎn)
    // 第一個(gè) for (i=0; i<N; i++) { if (condition) DoSomething(); else DoOtherthing(); } 優(yōu)缺點(diǎn):效率低但程序簡(jiǎn)潔
    // 第二個(gè) if (condition) { for (i=0; i<N; i++) DoSomething(); } else { for (i=0; i<N; i++) DoOtherthing(); }優(yōu)缺點(diǎn):效率高但程序不簡(jiǎn)潔
    說明:第一個(gè)程序比第二個(gè)程序多執(zhí)行了 N-1 次邏輯判斷。并且由于前者老要進(jìn)行邏輯判斷,打斷了循環(huán)“流水線”作業(yè),使得編譯器不能對(duì)循環(huán)進(jìn)行優(yōu)化處理,降低了效率。如果 N 非常大,最好采用第二個(gè)程序的寫法,可以提高效率。如果 N 非常小,兩者效率差別并不明顯,采用第一個(gè)程序的寫法比較好,因?yàn)槌绦蚋雍?jiǎn)潔。
    注意: 1、上面有提到,在多重循環(huán)中,如果有可能,應(yīng)當(dāng)將最長(zhǎng)的循環(huán)放在最內(nèi)層,最短的循環(huán)放在最外層,以減少 CPU 跨切循環(huán)層的次數(shù)。 ?
    2、建議 for 語句的循環(huán)控制變量的取值采用“半開半閉區(qū)間”寫法。
    int a[10];
    半開半閉區(qū)間寫法:for (n = 0; n < 10; n++)
    閉區(qū)間寫法:for (n = 0; n <= 9; n++)

    半開半閉區(qū)間寫法和閉區(qū)間寫法雖然功能是相同,但考慮到邊界計(jì)算,例如我們要在C語言中定義一個(gè)擁有 10 個(gè)元素的數(shù)組,那么 0 就是數(shù)組下標(biāo)的第一個(gè) “入界點(diǎn)”(指處于數(shù)組下標(biāo)范圍以內(nèi)的點(diǎn),包括邊界點(diǎn)),而 10 就是數(shù)組下標(biāo)中的第一個(gè)“出界點(diǎn)”(指不在數(shù)組下標(biāo)范圍以內(nèi)的點(diǎn),不含邊界點(diǎn))。因此寫成半開半閉區(qū)間的寫法更加直觀。

    3、不能在 for 循環(huán)體內(nèi)修改循環(huán)變量,防止循環(huán)失控。for (n = 0; n < 10; n++) { … n = 8;//不可,很可能違背了你的原意 … }
    4、循環(huán)要盡可能的短,要使代碼清晰,一目了然。
    如果你寫的一個(gè)循環(huán)的代碼超過一顯示屏,那會(huì)讓讀代碼的人發(fā)狂的。解決的辦法由兩個(gè):第一,重新設(shè)計(jì)這個(gè)循環(huán),確認(rèn)是否這些操作都必須放在這個(gè)循環(huán)里;第二,將這些代碼改寫成一個(gè)子函數(shù), 循環(huán)中只調(diào)用這個(gè)子函數(shù)即可。 一般來說循環(huán)內(nèi)的代碼不要超過 20行。

    5、把循環(huán)嵌套控制在 3 層以內(nèi)。
    國(guó)外有研究數(shù)據(jù)表明,當(dāng)循環(huán)嵌套超過 3 層,程序員對(duì)循環(huán)的理解能力會(huì)極大的降低。如果你的循環(huán)嵌套超過 3 層,建議你重新設(shè)計(jì)循環(huán)或是將循環(huán)內(nèi)的代碼改寫成一個(gè)字函數(shù)。

    與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

    總結(jié)

    以上是生活随笔為你收集整理的C语言再学习 -- 循环语句的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。