一、C语言的基本逻辑结构
C语言程序有3种基本结构:顺序结构、选择结构和循环结构
1)顺序结构:所谓顺序结构,就是从上到下的所有语句都会依次执行
2)选择结构:选择结构中存在一条(或多条)分支语句,当满足分支的条件时语句才会执行,否则不会执行
3)循环结构:循环结构即是在某些条件的控制下重复执行一段代码语句,当满足循环条件时执行循环语句,否则不执行循环语句。
二、选择结构:if-else结构
1、if-else结构使用
if(表达式)-else是最常见的2分支判断选择结构,常见的if()-else有3种形式:
⒈if(表达式)
{
语句块
……
}
⒉if(表达式)
{
语句块1
……
}
else
{
语句块2
……
}
⒊if(表达式1)
{
语句块1
……
}
else if(表达式2)
{
语句块2
……
}
....
else
{
语句块n
}
……
1)if(表达式)
用法:
if(表达式)
{
语句块;
……
}
说明:
当程序执行到if语句时,会判断if()内表达式的真假,若为真,则会执行语句块,否则跳过语句块
示例:
int main()
{
int a = 5;
if(a>0)
{
printf("a大于0\n");//满足if条件,这条语句会执行
}
a = -5;
if(a>0)
{
printf("a大于0\n");//不满足if条件,这条语句不会执行
}
return 0;
}
执行结果:输出一条"a大于0"
2)if(表达式)-else
用法:
if(表达式)
{
语句块1;
……
}
else
{
语句块2;
……
}
说明:
当程序执行到if语句时,会判断if()内表达式的真假,若为真,则会执行if下语句块1;若为假,则会执行else下语句块2
示例:
int main()
{
int a = 5;
if(a>0)
{
printf("a大于0\n");
}
else
{
printf("a小于0\n");
}
a = -5;
if(a>0)
{
printf("a大于0\n");
}
else
{
printf("a小于0\n");
}
return 0;
}
3)多个if(表达式)-else
用法:
if(表达式1)
{
语句块1
……
}
else if(表达式2)
{
语句块2
……
}
……//可使用多个
else//最后一个以else结尾
{
语句块3
……
}
说明:当程序执行到if(表达式1)时,会判断表达式1的真/假。当表达式1为真时,执行语句块1;
否则,执行if(表达式2),会判断表达式2的真/假
依次进行每个if(表达式)的判断
如果以上if(表达式)都为假,则执行最后的else语句后的语句块3
实际上多个if()-else表达式就是使用多个2分分支判断实现了多重分支判断
示例:
程序输入成绩,为0~100之间的整数。之后输出成绩代表的分数段:
90~100为优,80~89为良,70~79为中,60~69为及格,0~59为不及格,其他则输出错误信息
#include<stdio.h>
#include<stdlib.h>
int main()
{
int score;
printf("请输入学生成绩:");
scanf("%d",&score);
if(score<=100 && score>=90)
{
printf("成绩为优\n");
}
else if(score<90 && score>=80)
{
printf("成绩为良\n");
}
else if(score<80 && score>=70)
{
printf("成绩为中\n");
}
else if(score<70 && score>=60)
{
printf("成绩为及格\n");
}
else if(score<60 && score>=0)
{
printf("成绩为不及格\n");
}
else
{
printf("输入非法数据\n");
}
return 0;
}
4)如果if()或者else表达式下未使用{}限制,则只会执行if()或else下的第一条语句。
示例:
#include<stdio.h>
int main()
{
int a = 5;
if(a>0)
printf("a是正数\n");
else
a = -3;
printf("a不是正数\n");
printf("a is %d\n",a);
return 0;
}
程序输出结果:
a是正数
a不是正数
a is 5
尽管在本例中,else下的两句表达式缩进相同(以代表两句都隶属于else语句块)但是由于else后没有{},因此实际上隶属于else的语句只有第一句(即a=-3,如果能执行的话),而printf()语句则会照常执行。因此我们建议使用{}将if()和else后的语句都括起来,以免出现逻辑错误
上面输入成绩输出分数段的示例等价于:
#include<stdio.h>
int main()
{
int score;
printf("请输入学生成绩:");
scanf("%d",&score);
if(score<=100 && score>=90)
printf("成绩为优\n");
else if(score<90 && score>=80)
printf("成绩为良\n");
else if(score<80 && score>=70)
printf("成绩为中\n");
else if(score<70 && score>=60)
printf("成绩为及格\n");
else if(score<60 && score>=0)
printf("成绩为不及格\n");
else
printf("输入非法数据\n");
return 0;
}
练习1:输入3个整数,从小到大输出
答案:
int main()
{
int a,b,c,tmp;//tmp用于交换值的中间变量
scanf("%d %d %d",&a,&b,&c);
if(a>b && a>c)//此时a是最大值
{
tmp = a;
a = c;
c = tmp;
}
else if(b>c && b>a)//此时b是最大值
{
tmp = b;
b = c;
c = tmp;
}
//程序执行到这,c中存的是3个数中最大值,剩下a,b两个数待比较
if(a>b)
{
tmp = a;
a = b;
b = tmp;
}
printf("%d %d %d\n",a,b,c);
return 0;
}
练习2:输入3个正整数作为3条线段的长度,判断这3条线段能否构成三角形。构成三角形的条件是:任意两边之和大于第三边
答案:
#include<stdio.h>
int main()
{
int bian1,bian2,bian3;
int flag=0;//用于标识状态
//flag状态:0能构成三角形、1输入非法数据、2不能构成三角形
printf("请输入三角形的3条边:\n");
scanf("%d%d%d",&bian1,&bian2,&bian3);
if(bian1<=0 || bian2<=0 || bian3<=0)
flag=1;
else if(bian1+bian2<=bian3 || bian1+bian3<=bian2 || bian2+bian3<=bian1)
flag=2;
//程序执行到这里,flag获得状态
if(flag==0)
printf("三条边能构成三角形\n");
else if(flag==1)
printf("输入数据错误\n");
else if(flag==2)
printf("三条边不能构成三角形\n");
return 0;
}
2、if()的嵌套使用
在if()-else语句中又包含一个或多个if()-else语句称为if()的嵌套使用。一般形式如下:
if(表达式1)
{
if(表达式2)
{
语句块1
……
}
else
{
语句块2
……
}
}
else
{
if(表达式3)
{
语句块3
……
}
else
{
语句块4
……
}
}
程序的执行逻辑:
表达式1为真:
表达式2为真:
执行语句块1
否则:
执行语句块2
否则:
表达式3为真:
执行语句块3
否则
执行语句块4
示例:输入一个整数,判断这个整数是正整数、0还是负整数
1)使用多个if()-else
int main()
{
int input;
scanf("%d",&input);
if(input>0)
printf("输入的是正整数\n");
else if(input==0)
printf("输入的是0\n");
else
printf("输入的是负整数\n");
return 0;
}
2)使用if()嵌套
int main()
{
int input;
scanf("%d",input);
if(input>0)
printf("输入的是正整数\n");
else
{
if(input==0)
printf("输入的是0\n");
else
printf("输入的是负整数\n");
}
return 0;
}
练习:输入一个年份(正整数),判断这年是否是闰年
闰年判断标准:年份能被4整除;如若遇到100的倍数,则需判断年份能否被400整除。(逢4一闰,逢百不闰,逢400又闰)
如1900年不是闰年,1904年是闰年,2000年是闰年
答案:
int main()
{
int input;
scanf("%d",&input);
if(input%4==0)
{
if(input%100!=0)
{
printf("%d是闰年\n",input);
}
else if(input%400==0)
{
printf("%d是闰年\n",input);
}
else
{
printf("%d不是闰年\n",input);
}
}
else
{
printf("%d不是闰年\n",input);
}
return 0;
}
3、if()和else的配对
(当没有{}限定的时候)当else与if配对的时候,else总是与它上面最近的未配对的if()结合
if()
if()语句1
else 语句2
if()语句3
else 语句4
在这段程序中,虽然编程人员将else 语句2放在与第一个if()同一缩进上以表示该else与首个if()结合,但实际上这个else是与它的上一个if(即if()语句1)结合。因此在使用if()-else语句(尤其在嵌套使用时)一定要使用{}来限定
三、选择结构:switch-case结构
if()-else语句只能判断2个分支,若要判断多个分支则需要if()-else的多次使用或嵌套使用,十分不便
switch()语句是多分支选择语句。通过switch()的多分支判断可以简便地实现多分支选择结构
switch()语句的一般形式如下:
switch(表达式)
{
case 常量1:
语句1;
break;
case 常量2:
语句2;
break;
……//多个case结构
case 常量n:
语句n;
break;
default:
语句n+1;
}
说明:
1)switch(表达式)表达式的值应是一个整数(包括字符数据)
2)switch()下的{}是一段语句块,这段语句包含若干个以case开头的语句块和至多一个以default开头的语句块
3)case后需要一个常量(或常量表达式),case和default都是标号作用。首先判断switch(表达式)的表达式的值,之后与各个case之后的值进行比对,如果某个case后的值与表达式的值相同,则跳转到此case语句;如果所有的case都不匹配,则跳转到default后的语句
4)可以没有default语句。若没有default语句,则如果没有匹配的case,则程序不执行任何语句
5)各个case之间的先后顺序以及default的位置不影响程序执行结果,不过我们强烈推荐按一定顺序排列case语句,default语句放在最后
6)每个case语句后的常量值必须各不相同,否则会发生互相矛盾现象
7)break语句用来终止switch()语句。如果case语句后没有break语句,则当匹配到合适的case后,程序会一直执行接下来的语句直至遇到break或switch()结束
示例:使用switch()实现:输入一个正整数,输出对应的星期。如输入1代表星期一,输入2代表星期二……输入7代表星期日。输入其他数输出错误信息
#include<stdio.h>
int main()
{
int input;
scanf("%d",&input);
switch(input)
{
case 1:
printf("今天是星期一\n");
break;
case 2:
printf("今天是星期二\n");
break;
case 3:
printf("今天是星期三\n");
break;
case 4:
printf("今天是星期四\n");
break;
case 5:
printf("今天是星期五\n");
break;
case 6:
printf("今天是星期六\n");
break;
case 7:
printf("今天是星期日\n");
break;
default:
printf("输入错误\n");
}
return 0;
}
在示例中,如果去掉所有的break语句,则:
#include<stdio.h>
int main()
{
int input;
scanf("%d",&input);
switch(input)
{
case 1:
printf("今天是星期一\n"); case 2:
printf("今天是星期二\n"); case 3:
printf("今天是星期三\n"); case 4:
printf("今天是星期四\n"); case 5:
printf("今天是星期五\n"); case 6:
printf("今天是星期六\n"); case 7:
printf("今天是星期日\n"); default:
printf("输入错误\n");
}
return 0;
}
程序执行结果:
输入4,输出:今天是星期四 今天是星期五 今天是星期六 今天是星期日 输入错误
练习1:将上文的“输入学生成绩,输出优、良、中、及格、不及格”问题使用switch()语句来实现
答案:
int main()
{
int input;
printf("请输入学生成绩:");
scanf("%d",&input);
if(input>100 || input<0)
printf("输入数据错误!\n");
else
input /= 10;
switch(input)
{
case 10:
case 9:
printf("成绩为优\n");
break;
case 8:
printf("成绩为良\n");
break;
case 7:
printf("成绩为中\n");
break;
case 6:
printf("成绩为及格\n");
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
printf("成绩为不及格\n");
break;
default:
printf("输入非法数据\n");
}
return 0;
}
注意在case 10处,以及case 5~case 0处均没有break,则匹配到这些case后会顺序执行之后的语句直至出现break或switch()语句结束
练习2:运输公司对用户按路程计算费用。路程越远,每吨*千米运费折扣越高。计算运费公式如下:
freight = weight * distance * price * (1-discount);
路程与折扣的关系如下:
s<250:无折扣
250<=s<500:2%折扣
500<=s<1000:5%折扣
1000<=s<2000:8%折扣
2000<=s<3000:10%折扣
3000<=s:15%折扣
要求从键盘输入货运总重(单位吨)、货运路程(单位千米)、每吨*千米货运单价(单位元),输出总花费
答案:
#include<stdio.h>
int main()
{
int distance,c;
float price,weight,discount,freight;
printf("请输入货运总重量:");
scanf("%f",&weight);
printf("请输入货运路程:");
scanf("%d",&distance);
printf("请输入单价:");
scanf("%f",&price);
if(distance>=3000)
c=12;
else
c=distance/250;
switch (c)
{
case 0:
discount=0;break;
case 1:
discount=2;break;
case 2:
case 3:
discount=5;break;
case 4:
case 5:
case 6:
case 7:
discount=8;break;
case 8:
case 9:
case 10:
case 11:
discount=10;break;
case 12:
discount=15;break;
}
freight = price * distance *weight * (1-discount/100);
printf("总运费是%f\n",freight);
return 0;
}