《C語言程序設(shè)計(jì)》課件2第4章_第1頁
《C語言程序設(shè)計(jì)》課件2第4章_第2頁
《C語言程序設(shè)計(jì)》課件2第4章_第3頁
《C語言程序設(shè)計(jì)》課件2第4章_第4頁
《C語言程序設(shè)計(jì)》課件2第4章_第5頁
已閱讀5頁,還剩58頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第4章選擇結(jié)構(gòu)4.1語句與復(fù)合語句4.2二分支選擇結(jié)構(gòu)4.3多分支選擇結(jié)構(gòu)4.4程序舉例習(xí)題4

本章學(xué)習(xí)要求:

1.了解關(guān)系運(yùn)算、邏輯運(yùn)算與表達(dá)式的關(guān)系,掌握語句、復(fù)合語句的概念。

2.掌握if語句(if;if…else…;if…elseif…else…)的使用、if-else語句的嵌套使用,掌握switch和break語句的使用。

為了控制計(jì)算機(jī)各操作的執(zhí)行次序,程序設(shè)計(jì)語言中引入了控制語句。選擇結(jié)構(gòu)是結(jié)構(gòu)化程序設(shè)計(jì)的三種結(jié)構(gòu)之一。C語言提供了二分支和多分支選擇結(jié)構(gòu),本章將進(jìn)行詳細(xì)介紹。

1.語句

C語言規(guī)定,在表達(dá)式的后面加上一個分號(;)即成為語句。例如:

x=1; 賦值語句

scanf("%d",&y); 輸入語句

y++; 自增運(yùn)算語句4.1語句與復(fù)合語句在C語言中除了結(jié)構(gòu)控制行之外,其他的內(nèi)容均由語句組成,即所有的語句均由一個分號(;)結(jié)束。有時為了程序的需要,我們會遇到只有一個分號而沒有表達(dá)式的情形,這在C語言中也是合法的,稱為空語句,例如:

main()

{

; /*空語句*/

}

在第1章的C語言特點(diǎn)中提到,C語言書寫靈活,允許一行寫多條語句,一條語句也可以寫在多行。但是建議初學(xué)者不要采用此種形式,因?yàn)檫@樣做不利于檢查和調(diào)試程序。

2.復(fù)合語句

在C語言中,用一對花括號“{}”將若干條語句括起來成為一個語句組,稱為復(fù)合語句,其一般形式如下:

{語句1;語句2;語句3;…;語句n;}

花括號內(nèi)語句的數(shù)量、類型不限,可以是聲明語句、賦值語句等;一個復(fù)合語句在語法上被視為一條語句。例如:

#include<stdio.h>

main()

{…

{inta,b,c;/*變量a、b、c只能在此復(fù)合語句內(nèi)使用*/

a=10;b=20;

c=a+b;

printf("%d,%d,%d\n",a,b,c);

}

}

注意,復(fù)合語句內(nèi)的定義變量語句要出現(xiàn)在執(zhí)行語句之前,且復(fù)合語句內(nèi)定義的變量只能在該復(fù)合語句內(nèi)部有效。

4.2.1簡單的二分支選擇結(jié)構(gòu)

C語言的if語句有兩種基本形式,即獨(dú)立的if結(jié)構(gòu)和if-else結(jié)構(gòu)。

1.獨(dú)立的if結(jié)構(gòu)

1)語法形式

if(表達(dá)式)

語句4.2二分支選擇結(jié)構(gòu)其中:

(1)

if是C語言的關(guān)鍵字;

(2)表達(dá)式可以是任意的表達(dá)式,且一對圓括號不可缺??;

(3)語句可以是一條簡單語句或復(fù)合語句。

2)執(zhí)行過程

首先計(jì)算表達(dá)式的值,然后根據(jù)其真假來決定程序的走向。若表達(dá)式為真(值為非零)則執(zhí)行語句,若為假(值為零)則不執(zhí)行語句。退出分支結(jié)構(gòu)后,程序繼續(xù)執(zhí)行if結(jié)構(gòu)后面的語句,如圖4.1所示。

圖4.1if結(jié)構(gòu)流程圖

3)舉例

執(zhí)行如下程序:

if(a>b)

b++;

若a的初值為20,b的初值為10,則表達(dá)式(a>b)為真,執(zhí)行語句“b++;”,則a的結(jié)果為20,b的結(jié)果為11。

若a的初值為10,b的初值為20,則表達(dá)式(a>b)為假,不執(zhí)行語句“b++;”,則a和b均保留初值即10和20。

如果語句為復(fù)合語句,將以上程序段改為

