天天看點

選擇分支結構

if語句

1.簡單if語句

if(表達式) 語句1;

其語義是先計算表達式的值,若為“真”,則執行語句1,否則跳過語句1執行if語句的下一條語句。

【例】輸入3個整數x、y、z,請把這3個數由小到大輸出。

算法分析:

(1)先将x與y比較,把小者放x中,大者放y中;

(2)再将x與z比較,把小者放x中,大者放z中,此數x已是三者中最小的;

(3)最後将y與z比較,大者放z中,小者放y中,此時x、y、z已按從小到大的順序排列好。

#include<stdio.h>
int main()
{
	int a,b,c,d;
	printf("\n請輸入兩個整數(a,b,c):");
	scanf("%d,%d,%d",&a,&b,&c);
	if(a>b)
	{
		d=a;
		a=b;
		b=d;
	}
	if(a>c)
	{
		d=a;
		a=c;
		c=d;
	}
	if(b>c)
	{
		d=b;
		b=c;
		c=d;
	}
	printf("該3個數由小到大的順序為:%d,%d,%d\n",a,b,c);
	return 0;
}
           

2.if-else語句

if-else語句的形式如下:

if (表達式)語句1;

else 語句2;

其語句是:如果表達式的值為真,則執行語句1,并跳過語句2,繼續執行if語句的下一條語句;若表達式的值為假,執行語句2,然後繼續執行if語句後的下一條語句。

【例1】判斷給定的某一年是否是閏年。

分析:如果某年能被4整除而不能被100整除,或者能被400整除,那麼該年就是閏年,否則就是平年。

#include<stdio.h>
int main()
{
	int year,leap=0;
	printf("\n請輸入年份(yyyy):");
	scanf("%d",&year);
	if(year%4==0&&year%100!=0||year%100==0)
	 printf("%d年是閏年\n",year);
	else
	 printf("%d年是平年\n",year);
	return 0;
 } 
           

【例2】制作簡單的猜數字遊戲。程式運作時自動産生1~5的随機數,接着等待鍵盤輸入猜的數字。如果猜對了,顯示“猜對了”相關資訊;否則顯示“猜錯了”相關資訊。

(1)随機數産生。C語言提供srand()函數,配合rand()函數可産生介于0~32767的随機數(srand()、rand()函數均包含在stdlib.h中,time()函數包含在time.h中)。

(2)1~5的随機數。首先用rand()函數産生的随機數對5求餘(rand()%5),産生0 ~4之間的整數,然後再加1,即rand()%5+1就産生1 ~5的整數。

(3)判斷程式結構為二路選擇結構。

#include<stdio.h>
#include<stdlib.h>                                   /*包含産生随機數的srand()、rand()函數*/ 
#include<time.h>
int main()
{
	int data,guess;
	srand((unsigned)time(NULL));                     /*做随機數産生器的種子*/ 
	data=rand()%5+1;                                 /*将随機數對5求餘(rand()%5),産生0~4之間的整數,然後再加1,産生1~5的整數*/ 
	printf("請輸入要猜的數字(限1~5):");
	scanf("%d",&guess);
	if (guess==data)                                 /*guess=rand();為以上面得到的種子産生0~32767的整數*/ 
	 printf("猜對了!,正确數字為 %d !\n",data);
	else
	 printf("猜錯了!,正确數字為 %d !\n",data);
	return 0;
 } 
           

【例3】一個五位數,判斷它是不是回文數,如65456是個回文數,即該數的個位與萬位相同、十位與千位相同。

分析:

(1)題目要求是一個五位數,由于五位數超過了int類型的範圍,是以應該用long int類型,那麼在輸入時一定要用對應的“%ld”格式。

(2)判斷輸入的數是否為五位數,即是否在10000~100000。

(3)分解出該數的每一位數(萬位、千位、十位和個位),然後按要求進行判斷,即個位與萬位相同、十位與千位相同。

