寫這篇文章,我深有感觸,在寫代碼的程序中,我們經常會出現最后的結果達不到我們預期的效果的情況,我們一定一定要耐下心來,一步一步地去思考,是哪里出了問題,怎么能解決問題,這樣的一個程序是十分重要的,是能讓我們越來越接近真相的程序,學習編程的路肯定不是一帆風順的,但我們要有能夠克服任何苦難的決心,這是最重要的,
在這篇文章中,我們將會對回圈陳述句有一個更加深入的了解
并且我們還能了解到getchar與putchar的相關知識
讓我們開始吧!
目錄
一.while回圈
1.while回圈語法
2.break和continue 在while回圈中
(1).break
(2).continue
3.兩個代碼的練習
第一個代碼
第二個代碼
二.for回圈
1.for回圈語法
2. break和continue在for回圈中
(1).break
(2).continue
continue在for回圈和在while回圈中有所不同
三.do...while()回圈
1.do...while()回圈的語法
2.break和continue在do...while回圈中
(1).break
(2).continue
一.while回圈
1.while回圈語法
while陳述句又稱當型回圈陳述句,其語法為:
while (運算式)
回圈陳述句;
其具體執行程序如下:
(1)計算運算式的值,若為真,則轉步驟(2),否則退出回圈,執行while的下一條陳述句
(2)執行回圈陳述句(即回圈體),并回傳步驟(1)
這里試著使用while回圈列印1~10的數
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
printf("%d ", i);
i++;
}
return 0;
}
2.break和continue 在while回圈中
(1).break
#i#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(5 == i)
break;
printf("%d ", i);
i ++;
}
return 0;
}

運行的結果如圖
總結:
break在while回圈中的作用:
其實在回圈中只要遇到break,就停止后期的所有的回圈,直接終止回圈,
所以:while中的break是用于永久終止回圈的,
(2).continue
如果將剛剛的break換成continue
那么運行的結果又會發生什么變化呢?
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(5 == i)
continue;
printf("%d ", i);
i ++;
}
return 0;
}

4后面的游標在閃動,說明此時程式進入了死回圈
原因是,與break陳述句不同,
continue是用于終止本次回圈的,也就是本次回圈中continue后邊的代碼不會再執行,而是直接 跳轉到while陳述句的判斷部分,進行下一次回圈的入口判斷

如圖中紅色框框內的代碼在continue的作用下會被跳過,i++不會被執行,所以i就一直為5,進去死回圈
3.兩個代碼的練習
讓我們再看兩個跟while回圈有關的代碼,再看之前,我們需要先了解一下getchar和putchar
getchar

在msdn中,我們查找到getchar的解釋
int ch = getchar() ; //獲取字符
printf("%c\n",ch) ; //列印獲取的字符
這里我們會有這樣的疑問:我們的 ch 獲取的是一個字符,為什么放到int整型里去?
原因有兩個:
- 雖然getchar回傳的是個字符,但是字符的存盤值是它的 ASCII碼值,如 ’a‘對應的ASCII碼值就是97
- getchar讀取失敗的時候回傳EOF,而EOF是-1,是個整數


getchar - 獲取(輸入一個字符)
putchar - 輸出一個字符
putchar
在msdn中的定義

int ch = getchar() ; //獲取字符
putchar (ch);//輸出一個字符
getchar 和 putchar 可以用scanf 和printf代替,且scanf和printf的功能更全,getchar和putchar只能操作字符
第一個代碼

這個代碼會將你輸入的字符列印出來,如果想停止:ctrl+z 可以讓getchar回傳一個EOF
我們寫這樣的代碼有什么意義呢?實際上是有意義的,我們這里再舉一個例子
#include <stdio.h>
int main()
{
char input[20] = { 0 };//創建一個陣列
printf("請輸入密碼:>");
scanf("%s", input);
printf("請確認密碼(Y/N):>");
int ch = getchar();
if (ch == 'Y')
{
printf("確認成功\n");
}
else
{
printf("確認失敗\n");
}
return 0;
}
看這個代碼時,可能會有疑問,為什么scanf函式里的input沒有取地址,
是因為陣列名本身就是一個地址,所以不需要再取地址
這樣一個程式,我們的本意是輸入密碼后需要用戶確認密碼是否正確,可當程式走起來后我們發現,在我們還沒有輸入時,已經列印出了“確認失敗”