if(a>b)

{b++;

a++;}若a的初值為20,b的初值為10,則表達(dá)式(a>b)為真,執(zhí)行語句“b++;”和“a++;”,a的結(jié)果為21,b的結(jié)果為11。若a的初值為10,b的初值為20,則表達(dá)式(a>b)為假,語句“b++;”和“a++;”均不被執(zhí)行,a的結(jié)果仍為10,b的結(jié)果仍為20。如果將復(fù)合語句的一對花括號去掉,則程序段成為

if(a>b)

b++;

a++;

此時,語句“a++;”已不再屬于if結(jié)構(gòu),不管條件為真或?yàn)榧伲瑢τ谡麄€程序來說它都將被執(zhí)行。

2.?if-else結(jié)構(gòu)

1)語法形式

if(表達(dá)式)

語句1

else

語句2其中:

(1)

if和else是C語言的關(guān)鍵字,表達(dá)式及語句1、語句2的解釋同獨(dú)立的if結(jié)構(gòu);

(2)

else不能獨(dú)立存在,它必須與if語句配對組合方可使用,否則會產(chǎn)生語法錯誤;

(3)

else后面絕對不能跟條件表達(dá)式,它執(zhí)行的條件是隱含的,即與之配對的if的反面。

2)執(zhí)行過程

首先計(jì)算表達(dá)式的值,然后根據(jù)其真假來決定程序的走向。若表達(dá)式為真(值為非零)則執(zhí)行語句1,若為假(值為零)則執(zhí)行語句2。退出分支結(jié)構(gòu)后程序繼續(xù)執(zhí)行if-else結(jié)構(gòu)后面的語句,如圖4.2所示。

圖4.2if-else結(jié)構(gòu)流程圖

3)舉例

if(a>b)

b++;

else

a++;

若a的初值為20,b的初值為10,則表達(dá)式(a>b)為真,執(zhí)行語句“b++;”,然后退出if-else結(jié)構(gòu),a的結(jié)果為20,b的結(jié)果為11。

若a的初值為10,b的初值為20,則表達(dá)式(a>b)為假,執(zhí)行語句“a++;”,然后退出if-else結(jié)構(gòu),a的結(jié)果為11,b的結(jié)果為20。前文曾提到過語句1和語句2都可以是復(fù)合語句,但如果不慎將語句1的花括號丟了,則編譯時會出現(xiàn)語法錯誤,如下例:

main()

{inta=1,b=2;

if(a>b)a++;b--;

elsea--;}

該程序執(zhí)行時會出現(xiàn)錯誤提示信息:“Error:Misplacedelseinfunctionmain”,因?yàn)榇藭relse不能與if合法匹配,而else又不能獨(dú)立存在,所以出現(xiàn)了上述錯誤。4.2.2嵌套的二分支選擇結(jié)構(gòu)

1.在if語句中嵌套分支結(jié)構(gòu)

1)語法形式

if(表達(dá)式1)

if(表達(dá)式2)語句1

else語句2

else語句3其中:

(1)表達(dá)式1、2均可以是任意的表達(dá)式;

(2)語句1、2、3均可以是一條簡單語句或復(fù)合語句;

(3)內(nèi)層if-else語句書寫時注意格式縮進(jìn),以培養(yǎng)良好的程序設(shè)計(jì)風(fēng)格;

(4)內(nèi)層if-else結(jié)構(gòu)仍然可以繼續(xù)嵌套,依此類推。

2)執(zhí)行過程

首先計(jì)算表達(dá)式1的值,若表達(dá)式1為真則執(zhí)行內(nèi)層if-else語句,若表達(dá)式1為假則執(zhí)行語句3。若執(zhí)行內(nèi)層if-else語句,則計(jì)算表達(dá)式2的值,若表達(dá)式2為真則執(zhí)行語句1,若表達(dá)式2為假則執(zhí)行語句2,如圖4.3所示??傊绦虮仨氃谡Z句1、2、3中選擇其一來執(zhí)行。

圖4.3if嵌套的分支結(jié)構(gòu)流程圖

3)舉例

如果一個奇數(shù)x能被3整除,則輸出“是”,否則輸出“否”。程序段如下:

if(x%2!=0) /*條件1,判斷x是否為奇數(shù)*/

if(x%3==0) /*條件2,判斷x能否被3整除*/

printf("yes\n"); /*語句1*/

elseprintf("no\n"); /*語句2*/

elseprintf("no\n"); /*語句3*/