#include<stdio.h>
int main()
{
	long x;
	int ge,shi,qian,wan;
	printf("\n請輸入一個五位數:");
	scanf("%ld",&x);
	if(x>=10000&&x<100000)
	{
		wan=x/10000;                              /*分解出萬位*/
		qian=x%10000/1000;                        /*分解出千位*/
		shi=x%100/10;                             /*分解出十位*/
		ge=x%10;                                  /*分解出個位*/
		if(ge==wan&&shi==qian)
		 printf("該數是回文數!\n");
		else
		 printf("該數不是回文數!\n"); 
	}
	else
	{
		printf("抱歉,該數不是一個五位數!\n");
		int exit(1);                              /*出錯退出*/ 
	}
	return 0;
 } 
           

exit()函數的原型如下:void exit(程式狀态值);

功能:結束程式運作,傳回作業系統,并将“程式狀态值”傳回給作業系統。當程式狀态值為0時,表示程式正常退出;為非0值時,表示程式出錯退出。

【例4】輸入一個三角形的三邊長A、B、C,然後判斷此三角形是否為直角三角形。

分析:

(1)滿足三角形邊長的基本條件為:邊長不能為負數,且兩邊之和必須大于第三邊。

(2)直角三角形的三邊長應滿足A^2+B ^2=C或A ^2+C ^2=B ^2或B ^2+C ^2=A ^2其中之一。

(3)C語言提供pow(a,b)函數可傳回a^b的值,該函數包含在頭檔案math.h中。

#include<stdio.h>
#include<math.h>                                                                                              /*包含pow(a,b)函數*/ 
int main()
{
	int A,B,C;
	printf("請輸入三角形的三個邊長(A,B,C):");
	scanf("%d,%d,%d",&A,&B,&C);
	if(A<0||B<0||C<0)                                                                                         /*邊長不為負數*/ 
	{
		printf("抱歉,邊長不能為負數!");
		int exit(1);                                                                                          /*出錯退出*/ 
	}
	if(A+B<=C||A+C<=B||B+C<=A)                                                                                /*三角形任意兩邊和大于第三邊*/ 
	{
		printf("抱歉,三角形任意邊之和應該大于第三邊!");
		int exit(1);                                                                                          /*出錯退出*/ 
	}
	if((pow(A,2)+pow(B,2))==pow(C,2)||(pow(A,2)+pow(C,2))==pow(B,2)||(pow(B,2)+pow(C,2))==pow(A,2))           /*C語言pow(a,b)函數可傳回a^b的值*/ 
	 printf("是直角三角形!\n");
	else
	 printf("不是直角三角形!\n");
	return 0;
 } 
           

3.if-else-if語句

當有多個分支選擇時,可采用if-else-if語句,其一般形式如下。

if(表達式1) 語句1;

else if(表達式2) 語句2;

else if(表達式3) 語句3;

else if(表達式n-1) 語句n-1;

else 語句n;

其語義是:依次判斷表達式1至n-1的值,當表達式中某個值為邏輯真是,則執行其相應的語句,然後跳到整個if語句之外繼續執行後續語句。如果所有的表達式均為假,則執行語句n,然後繼續執行後續語句。if-else-if語句的執行過程如圖所示。

選擇分支結構

【例1】假設一年四季中春季為2~4月,夏季為5 ~7月,秋季為8 ~10月,冬季為11 ~次年1月。編寫程式,根據輸入的月份列印出所屬的季節。

#include<stdio.h>
int main()
{
	int a;
	printf("請輸入月份(1~12):");
	scanf("%d",&a);
	if(a>=2&&a<=4)
	 printf("現在是春季!");
	else if(a>=5&&a<=7)
	 printf("現在是夏季!");
	else if(a>=8&&a<=10)
	 printf("現在是秋季!");
	else if(a==11||a==12||a==1)
	 printf("現在是冬季!");
	return 0;
 }
           

【例2】編寫程式,要求判别鍵盤輸入字元的類别。

