《C语言程序设计》课件2第4章_第1页
《C语言程序设计》课件2第4章_第2页
《C语言程序设计》课件2第4章_第3页
《C语言程序设计》课件2第4章_第4页
《C语言程序设计》课件2第4章_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第4章选择结构4.1语句与复合语句4.2二分支选择结构4.3多分支选择结构4.4程序举例习题4

本章学习要求:

1.了解关系运算、逻辑运算与表达式的关系,掌握语句、复合语句的概念。

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

为了控制计算机各操作的执行次序,程序设计语言中引入了控制语句。选择结构是结构化程序设计的三种结构之一。C语言提供了二分支和多分支选择结构,本章将进行详细介绍。

1.语句

C语言规定,在表达式的后面加上一个分号(;)即成为语句。例如:

x=1; 赋值语句

scanf("%d",&y); 输入语句

y++; 自增运算语句4.1语句与复合语句在C语言中除了结构控制行之外,其他的内容均由语句组成,即所有的语句均由一个分号(;)结束。有时为了程序的需要,我们会遇到只有一个分号而没有表达式的情形,这在C语言中也是合法的,称为空语句,例如:

main()

{

; /*空语句*/

}

在第1章的C语言特点中提到,C语言书写灵活,允许一行写多条语句,一条语句也可以写在多行。但是建议初学者不要采用此种形式,因为这样做不利于检查和调试程序。

2.复合语句

在C语言中,用一对花括号“{}”将若干条语句括起来成为一个语句组,称为复合语句,其一般形式如下:

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

花括号内语句的数量、类型不限,可以是声明语句、赋值语句等;一个复合语句在语法上被视为一条语句。例如:

#include<stdio.h>

main()

{…

{inta,b,c;/*变量a、b、c只能在此复合语句内使用*/

a=10;b=20;

c=a+b;

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

}

}

注意,复合语句内的定义变量语句要出现在执行语句之前,且复合语句内定义的变量只能在该复合语句内部有效。

4.2.1简单的二分支选择结构

C语言的if语句有两种基本形式,即独立的if结构和if-else结构。

1.独立的if结构

1)语法形式

if(表达式)

语句4.2二分支选择结构其中:

(1)

if是C语言的关键字;

(2)表达式可以是任意的表达式,且一对圆括号不可缺省;

(3)语句可以是一条简单语句或复合语句。

2)执行过程

首先计算表达式的值,然后根据其真假来决定程序的走向。若表达式为真(值为非零)则执行语句,若为假(值为零)则不执行语句。退出分支结构后,程序继续执行if结构后面的语句,如图4.1所示。

图4.1if结构流程图

3)举例

执行如下程序:

if(a>b)

b++;

若a的初值为20,b的初值为10,则表达式(a>b)为真,执行语句“b++;”,则a的结果为20,b的结果为11。

若a的初值为10,b的初值为20,则表达式(a>b)为假,不执行语句“b++;”,则a和b均保留初值即10和20。

如果语句为复合语句,将以上程序段改为

if(a>b)

{b++;

a++;}若a的初值为20,b的初值为10,则表达式(a>b)为真,执行语句“b++;”和“a++;”,a的结果为21,b的结果为11。若a的初值为10,b的初值为20,则表达式(a>b)为假,语句“b++;”和“a++;”均不被执行,a的结果仍为10,b的结果仍为20。如果将复合语句的一对花括号去掉,则程序段成为

if(a>b)

b++;

a++;

此时,语句“a++;”已不再属于if结构,不管条件为真或为假,对于整个程序来说它都将被执行。

2. if-else结构

1)语法形式

if(表达式)

语句1

else

语句2其中:

(1)

if和else是C语言的关键字,表达式及语句1、语句2的解释同独立的if结构;

(2)

else不能独立存在,它必须与if语句配对组合方可使用,否则会产生语法错误;

(3)

else后面绝对不能跟条件表达式,它执行的条件是隐含的,即与之配对的if的反面。

2)执行过程

首先计算表达式的值,然后根据其真假来决定程序的走向。若表达式为真(值为非零)则执行语句1,若为假(值为零)则执行语句2。退出分支结构后程序继续执行if-else结构后面的语句,如图4.2所示。

图4.2if-else结构流程图

3)举例

if(a>b)

b++;

else

a++;

若a的初值为20,b的初值为10,则表达式(a>b)为真,执行语句“b++;”,然后退出if-else结构,a的结果为20,b的结果为11。