若x為6則條件1不滿足,執(zhí)行語句3,輸出“no”;若x為5則條件1滿足,條件2不滿足,執(zhí)行語句2,輸出“no”;若x為9則條件1、條件2均滿足,執(zhí)行語句1,輸出“yes”。

2.在else語句中嵌套分支結(jié)構(gòu)

1)語法形式

if(表達(dá)式1)

語句1

else

if(表達(dá)式2)語句2

else語句3

其中,解釋同上。

2)執(zhí)行過程

首先計(jì)算表達(dá)式1的值,若表達(dá)式1為真則執(zhí)行語句1,若表達(dá)式1為假則執(zhí)行內(nèi)層if-else語句。若執(zhí)行內(nèi)層if-else語句,則計(jì)算表達(dá)式2的值,若表達(dá)式2為真則執(zhí)行語句2,若表達(dá)式2為假則執(zhí)行語句3,如圖4.4所示??傊绦虮仨氃谡Z句1、2、3中選擇其一來執(zhí)行。

圖4.4else嵌套的分支結(jié)構(gòu)流程圖

3)舉例

題目同上,如果一個奇數(shù)x能被3整除,則輸出“是”,否則輸出“否”。改用另外一種思路來解決,程序段如下:

if(x%2==0) /*條件1,判斷x是否為奇數(shù)*/

printf("no\n"); /*語句1*/

else

if(x%3==0) /*條件2,判斷x能否被3整除*/

printf("yes\n"); /*語句2*/

elseprintf("no\n"); /*語句3*/觀察發(fā)現(xiàn)將嵌套if-else結(jié)構(gòu)移至外層else語句之后,此例與上例的主要變化之處在于表達(dá)式1及語句1、語句2的變化,只有改變才能解決問題。可見,同一個問題可以有很多種解決辦法,我們要善于開拓思路,推陳出新。如此一來,若x為6則條件1滿足,執(zhí)行語句1,輸出“no”;若x為5則條件1不滿足,條件2也不滿足,執(zhí)行語句3,輸出“no”;若x為9則條件1不滿足,條件2滿足,執(zhí)行語句2,輸出“yes”。特別說明:

(1)在一個分支結(jié)構(gòu)中,if和else語句均可以同時進(jìn)行若干層嵌套;

(2)內(nèi)嵌結(jié)構(gòu)可以是if語句或if-else語句;

(3)當(dāng)嵌套較多的時候,則程序結(jié)構(gòu)不清晰,if與else的配對容易混淆,這里給大家一個解決辦法,從上至下將每個else與距其最近的尚未配對的if進(jìn)行匹配。

在C語言中還提供了一種多路判定語句switch,在這種結(jié)構(gòu)里可以實(shí)現(xiàn),一個條件符合時程序執(zhí)行若干條語句。

1.語法形式

switch(表達(dá)式)

{case常量表達(dá)式1:語句序列1

case常量表達(dá)式2:語句序列2

case常量表達(dá)式n:語句序列n

default:語句序列n+1

}4.3多分支選擇結(jié)構(gòu)…其中:

(1)

switch、case和default是C語言關(guān)鍵字,default是可以缺省的項(xiàng);

(2)

switch后的表達(dá)式必須為整型或字符型表達(dá)式;

(3)

case后的常量表達(dá)式稱為標(biāo)號,且標(biāo)號必須互不相同,case與標(biāo)號之間必須留有空格;

(4)

必要時,某些case標(biāo)號后的語句序列可以不寫,但冒號不可省掉;

(5)語句序列可以是一條也可以是多條,且多條不需組合成復(fù)合語句。

2.執(zhí)行過程

首先計(jì)算switch后表達(dá)式的值,然后尋找與其相等的case標(biāo)號,如果找到了則從該case后的語句序列開始執(zhí)行下去,不再進(jìn)行判斷,直至遇break或switch結(jié)構(gòu)結(jié)束;如果沒有找到與switch表達(dá)式的值相等的case標(biāo)號,則執(zhí)行default后的語句序列或退出switch結(jié)構(gòu)(default缺省的情況下)。

這里提到了break,它是一個使程序立即從switch結(jié)構(gòu)或循環(huán)中退出的語句,在下一章會詳細(xì)介紹。具體程序中到底要不要使用break,需要針對實(shí)際問題而定。

3.舉例

設(shè)變量grade是字符型,代表成績的等級,以下程序段則實(shí)現(xiàn)根據(jù)學(xué)生成績的等級來輸出相應(yīng)的分?jǐn)?shù)范圍:

switch(grade)