分析:根據輸入字元的ASCII碼來判斷類型。由附錄I中的ASCII碼表可知ASCII碼值小于32的為控制字元,在’0’(48)和’9’(57)之間的字元為數字,在’A’(65)和’Z’(90)之間的字元為大寫字母,在’a’(97)和’z’(122)之間的字元為小寫字母,其餘歸為其他字元。這是一個多分支選擇的問題,用if-else-if語句程式設計,判斷輸入字元ASCII碼所在的範圍,分别給出不同的輸出。

#include<stdio.h>
int main()
{
	char c;
	printf("\n請輸入一個字元:\n");
	c=getchar();                          /*從鍵盤上讀入字元直到回車結束*/ 
	if(c<32)
	 printf("這是一個控制字元!\n");
	else if(c>='0'&&c<='9')               /*也可以用ASCII碼值進行判斷。即也可寫為if(c>=48&&c<=57),隻是前者程式的可讀性更強*/ 
	 printf("這是一個數字!\n");
	else if(c>='A'&&c<='Z')
	 printf("這是一個大寫字母!\n");
	else if(c>='a'&&c<='z')
	 printf("這是一個小寫字母!\n");
	else
	 printf("這是其他字元!\n");
	return 0;
}
           

【例3】給不多于五位的正整數,求出它的位數并按逆序列印出各位數字。

#include<stdio.h>
int main()
{
	long x;
	int wan,qian,bai,shi,ge;
	printf("請輸入一個不多于五位的正整數:");
	scanf("%ld",&x);
	if(x>100000)
	{
		printf("\n抱歉,該數已超過五位數!");
	    int exit(1);
	}
	else if(x<0)
	{
		printf("\n抱歉,該數不是正數!");
		int exit(1);
	}
	else
	{
		wan=x/10000;                                //分解出萬位
		qian=x%10000/1000;                          //分解出千位
		bai=x%1000/100;                             //分解出百位
		shi=x%100/10;                               //分解出十位
		ge=x%10;                                    //分解出個位
		if(wan!=0)
		 printf("該數有五位,個位:%d,十位:%d,百位:%d,千位:%d,萬位:%d\n",ge,shi,bai,qian,wan);
		else if(qian!=0)
		 printf("該數有四位,個位:%d,十位:%d,百位:%d,千位:%d\n",ge,shi,bai,qian);
		else if(bai!=0)
		 printf("該數有三位,個位:%d,十位:%d,百位:%d\n",ge,shi,bai);
		else if(shi!=0)
		 printf("該數有二位,個位:%d,十位:%d\n",ge,shi);
		else if(ge!=0)
		 printf("該數有一位,個位:%ld\n",ge);
		else
		 printf("該數為0.");
	}
	return 0;
 }
           

if語句的嵌套

當if語句中執行語句又是if語句時,則構成了if語句嵌套的情形。其一般形式可表示如下。

if(表達式)

if語句;

或者:

if(表達式) if語句;

else if語句;

在嵌套内的if語句可能又是if-else型的,這将會出現多個if和多個else重疊的情況,這時要特别注意if和else的配對問題。例如:

if(表達式1)

if(表達式2) 語句1;

else 語句2;

為了避免二義性,C語言規定,else總是與在它前面、據它最近、且尚未比對的if配對。強烈建議:将内嵌的if語句一律用花括号括起來。

【例】有一個函數如下:

y=x+1 (x<10)

y=x^2 (10<=x<20)

y=6x+9 (x>=20)

編寫一個程式,輸入任意x值,輸出對應的y值。

方法一:

#include<stdio.h>
int main()
{
	float x,y;
	printf("\n請輸入x:");
	scanf("%f",&x);
	if(x<10)
	 y=x+1;
	else if(x>=10&&x<20)
	 y=x*x;
	else if(x>=20)
	 y=6*x+9;
	printf("y=%f\n",y);
	return 0;
 }
           

方法二(改進)

#include<stdio.h>
#include<math.h>
int main()
{
	float x,y;
	printf("\n請輸入x:");
	scanf("%f",&x);
	if(x<10)
	 y=x+1;
	else if(x<20)
	 y=pow(x,2);
	else
	 y=6*x+9;
	printf("y=%f\n",y);
	return 0;
 } 
           