若a的初值为10,b的初值为20,则表达式(a>b)为假,执行语句“a++;”,然后退出if-else结构,a的结果为11,b的结果为20。前文曾提到过语句1和语句2都可以是复合语句,但如果不慎将语句1的花括号丢了,则编译时会出现语法错误,如下例:

main()

{inta=1,b=2;

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

elsea--;}

该程序执行时会出现错误提示信息:“Error:Misplacedelseinfunctionmain”,因为此时else不能与if合法匹配,而else又不能独立存在,所以出现了上述错误。4.2.2嵌套的二分支选择结构

1.在if语句中嵌套分支结构

1)语法形式

if(表达式1)

if(表达式2)语句1

else语句2

else语句3其中:

(1)表达式1、2均可以是任意的表达式;

(2)语句1、2、3均可以是一条简单语句或复合语句;

(3)内层if-else语句书写时注意格式缩进,以培养良好的程序设计风格;

(4)内层if-else结构仍然可以继续嵌套,依此类推。

2)执行过程

首先计算表达式1的值,若表达式1为真则执行内层if-else语句,若表达式1为假则执行语句3。若执行内层if-else语句,则计算表达式2的值,若表达式2为真则执行语句1,若表达式2为假则执行语句2,如图4.3所示。总之,程序必须在语句1、2、3中选择其一来执行。

图4.3if嵌套的分支结构流程图

3)举例

如果一个奇数x能被3整除,则输出“是”,否则输出“否”。程序段如下:

if(x%2!=0) /*条件1,判断x是否为奇数*/

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

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

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

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

若x为6则条件1不满足,执行语句3,输出“no”;若x为5则条件1满足,条件2不满足,执行语句2,输出“no”;若x为9则条件1、条件2均满足,执行语句1,输出“yes”。

2.在else语句中嵌套分支结构

1)语法形式

if(表达式1)

语句1

else

if(表达式2)语句2

else语句3

其中,解释同上。

2)执行过程

首先计算表达式1的值,若表达式1为真则执行语句1,若表达式1为假则执行内层if-else语句。若执行内层if-else语句,则计算表达式2的值,若表达式2为真则执行语句2,若表达式2为假则执行语句3,如图4.4所示。总之,程序必须在语句1、2、3中选择其一来执行。

图4.4else嵌套的分支结构流程图

3)举例

题目同上,如果一个奇数x能被3整除,则输出“是”,否则输出“否”。改用另外一种思路来解决,程序段如下:

if(x%2==0) /*条件1,判断x是否为奇数*/

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

else

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

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

elseprintf("no\n"); /*语句3*/观察发现将嵌套if-else结构移至外层else语句之后,此例与上例的主要变化之处在于表达式1及语句1、语句2的变化,只有改变才能解决问题。可见,同一个问题可以有很多种解决办法,我们要善于开拓思路,推陈出新。如此一来,若x为6则条件1满足,执行语句1,输出“no”;若x为5则条件1不满足,条件2也不满足,执行语句3,输出“no”;若x为9则条件1不满足,条件2满足,执行语句2,输出“yes”。特别说明:

(1)在一个分支结构中,if和else语句均可以同时进行若干层嵌套;

(2)内嵌结构可以是if语句或if-else语句;

(3)当嵌套较多的时候,则程序结构不清晰,if与else的配对容易混淆,这里给大家一个解决办法,从上至下将每个else与距其最近的尚未配对的if进行匹配。

在C语言中还提供了一种多路判定语句switch,在这种结构里可以实现,一个条件符合时程序执行若干条语句。

1.语法形式

switch(表达式)

{case常量表达式1:语句序列1

case常量表达式2:语句序列2

case常量表达式n:语句序列n

default:语句序列n+1

}4.3多分支选择结构…其中:

(1)

switch、case和default是C语言关键字,default是可以缺省的项;

(2)

switch后的表达式必须为整型或字符型表达式;

(3)

case后的常量表达式称为标号,且标号必须互不相同,case与标号之间必须留有空格;

(4)

必要时,某些case标号后的语句序列可以不写,但冒号不可省掉;

(5)语句序列可以是一条也可以是多条,且多条不需组合成复合语句。

2.执行过程

首先计算switch后表达式的值,然后寻找与其相等的case标号,如果找到了则从该case后的语句序列开始执行下去,不再进行判断,直至遇break或switch结构结束;如果没有找到与switch表达式的值相等的case标号,则执行default后的语句序列或退出switch结构(default缺省的情况下)。

这里提到了break,它是一个使程序立即从switch结构或循环中退出的语句,在下一章会详细介绍。具体程序中到底要不要使用break,需要针对实际问题而定。

3.举例