下面我們就來分析一下程式出問題的原因 ,全部在這張圖上了

解決方法 :把輸入緩沖區里scanf沒有拿走的\n拿走 ,改進如下
#include <stdio.h>
int main()
{
char input[20] = { 0 };//創建一個陣列
printf("請輸入密碼:>");
scanf("%s", input);
getchar(); //拿走\n
printf("請確認密碼(Y/N):>");
int ch = getchar();
if (ch == 'Y')
{
printf("確認成功\n");
}
else
{
printf("確認失敗\n");
}
return 0;
}

我們成功了!!!
下面是還可能出現的錯誤的情況:如果密碼當中有“ ”(空格)

當用戶輸入的密碼中含有空格時,又出現了剛剛的錯誤的情況,我們再來分析

我們可以發現這時需要拿走更多的字符,所以我們使用while回圈
while ((tmp = getchar()) != '\n') //只要不是/n,就說明沒拿完,就進入回圈
{
; //空陳述句(什么也不干)
}
#include <stdio.h>
int main()
{
char input[20] = { 0 };//創建一個陣列
printf("請輸入密碼:>");
scanf("%s", input);
int tmp = 0;
while ((tmp = getchar()) != '\n')//只要不是/n,就說明沒拿完,就進入回圈
{
;//空陳述句(什么也不干)
}
printf("請確認密碼(Y/N):>");
int ch = getchar();
if (ch == 'Y')
{
printf("確認成功\n");
}
else
{
printf("確認失敗\n");
}
return 0;

我們驚喜地發現,我們又通過改變代碼使這個程式執行成功了!
第二個代碼
#include <stdio.h>
int main()
{
int ch=0;
while ((ch = getchar()) != EOF)
{
if (ch < ‘0’ || ch > ‘9’)
continue;
putchar(ch);
}
return 0;
}
這個代碼就比較簡單了 就是只列印0~9的數字
但有一點需要說明
這個括號不能少((ch=getchar())!=EOF) 如果少了 ,就不是把獲取的字符放進ch和EOF比較了,而是字符直接與EOF比較,不相等就為假,就為0,這時就把0賦給了ch
二.for回圈
1.for回圈語法
for回圈的語法:
for (運算式1;運算式2;運算式3)
回圈陳述句;
運算式1
運算式1為初始化部分,用于初始化回圈變數的,
運算式2
運算式2為條件判斷部分,用于判斷回圈時候終止,
運算式3
運算式3為調整部分,用于回圈條件的調整,
這里我們同樣也使用for回圈來列印一下1~10的數來熟悉一下for回圈
#include <stdio.h>
int main()
{
int i = 0;
for(i=1; i<=10; i++)
{
printf("%d ", i);
}
return 0;
}
并且,我們用這個代碼為例,來幫助我們理解for回圈的流程圖

現在我們對比一下for回圈和while回圈
int i = 0;
//實作相同的功能,使用while
i=1;//初始化部分
while(i<=10)//判斷部分
{
printf("hehe\n");
i = i++;//調整部分
}
//實作相同的功能,使用while
for(i=1; i<=10; i++)
{
printf("hehe\n");
}
可以發現在while回圈中依然存在回圈的三個必須條件,但是由于風格的問題使得三個部分很可能偏離 較遠,這樣查找修改就不夠集中和方便,所以,for回圈的風格更勝一籌, for回圈使用的頻率也最高,
2. break和continue在for回圈中
我們發現在for回圈中也可以出現break和continue,他們的意義和在while回圈中是一樣的,
但是還是有些差異:
(1).break

可見,break在for回圈中與在while回圈中類似,都是直接終止回圈
(2).continue
#include <stdio.h>
int main()
{
int i = 0;
for(i=1; i<=10; i++)
{
if(i == 5)
continue;
printf("%d ",i);
}
return 0;
}
continue在for回圈和在while回圈中有所不同

這里執行起來并不是死回圈了,而是跳過5列印了1 2 3 4 6 7 8 9 10

當i==5時,執行continue陳述句,跳過printf陳述句 ,執行 i++,之后 i為6,i==5為假,continue陳述句不再執行
for陳述句的回圈控制變數 (作為補充)
一些建議:
- 不可在for 回圈體內修改回圈變數,防止 for 回圈失去控制,
- 建議for陳述句的回圈控制變數的取值采用“前閉后開區間”寫法,
int i = 0;
//前閉后開的寫法
for(i=0; i<10; i++)
{}
//兩邊都是閉區間
for(i=0; i<=9; i++)
{}
第一種也就是前閉后開的寫法很直觀,這個回圈要回圈10次(但不是總是如此)
一些for回圈的變種
#include <stdio.h>
int main()
{
//變種1
for(;;)
{
printf("hehe\n");
}
//變種2
int x, y;
for (x = 0, y = 0; x<2 && y<5; ++x, y++)
{
printf("hehe\n");
}
return 0;
}
變種1
for的初始化,判斷,調整三個部分都可以省略
中間的判斷部分如果省略,意味著判斷恒為真,就構成死回圈
如果條件允許,不建議省略for回圈的3個運算式
這里看一個嵌套的for回圈 ,來比較一下
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
for (i = 0;i < 3;i++)
{
for (j = 0;j < 3;j++)
{
printf("hehe\n");
}
}
return 0;
}
在正常情況下,這個程式會3次外回圈,3次內回圈,共9次 列印9次hehe
我們現在試一下省略for的第一個初始化陳述句
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
for (;i < 3;i++)
{
for (;j < 3;j++)
{
printf("hehe\n");
}
}
return 0;
}