switch語句

switch語句的一般形式

switch(表達式)

{

case 常量1: 語句1;

case 常量2: 語句2;

case 常量n: 語句n;

defauly: 語句n+1;

}

其語義是:首先計算switch後圓括号内表達式的值,然後用該值逐個與case後面的常量值進行比較。當與某個case後的常量值想等時,則執行該case後的語句,然後順序執行後面所有的case後的語句。如果圓括号内表達式的值與所有case後的常量值均不相等時,如果存在default則執行其後的語句序列,否則什麼都不做。

【例1】了解switch語句的執行過程。

#include<stdio.h>
int main()
{
	int j=10;
	switch(j)
	{
		case 9:j+=1;
		case 10:j+=2;
		case 11:j+=3;
		default:j+=4;
	}
	printf("j=%d\n",j);
	return 0;
 } 
           

分析:首先得到j=10,是以用10和case後的常量比較發現相同的便執行其後的語句j+=2,然後不再進行比較,順序執行後面所有case後的語句j+=3,j+=4,是以運作結果如下。

j=19
           

switch-break語句

switch(表達式)

{

case 常量1: 語句1;break;

case 常量2: 語句2;break;

case 常量n: 語句n;break;

default: 語句n+1;break;

}

其語義為:首先計算表達式的值,若該值與某個case後面的常量值相等,則執行其後的語句序列。遇到break語句時,跳出整個switch結構。如果表達式的值與所有常量值都不相等,若存在default則執行其後的語句序列,否則什麼也不做。将【例1】修改如下。

#include<stdio.h>
int main()
{
	int j=10;
	switch(j)
	{
		case 9:j+=1;break;
		case 10:j+=2;break;
		case 11:j+=3;break;
		default:j+=4;break;
	}
	printf("j=%d\n",j);
	return 0;
 }
           

運作結果:

j=12
           

在使用switch語句時還應注意以下幾點。

(1)在case後的各常量表達式的值不能相同,否則會出現錯誤。

(2)在case後,允許有多個語句,可以不用{}括起來。

(3)各case和default子句的先後順序可以變動,而不會影響程式執行結果(前提是每個case語句中都存在break語句)。

(4)default子句可以省略不用。

switch語句的嵌套

【例】了解switch語句嵌套結構并分析其執行過程。

#include<stdio.h>
int main()
{
	int a=1,b=0;
	switch(a)
	{
		case 1:switch(b)
		{
			case 0:printf("***");break;
			case 1:printf("@@@");break;
		}
		case 2:printf("$$$");break;
		default:printf("###");	
	}
	return 0;
 }
           

分析:首先得到a=1,那麼執行對應的case 1之後的語句,又是一個switch語句。先得到b=0,執行相應的case 0語句,列印“***”之後碰到break,跳出其所在的switch語句,即switch(b)。然後順序執行case 2之後的語句,列印“$$$”之後碰到break,跳出所在的switch(a),進而程式結束。

運作結果:

***$$$
           

選擇分支結構程式舉例

【例1】查詢自動販賣機中商品的價格。假設自動販賣機中出售6種商品:綠茶、可樂、芬達、礦泉水、爆米花和瓜子,售價分别為4元、3.5元、3元、1.5元、5元和2.5元。

#include<stdio.h>
int main()
{
	int a;
	printf("\n  ******自動販賣機查詢系統******\n");
	printf("查詢價格請按商品前的序号,按0退出查詢。\n");
	printf("             1.綠茶\n");
	printf("             2.可樂\n");
	printf("             3.芬達\n");
	printf("             4.礦泉水\n");
	printf("             5.爆米花\n");
	printf("             6.瓜子\n");
	printf("             0.退出\n");
	printf("您要查詢:");
	scanf("%d",&a);
	switch(a)
	{
		case 1:printf("綠茶: 4元/瓶");break;
		case 2:printf("可樂: 3.5元/瓶");break;
		case 3:printf("芬達: 3元/瓶");break;
		case 4:printf("礦泉水: 1.5元/瓶");break;
		case 5:printf("爆米花: 5元/杯");break;
		case 6:printf("瓜子: 2.5元/袋");break;
		case 0:return 0;
	}
	printf("\n");
	return 0;
 }
           