设变量grade是字符型,代表成绩的等级,以下程序段则实现根据学生成绩的等级来输出相应的分数范围:

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");

}执行以上程序段时,若grade的值为A则输出结果是:90~100<换行符>;若grade的值为D则输出结果是:60~69<换行符>;若grade的值超出A~E这五个等级,例如G则输出结果是: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");

}则程序找到一个入口之后会一直执行到switch结束,例如,若grade的值为C,则输出结果是:

70~79

60~69

0~59

error!

显然,后面三行的信息是不需要的,所以实际应用中要善于使用break语句。

要注意的是,A~E是字符常量,其两边一定要加上单引号,否则系统认为是五个变量从而会导致若干错误。

例4.1

从键盘输入三个整数,然后将其中最大的一个输出。

求解最大值是很常见的问题,解决办法也有很多种,下面给出的三种解法与前文讲过的几种二分支选择结构对应,大家可进一步掌握分支结构。4.4程序举例

方法一采用独立的if语句实现。

#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);

}程序的运行结果如下:

pleaseenterthreenumbers:

25,49,3

themaximum:49<回车>

方法二采用if-else语句实现。这里只将以上程序的主体部分(即6、7、8行)进行如下修改:

if(x>y)m=x;

elsem=y; /*隐含条件是(x<=y)*/

if(z>m)m=z;

方法三采用嵌套的if-else语句实现。将第一个程序的主体部分(即6、7、8行)进行如下修改:

if(x>y)

if(x>z)m=x; /*内嵌if-else执行条件是(x>y),本行成立条件是(x>y)&&(x>z)*/

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

else /*隐含条件是(x<=y)*/

if(z<y)m=y; /*内嵌if-else执行条件是(x<=y),本行成立条件是(x<=y)&&(z<y)*/

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

通过以上三种解题方法可以看出,第三个程序显然比前两个要复杂,可读性较差。所以在实际应用中我们要善于思考比较,编写出较为简洁、易读的程序。

例4.2

有一函数:

写一程序,输入x值,输出y值。

本例题既可以用独立的if语句解决,也可以用if-else语句实现。这里仅给出用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);

}编写这段程序的主体部分时,初学者容易写成如下形式:

if(x<0)y=x;

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

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

此种写法首先存在以下两处严重的语法错误:

(1)表达式(0<=x<10)写法错误,必须改成(0<=x&&x<10);

(2)表达式“2x-1”、“3x-11”中的2x和3x系统无法识别,必须改成“2*x-1”、“3*x-11”,因为表达式必须由运算符和操作数组成。

另外,还有两处多余的地方,即:

(1)“if(0<=x<10)”中的大于等于零条件已经隐含了,无需再列出,“if(x<10)”即可;

(2)第三个if语句“if(x>=10)”不必写出,它的条件也已由第二个else隐含实现了。

例4.3

给出一个百分制成绩,要求输出其相应的等级。规定:90分以上为“A”,

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

本例题要求使用switch语句解决。大家知道实际生活中成绩是允许带小数的,比如70.5。假设带一位小数,则可能出现的分数将有近千种,因而用case列出所有的分数情况显然是不可能的,如果是两位小数则情况更要成倍增加。对待较复杂问题,重在寻找规律。我们发现,除了100分,“A”等级分数的十位数字均是9,“B”等级分数的十位数字均是8,依此类推。所以如果能取到成绩的十位数字,问题则只剩下0~10这11种情况,相对要简单得多,实际上因为60分以下均为“E”,所以编程时只要列出5种情况即可。

问题重点就成为了如何取到分数的十位数字,其中一个解决办法就是将分数除以10,取结果的整数部分即可。程序如下:

#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");

}

}

以上程序的运行结果是:

pleaseenteranumberbetween0and100

86.5

thegradeisB仔细考虑后发现,以上程序存在以下两个不足:

(1)如果用户不小心输入了一个不符合常规的分数,比如-6、112等,程序仍会给出一个等级“E”;

(2)本程序的switch中共有5条几近相同的printf()函数组成的语句,显得非常累赘;

针对以上问题,我们将程序改进如下:

#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");

}

运行时如果不小心输入了一个超过范围的数据,则程序会输出出错的信息。

本问题也完全可以用if-else结构来实现,大家可以自己编写练习。

一、选择题

1.为了避免在嵌套的if-else中产生歧义,C语言规定,一般else子句总是与()配对。

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

C.其之后最近的ifD.同一行上的if习题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.执行下面程序时,若从键盘输入5,则输出为()。

main()

{inta;

scanf("%d",&a);

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

else

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论