結果只列印了三次, 原因是 雖然外回圈還是3次,但內回圈由于 j 沒有初始化,在內回圈第3次后,j就變成了4,內回圈不再執行
變種2
使用多于一個變數控制回圈,這是允許的
for (x=0,y=0;x<2&&y<5,++x,y++)
這里,我們再拓展一道筆試題:
請問回圈要回圈多少次?
//請問回圈要回圈多少次?
#include <stdio.h>
int main()
{
int i = 0;
int k = 0;
for(i =0,k=0; k=0; i++,k++)
k++;
return 0;
}
答案是0次 
原因是這里的紅色框中的 k=0是賦值,k被賦值為0,0為假,回圈不執行
三.do...while()回圈
1.do...while()回圈的語法
do
回圈陳述句;
while (運算式);
我們再用do...while回圈來試著列印1~10的數
#include <stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i++;
} while (i <= 10);
}
do..while的特點是:回圈至少執行一次,使用的場景有限,所以不是經常使用,
流程圖
2.break和continue在do...while回圈中
(1).break
#include <stdio.h>
int main()
{
int i = 1;
do
{
if (5 == i)
break;
printf("%d ", i);
i++;
} while (i <=10);
return 0;
}

可見,break在三個回圈中較為類似,都是直接終止回圈,但是值得注意的是: break只能終止一層回圈,如果有剛剛那種嵌套式的回圈,只能終止一層
(2).continue
#include <stdio.h>
int main()
{
int i = 1;
do
{
if (5 == i)
continue;
printf("%d ", i);
i++;
} while (i <=10);
return 0;
}

運行的結果是1 2 3 4死回圈
好了,關于三個回圈就說到這兒,后續會更新回圈方面的練習題,寫到這兒已經寫了n個小時了,屬實是寫不動了.. 😪😪😪
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/342268.html
標籤:其他
上一篇:常用字串函式