運作結果:

您要查詢:1
綠茶:4元/瓶
           
您要查詢:5
爆米花:5元/杯
           

【例2】某地計程車的收費方法為:起步價7元,最多可行駛3公裡(不包含3公裡);3~8公裡(不包含8公裡)按1.7元/公裡計算(不足1公裡,按1公裡計算);8公裡以後按2.0元/公裡計算(不足1公裡,按1公裡計算)。編寫程式,輸入所行使裡程數,計算并輸出車費。

#include<stdio.h>
int main()
{
	double a,b;
	printf("請輸入公裡數:");
	scanf("%lf",&a);
	if(a<0)
	{
		printf("抱歉,格式出錯!"); 
	}
	else
	{
		if(a<3)          b=7;
		else if(a<8)     b=7+((int)(a-2+1))*1.7;                       /*不足1公裡的部分按照1公裡計算,即為(a-2+1)。(int)定義(a-2+1)部分為整型,即舍棄小數部分*/ 
		else             b=7+5*1.7+((int)(a-7+1))*2.0;    
	}
	printf("您的計程車費用為:%8.2lf元。\n",b);                        //%8.2lf表示,輸出的寬度為8,輸出2為小數// 
	return 0;
}
           

運作結果:

請輸入公裡數:0
抱歉,出錯!
           
請輸入公裡數:3.2
您的計程車費用為:10.40元
           

【例3】求ax^2+bx+c=0方程的解。

分析:求解此方程的解,應該考慮到各種可能的情況。

當a=0時,不是二次方程,沒有二次方根,否則:

(1)當b^2-4ac=0時,方程有兩個相等的實根。

(2)當b^2-4ac>0時,方程有兩個不相等的實根。

(3)當b^2-4ac<0時,方程有兩個共轭的複根。

#include<stdio.h>
#include<math.h>
int main()
{
	float a,b,c,disc,x1,x2,realpart,imagpart;
	printf("\n請輸入方程的3個系數:(a=,b=,c=)\n");
	scanf("a=%f,b=%f,c=%f",&a,&b,&c);
	if(fabs(a)<=1e-6) printf("該方程沒有二次方根。\n");                  /*在怕判斷disc是否為0時,由于此值為實數,而實數在計算和儲存時會存在一定誤差,
	是以不能直接進行if(disc==0)的判斷,是以在這裡是用判别disc的絕對值(fabs(disc))是否小于一個很小的數(10^6),如果小于此數,就近似認為disc等于0.*/ 
	else disc=b*b-4*a*c;
	if(fabs(disc)<=1e-6)
	 printf("該方程有兩個相等的實根:x1=x2=%8.4f\n",-b/(2*a));           //%8.4f表示,輸出的寬度為8,輸出4位小數// 
	else if(disc>1e-6)
	{
		x1=(-b+sqrt(disc))/(2*a);
		x2=(-b-sqrt(disc))/(2*a);
		printf("該方程有兩個不相等的實根:\n x1=%8.4f,x2=%8.4f\n",x1,x2);
	 } 
	 else
	 {
	 	realpart=-b/(2*a);
	 	imagpart=sqrt(-disc)/(2*a);
	 	printf("該方程有兩個複根:\n");
	 	printf("x1=%8.af+%8.4fi\n",realpart,imagpart);
	 	printf("x2=%8.4f-%8.4fi\n",realpart,imagpart);
	 }
	return 0;
}
           

運作結果:

a=0,b=1,c=1
該方程沒有二次方根
           
a=1,b=2,c=1
該方程有兩個相等的實根:x1=x2=-1.0000
           
a=2,b=6,c=1
該方程有兩個不相等的實根:x1=-0.1771,x2=-2.8229
           
a=1,b=2,c=2
該方程有兩個複根:
x1=-1.0000+1.0000i
x2=-1.0000-1.0000i