{case'A':printf("90~100\n");break;

case'B':printf("80~89\n");break;

case'C':printf("70~79\n");break;

case'D':printf("60~69\n");break;

case'E':printf("0~59\n");break;

default:printf("error!\n");

}執(zhí)行以上程序段時,若grade的值為A則輸出結(jié)果是:90~100<換行符>;若grade的值為D則輸出結(jié)果是:60~69<換行符>;若grade的值超出A~E這五個等級,例如G則輸出結(jié)果是:error!<回車>。

如果將所有的break語句去掉,程序變成:

switch(grade)

{case'A':printf("90~100\n");

case'B':printf("80~89\n");

case'C':printf("70~79\n");

case'D':printf("60~69\n");

case'E':printf("0~59\n");

default:printf("error!\n");

}則程序找到一個入口之后會一直執(zhí)行到switch結(jié)束,例如,若grade的值為C,則輸出結(jié)果是:

70~79

60~69

0~59

error!

顯然,后面三行的信息是不需要的,所以實(shí)際應(yīng)用中要善于使用break語句。

要注意的是,A~E是字符常量,其兩邊一定要加上單引號,否則系統(tǒng)認(rèn)為是五個變量從而會導(dǎo)致若干錯誤。

例4.1

從鍵盤輸入三個整數(shù),然后將其中最大的一個輸出。

求解最大值是很常見的問題,解決辦法也有很多種,下面給出的三種解法與前文講過的幾種二分支選擇結(jié)構(gòu)對應(yīng),大家可進(jìn)一步掌握分支結(jié)構(gòu)。4.4程序舉例

方法一采用獨(dú)立的if語句實(shí)現(xiàn)。

#include<stdio.h>

main()

{intx,y,z,m;

printf("pleaseenterthreenumbers:\n");

/*提示信息*/

scanf("%d,%d,%d",&x,&y,&z); /*輸入語句*/

m=x;

if(y>m)m=y;

if(z>m)m=z;

printf("themaximum:%4d\n",m);

}程序的運(yùn)行結(jié)果如下:

pleaseenterthreenumbers:

25,49,3

themaximum:49<回車>

方法二采用if-else語句實(shí)現(xiàn)。這里只將以上程序的主體部分(即6、7、8行)進(jìn)行如下修改:

if(x>y)m=x;

elsem=y; /*隱含條件是(x<=y)*/

if(z>m)m=z;

方法三采用嵌套的if-else語句實(shí)現(xiàn)。將第一個程序的主體部分(即6、7、8行)進(jìn)行如下修改:

if(x>y)

if(x>z)m=x; /*內(nèi)嵌if-else執(zhí)行條件是(x>y),本行成立條件是(x>y)&&(x>z)*/

elsem=z; /*隱含條件是(x>y)&&(x<=z)*/

else /*隱含條件是(x<=y)*/

if(z<y)m=y; /*內(nèi)嵌if-else執(zhí)行條件是(x<=y),本行成立條件是(x<=y)&&(z<y)*/

elsem=z; /*隱含條件是(x<=y)&&(z>=y)*/

通過以上三種解題方法可以看出,第三個程序顯然比前兩個要復(fù)雜,可讀性較差。所以在實(shí)際應(yīng)用中我們要善于思考比較,編寫出較為簡潔、易讀的程序。

例4.2

有一函數(shù):

寫一程序,輸入x值,輸出y值。

本例題既可以用獨(dú)立的if語句解決,也可以用if-else語句實(shí)現(xiàn)。這里僅給出用if-else語句編寫的程序(流程圖如圖4.5所示)。

圖4.5例4.2程序流程圖

#include<stdio.h>

main()

{

intx,y;

printf("pleaseenteranumber:\n");

scanf("%d",&x);

if(x<0)y=x;

elseif(x<10)y=2*x-1;

elsey=3*x-11;

printf("y=%d\n",y);

}編寫這段程序的主體部分時,初學(xué)者容易寫成如下形式:

if(x<0)y=x;

elseif(0<=x<10)y=2x-1;

elseif(x>=10)y=3x-11;

此種寫法首先存在以下兩處嚴(yán)重的語法錯誤:

(1)表達(dá)式(0<=x<10)寫法錯誤,必須改成(0<=x&&x<10);

(2)表達(dá)式“2x-1”、“3x-11”中的2x和3x系統(tǒng)無法識別,必須改成“2*x-1”、“3*x-11”,因?yàn)楸磉_(dá)式必須由運(yùn)算符和操作數(shù)組成。

另外,還有兩處多余的地方,即:

(1)“if(0<=x<10)”中的大于等于零條件已經(jīng)隱含了,無需再列出,“if(x<10)”即可;

