printf("%d%d%d\n",a,b,c);//按从大到小顺序输出
}
此程序的功能:
把从键盘上输入的按任意次序排列的三个整数转变为按从大到小的次序排列(即a≥b≥c)并输出出来。
●使用if语句的编程举例
编写一个程序,求出一元二次方程ax2+bx+c=0的实数根。
分析:
由初等数学知识可知,一元二次方程的实数根为
,其中a≠0,b2-4ac≥0。
编写程序时,首先需要从键盘上为a、b、c输入3个实数,接着对a==0和b2-4ac<0的特殊情况进行处理(如输出无实根信息并退出运行),然后分别求出x1和x2两个实根。
参考程序如下:
#include
#include
#include
voidmain()
{
doublea,b,c,d,x1,x2;
printf("输入一元二次方程的二次项系数、一次项系数和常数项:
");
scanf("%Lf%Lf%Lf",&a,&b,&c);
if(a==0.0){
printf("此方程不是二次方程!
\n");
exit
(1);//中止程序运行
}
d=b*b-4*a*c;//d作为计算过程中为方便计算而使用的中间变量
if(d<0.0){
printf("此方程没有实数根!
\n");
exit
(1);//中止程序运行
}
if(d==0.0)
x1=x2=-b/(2*a);//具有相同的实数根
else{
x1=(-b+sqrt(d))/(2*a);
x2=(-b-sqrt(d))/(2*a);
}
printf("此方程的两个根为:
%Lf和%Lf\n",x1,x2);
}
二、switch开关语句
●switch语句的概念
在日常生活中,经常会碰到多种选择。
如一个单位需要同时为不同级别的人增加各自不同的工资;一个班主任需要根据学生成绩的不同分数段进行不同的成绩评定(评价)。
这些都需要根据职工级别和学生成绩进行多种不同的选择和操作。
在C语言中就是通过switch语句(开关、分情况)来处理的。
●语句格式
switch(<表达式>){
case<常量表达式1>:
<语句1序列>
case<常量表达式2>:
<语句2序列>
[default:
<语句n序列>]
}
每个case部分称为case子句,其中冒号前面为子句标号,后面为执行语句。
每个switch语句中可以包含多个case子句,当然相应的常量表达式的值各不同;default部分称为default子句,每个switch语句中最多包含一条default子句,该子句也可以被省略。
●语句执行过程
switch语句的执行过程分为以下3步描述。
⏹计算出语句关键字switch后面圆括号内<表达式>的值,假定其值用M表示,若它不是整型,系统将自动舍去其小数部分,只取整数部分作为结果值;
⏹依次计算出每个case子句中常量表达式的值,假定它们的值依次为M1、M2、…,同样若它们的值不是整型,则自动转换为整型;
⏹让M依次同M1、M2、...进行比较,一旦遇到M与某个值相等,则就从对应标号后面的语句序列开始向下执行;在碰不到相等的情况下,若存在default子句,则就执行其冒号后面的语句序列,否则不执行任何操作;当执行到复合语句最后的右花括号时就结束整个switch语句的执行。
注意:
通常在switch语句的每个子句中的语句序列的最后使用break语句,当执行到该语句时立即结束整个switch语句的执行。
●语句格式举例
举例1:
switch(n%3){//表达式为n%3,其值为M
case0:
c0++;break;//0相当于M1
case1:
c1++;break;//1相当于M2
case2:
c2++;break;//2相当于M3
}
举例2:
switch(ch){//表达式为ch,其值为M
case'a':
case'A':
printf("优秀\n");break;//'a'和'A'相当于M1和M2
case'b':
case'B':
printf("良好\n");break;//'b'和'B'相当于M3和M4
case'c':
case'C':
printf("一般\n");break;//'c'和'C'相当于M5和M6
default:
printf("较差\n");//带有default子句
}
●使用switch语句的程序举例
#include
#include
voidmain()
{
intx;
printf("输入0~15之间的一个整数:
");//提示信息
scanf("%d",&x);//输入一个整数到x
if(x<0||x>15){printf("输入数据不正确!
\n");exit
(1);}
switch(x){
case10:
printf("%c",A);break;
case11:
printf("%c",B);break;
case12:
printf("%c",C);break;
case13:
printf("%c",D);break;
case14:
printf("%c",E);break;
case15:
printf("%c",F);break;
default:
printf("%c",x+48);break;//48为数字0的ASCII码
}
printf("\n");
}
程序功能:
首先设定一个整数变量并为它输入0~15之间的一个整数,接着通过开关(分情况)语句输出与之对应的十六进制的数字字符。
●编程举例
根据从键盘上输入的两个整数和一个二目算术运算符求出运算结果。
分析
⏹因需要从键盘输入和向屏幕输出,所以要在程序开始包含stdio.h头文件;
⏹因需要从键盘上输入两个整数,所以需要定义两个整数变量来保存它们,假定为x和y,再定义一个字符变量,假定为op,用来保存从键盘输入的一个二目的算术运算符;
⏹定义一个整数变量保存运算结果,假定用标识符z表示,z=xopy;
⏹程序中只需一个主函数,开始定义变量,接着输入数据,再接着利用switch语句按op的值不同进行相应的计算,最后输出结果。
根据分析编写程序
#include
#include
voidmain(){
intx,y,z;charop;
printf("输入两个整数和一个运算符:
");
scanf("%d%d%c",&x,&y,&op);
switch(op){
case'+':
z=x+y;break;
case'-':
z=x-y;break;
case'*':
z=x*y;break;
case'/':
z=x/y;break;
case'%':
z=x%y;break;
default:
{printf("运算符错!
\n");exit
(1);}
}
printf("%d%c%d=%d\n",x,op,y,z);
}
程序运行结果
输入两个整数和一个运算符:
508/
50/8=6
三、for循环语句
●循环的概念
在日常生活中,有许多事情需要重复来做。
如财务人员需要给每个人计算工资,虽然对每个人来说只计算一次,但对所有人来说就需要重复计算多次,每次计算的方法(或者所采用的规则)都相同。
再如,一个商店每天关门时都需要计算当天销售商品的总金额,可以采用重复计算的方法进行,开始设总额为0,以后每次把一笔销售额累加到总额上,通过重复累加n次,就计算出n笔销售额的总金额。
在C语言中设置有专门用来处理循环问题的语句,包括for、while、do等3种循环语句。
●for循环语句的格式:
for(<表达式1>;<表达式2>;<表达式3>)<语句>
for和后面括号部分称为循环头,后面的语句称为循环体。
●for循环语句的执行过程:
1.计算表达式1的值;
2.计算表达式2的值,假定其值为M,若缺省其值为1;
3.若M为逻辑真则执行循环体,否则结束整个for循环语句的执行过程;
4.计算表达式3的值,紧接着自动转向第2步继续执行下一次循环。
for循环语句的执行过程的图形表示如教材第3章的图3-3所示。
●格式举例
(1)for(i=0;i<5;i++)printf("%d",i*i);//014916
//循环变量i,初值、终值、步长为0、5、1
(2)for(j=1,p=1;j<=M;j++,p*=j);//p=(M+1)!
循环体为空
(3)for(k=1;;){s=k*(k+1);k+=2;if(k>5)break;}
//表达式1、2省略,循环体为复合语句
●语句嵌套
(1)for(i=1;i<5;i++)//i的初、终、步为1、4、1
for(j=1;j<=i;j++)p+=i*j;//j的初、终、步为1、i、1
//若p=0则p=1*1+2*1+2*2+3*1+3*2+3*3+4*1+4*2+4*3+4*4=65
(2)for(i=1;i<=5;i++){
scanf("%d",&x);
for(j=2;j<=3;j++)if(x%j==0)break;
if(j>3)printf("%d",x);//输出不能被2和3整除的x值
}
●使用for循环的程序举例
程序1:
#include
#include
voidmain()
{
intn,x,max,min;//定义变量
printf("输入待处理数据的个数:
");//输入提示
scanf("%d",&n);//输入值赋n
for(;n<=0;){printf("重输(n>=1):
");scanf("%d",&n);}
printf("需要从键盘上输入%d个待处理的数据!
\n",n);//输入提示
scanf("%d",&x);//第1个数据输入到x中
max=min=x;//把x值同时赋给max和min
for(;--n;){//省略表达式1和3
scanf("%d",&x);//输入下一个数据到x
if(x>max)max=x;//较大的数赋给max
if(x}
printf("max:
%d,min:
%d\n",max,min);//输出最大数和最小数
}
处理结果:
假定需处理6个数据,这6个数据为:
48,62,30,24,55,36,则程序运行结果为:
输入待处理数据的个数:
6
需要从键盘上输入6个待处理的数据:
486230245536
max:
62
min:
24
程序2:
#include
voidmain()
{
inta,b;//定义变量
for(a=0,b=1;b<20;a=a+b,b=a+b)//处理过程
printf("%d%d",a,b);
//011235813
printf("%d%d\n",a,b);//2134//输出最后结果
}
程序功能:
此程序的功能是输出一个数列的前若干项,其中第1项为0,第2项为1,以后每一项等于其前两项之和。
如第7项为8,它等于第5项3和第6项5之和。
●利用for循环编程举例
举例1:
编一程序计算出1+22+42+62++502的值。
分析:
此题所给的计算公式是一个和式,它除第一项外,其余项为从2至50的每一个偶数的平方,因此可采用循环累加的方法来计算,即依次把每个数据项(在此为偶数的平方)累加到一个变量中。
设循环变量为i,它的初值、终值和步长应分别为2、50和2,设用于累加的变量为s,它的初值应为和式中的第一项1,因为它不能够通过有规律的循环累加到s上。
在循环体中通过赋值语句每次把i的平方值累加到s上,当循环结束后,s的值就是所求的结果。
根据分析编写出程序如下:
#include
voidmain()
{
inti,s=1;
for(i=2;i<=50;i+=2)s+=i*i;
printf("s=%d\n",s);
}
运行结果:
s=22101
举例2:
由勾股定理可知,在一个直角三角形中,两条直角边a和b与斜边c的关系为a2+b2=c2,编一程序求出每条直角边均不大于30的所有整数组解。
如(3,4,5)、(5,12,13)就是该题的2组解。
分析:
根据题意,需要使用二重循环来解决,设外循环变量用a表示,它的初值、终值和步长应分别取1、30和1,内循环变量用b表示,它的初值、终值和步长应分别取a+1,30和1。
内循环变量的初值若取1,而不是取a+1,则会出现象(3,4,5)和(4,3,5)这样的重复组,为了避免重复组的出现,所以让b从a+1开始,即使第二条直角边大于第一条直角边。
根据分析编写出程序如下:
#include
#include
constintN=30;
voidmain()
{
inta,b;
doublec;//存放斜边的值
for(a=1;a<=N;a++)
for(b=a+1;b<=N;b++){
c=sqrt(a*a+b*b);//sqrt求平方根
if(fabs(c-(int)(c+1e-5))<1e-5)//若斜边同为整数则输出
printf("(%d,%d,%d)\n",a,b,(int)(c+1e-5));
}//由于c为双精度,可能产生误差,不能用c==(int)c比较
}
四、while循环语句
●语句格式
while(<表达式>)<语句>
while(<表达式>)称为循环头,后面紧随的<语句>称为循环体。
while循环和for循环具有类似的功能,都能够通过条件控制循环体重复执行。
所不同的表现在循环头的格式上,在for循环头中有3个表达式,通常第1个表达式为循环变量赋初值,第2个为循环控制条件,第3个为改变循环变量的值(增加或减少)。
而在while循环头中,只有一个表达式,它给出循环控制条件。
●while循环语句的执行过程
(1)计算循环头中表达式的值,假定其值为M;
(2)若M为逻辑值真(非0),则执行循环体,否则结束整个循环的执行;
(3)循环体执行结束后转向第1步继续执行下一次循环。
●格式举例:
(1)while(x<=0)scanf("%d",&x);
//从键盘输入一个常数给x,直到>0止,进入循环前x值<=0
(2)while
(1){s+=i*i;i++;if(s>50)break;}
//每次循环把i平方值累加到s上,直到s的当前值大于50退出
(3)while(i++x=rand()%100;
if(x%2==0)c2++;
if(x%3==0)c3++;
if(x%5==0)c5++;
}//对随机产生的N个100以内的整数,分别统计出被2、3、5整除的个数
●带有while循环的程序举例
#include//支持数据输入和输出
#include//支持随机函数和退出程序运行
#include//支持数学函数运算
voidmain()
{
inti=10;//给i赋值0,用i作循环变量
while(i>0){
inta,j,k;//定义3个整数变量
a=rand()%190+10;//产生一个10-199之间的随机整数送a
k=(int)(sqrt(a)+1e-5);//求出a的平方根,取整后赋给k
for(j=2;j<=k;j++)//判断a是否能被2-k之间的任一数整除
if(a%j==0)break;
if(j>k){printf("%d",a);i--;}//条件成立a是素数(质数),
//否则a是非素数(合数),输出素数,循环变量减1
}
printf("\n");
}
程序功能:
该程序是一个双重循环,外层为while循环,内层为for循环,每执行一遍外循环体可能显示出一个10至199之间的一个素数。
该程序的功能是:
随机产生出10个10~199之间的素数并显示出来。
●使用while循环编程举例
编程举例1:
编一程序求出满足不等式
的最小n值。
分析:
此题不等式的左边是一个和式,该和式中的数据项个数是未知的,也正是要求出的。
对于和式中的每个数据项,对应的通式为
,i=1、2、...、n,所以可采用循环累加的方法来计算出它的值。
设程序中的循环变量为i,它应从1开始取值,每次增加1,直到和式的值不小于5为止,此时的i值就是所求的n;设累加变量为s,在循环体内应把1/i的值累加到s上。
根据以上分析,采用while循环编写出程序如下:
#include
voidmain()
{
inti=0;doubles=0;
while(s<5)s+=(double)1/++i;
printf("n=%d\n",i);
}
编程举例2:
编写一个程序,采用辗转相除法求出两个整数的最大公约数。
分析:
设两个整数分别为a和b,a除以b的整余数为r,若r==0,则表明b能被a整除,则b就是它们的最大公约数,否则,令b赋给a,r赋给b,再接着上述过程,直到整余数r为0时止,此时的b的值就是原有两个整数的最大公约数。
根据分析,采用while循环编写出程序如下:
#include
voidmain()
{
inta,b,r;
printf("请输入两个正整数:
");//输入提示信息
scanf("%d%d",&a,&b);//向a和b输入2个整数
while(a<=0||b<=0){printf("重新输入:
");scanf("%d%d",&a,&b);}
r=a%b;//求出a除以b的整余数
while(r){//通过辗转相除求出a和b的最大公约数
a=b;b=r;
r=a%b;
}
printf("%d\n",b);//输出最大公约数
}
五、do循环语句
●语句格式
do<语句>while(表达式);
do和while保留字之间的部分<语句>为循环体,while保留字后面表达式为循环控制条件。
特点:
是先执行循环体后进行循环条件的判断。
●执行过程
(1)执行一次循环体语句;
(2)计算表达式的值,若为逻辑真(非0)再继续执行下一次循环体,否则结束整个循环执行过程。
●格式举例:
dos+=i++;while(s<100);//循环体为s+=i++;循环条件为s<100
do{scanf("%d",&x);s*=x;}while(--n);//输入的n各整数累乘到s上
●程序举例
程序1:
#include
#defineNM10//定义符号常量NM的值为10
voidmain(){
intx,n=1,c=0;//定义变量并赋