04 (上)C语言的基本逻辑结构——分支结构

一、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;
}

猜你喜欢

转载自blog.csdn.net/qq_34427165/article/details/81209900