(2)第三個if語句“if(x>=10)”不必寫出,它的條件也已由第二個else隱含實(shí)現(xiàn)了。

例4.3

給出一個百分制成績,要求輸出其相應(yīng)的等級。規(guī)定:90分以上為“A”,

80~89分為“B”,70~79分為“C”,60~69分為“D”,60分以下為“E”。

本例題要求使用switch語句解決。大家知道實(shí)際生活中成績是允許帶小數(shù)的,比如70.5。假設(shè)帶一位小數(shù),則可能出現(xiàn)的分?jǐn)?shù)將有近千種,因而用case列出所有的分?jǐn)?shù)情況顯然是不可能的,如果是兩位小數(shù)則情況更要成倍增加。對待較復(fù)雜問題,重在尋找規(guī)律。我們發(fā)現(xiàn),除了100分,“A”等級分?jǐn)?shù)的十位數(shù)字均是9,“B”等級分?jǐn)?shù)的十位數(shù)字均是8,依此類推。所以如果能取到成績的十位數(shù)字,問題則只剩下0~10這11種情況,相對要簡單得多,實(shí)際上因?yàn)?0分以下均為“E”,所以編程時只要列出5種情況即可。

問題重點(diǎn)就成為了如何取到分?jǐn)?shù)的十位數(shù)字,其中一個解決辦法就是將分?jǐn)?shù)除以10,取結(jié)果的整數(shù)部分即可。程序如下:

#include<stdio.h>

main()

{

floatscore;

intg;

printf("pleaseenteranumberbetween0and100\n");

scanf("%f",&score);

g=(int)score;

switch(g/10)

{case10:

case9:printf("thegradeisA\n");break;

case8:printf("thegradeisB\n");break;

case7:printf("thegradeisC\n");break;

case6:printf("thegradeisD\n");break;

default

:printf("thegradeisE\n");

}

}

以上程序的運(yùn)行結(jié)果是:

pleaseenteranumberbetween0and100

86.5

thegradeisB仔細(xì)考慮后發(fā)現(xiàn),以上程序存在以下兩個不足:

(1)如果用戶不小心輸入了一個不符合常規(guī)的分?jǐn)?shù),比如-6、112等,程序仍會給出一個等級“E”;

(2)本程序的switch中共有5條幾近相同的printf()函數(shù)組成的語句,顯得非常累贅;

針對以上問題,我們將程序改進(jìn)如下:

#include<stdio.h>

main()

{

floatscore;

intg;charch;

printf("pleaseenteranumberbetween0and100\n");

scanf("%f",&score);

if((score>=0)&&(score<=100))

{g=(int)score;

switch(g/10)

{case10:

case9:ch='A';break;

case8:ch='B';break;

case7:ch='C';break;

case6:ch='D';break;

default:ch='E';

}

printf("thegradeis%c\n",ch);

}

elseprintf("error!\n");

}

運(yùn)行時如果不小心輸入了一個超過范圍的數(shù)據(jù),則程序會輸出出錯的信息。

本問題也完全可以用if-else結(jié)構(gòu)來實(shí)現(xiàn),大家可以自己編寫練習(xí)。

一、選擇題

1.為了避免在嵌套的if-else中產(chǎn)生歧義,C語言規(guī)定,一般else子句總是與()配對。

A.縮排位置相同的ifB.其之前最近的if

C.其之后最近的ifD.同一行上的if習(xí)題4

2.以下不正確的語句為()。

A.

if(x>y);

B.

if(x<y){x++;y++;}

C.

if(x!=y)scanf("%d",&x);elsescanf("%d",&y);

D.

if(x=y)&&(x!=0)x+=y;

3.以下if語句語法正確的是()。

A.

if(x>0)printf("%f",x)

elseprintf("%f",-x);

B.

if(x>0){x++;printf("%f",x);}

elseprintf("%f",-x);

C.

if(x>0){x++;printf("%f",x);};

elseprintf("%f",-x);

D.

if(x>0){x++;printf("%f",x)}

elseprintf("%f",-x);

4.閱讀以下程序,則()。

main()

{inta=5,b=0,c=0;

if(a=b+c)printf(“***\n”);

else

printf(“$$$\n”);

}

A.有語法錯誤不能通過編譯

B.可以通過編譯但不能通過連接

C.輸出***

D.輸出$$$

5.執(zhí)行下面程序時,若從鍵盤輸入5,則輸出為()。

main()

{inta;

scanf("%d",&a);

if(a++>5)printf("%d\n",a);

else

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論