跳转至

三、分支程序设计

本章讲述C语言三大结构之一,分支结构。

关系运算符和逻辑运算

关系运算符

C语言中提供了6种关系运算符,用来组成分支语句的条件判断

运算符 含义
< 小于
> 大于
<= 小于等于
>= 大于等于
== 等于
!= 不等于

这些逻辑运算符都是二元运算,用于对两个数值进行比较,得到0或1,如果条件为真则返回1,否则返回0 同时逻辑运算的两边也可以是表达式,因为所以表达式最后都会产生一个值 例:

int n = (3+4)==(5+2)//条件满足,返回1

逻辑运算

逻辑运算我们在高中数学已经大致了解,这里不做过多解释

这里主要介绍各个逻辑运算在C语言中的符号表示

C语言中有三种逻辑运算 分别是与 或 非

运算符 含义
! 逻辑非
&& 逻辑与
|| 逻辑或

if-else结构

我们在前面留下了一个问题,就是找零计算器中,当商品价格大于手中的现金时,要怎么办 如果有一种方法可以程序执行的两个支路就好了,当一种条件满足时,就执行一条支路,不满足就执行另一条

if-else分支语句提供了双路分支 if-else的基本形式如下

if(a>b){
    printf("a 大于 b");
}else{
    printf("a 不大于 b");
}

如果if后()内的条件为真时,就执行if后面花括号内的内容,否则的话,就执行else后花括号内的内容

简单改变一下之前找零计算器的代码

#include<stdio.h>
int main(){
    int myYuan,myJiao;// 现金的元单位数和角单位数
    int waresYuan,waresJiao;//商品售价的元单位数 角单位数

    printf("please enter two numbers: ");
    scanf("%d%d",&myYuan,&myJiao);//输入现金
    printf("please enter two numbers: ");
    scanf("%d%d",&waresYuan,&waresJiao);//输入商品价格

    int t1 = myYuan*10+myJiao;//将手中现金转化为角单位
    int t2 = waresYuan*10+waresJiao;//将商品价格化为角单位

    int t = t1 - t2;//将两个相同单位的数进行相减
    if(t<0){
        printf("您的钱不够");
    }else{
        //t/10->表示元单位
        //t%10->表示角单位
        printf("应找零%d元%d角",t/10,t%10);//输出结果
    }
}

有这样一个问题,当手里面的现金和商品价格一样,也就是t=0时,就不用找零了,我们可不可以在整出来一个分支,来执行不找零的情况 这里就要用到else if

if(a>b){
    printf("a 大于 b");
}else if(a==b){
    printf("a 等于 b");
}else{
    printf("a 小于 b");
}

这里就形成了一个简单的三路分支,每一个分支执行的条件是不同的 当第一个if后括号内的条件为真时,就执行if后面花括号内的内容 当括号内的条件为假时,判断else if后面括号内的条件是否为真,为真时执行else if后面花括号内的内容 否则的话执行最后的else后面花括号内的内容

显然最后else后面花括号内的内容的执行条件是前面两个条件同时为假

这样的话就可以改变之前的找零计算器的程序(只保留了分支语句部分)

if(t<0){
    printf("您的钱不够");
}else if(t==0){
    printf("您的钱正好够购买商品");
}else{
        printf("应找零%d元%d角",t/10,t%10);//输出结果
}

了解了级联的if else之后,这样我们可以用它来表示数学上面经常遇到的分段函数

f(n) = 2n (n>3); 1 (n==3); -2n (n<3);

if(n>=3){
    m = 2*n;
}else if(n==3){
    m = 1;
}else{
    m = -2*n;
}

假设这样一个场景,需要我们设计一个程序来解决学生成绩的评级问题 输入成绩,根据成绩的范围来给出等级(成绩范围0-100)

假设: 100分为S级 90-100分为A级 80-89分为B级 70-79分为C级 60-69分为D级 60分以下为E级

回想前面提到的if else分支语句的嵌套,通过级联的if else 语句可以满足需求

代码如下

#include<stdio.h>
int main(){
    int n;//定义变量A来表示成绩

    printf("please enter the number: ");
    scanf("%d",&n);//输入成绩

    if(n==100){
        printf("S");//n==100为真时,S级
    }else if(n>=90){//n==100为假,即n小于100(成绩的范围只有0-100),同时n>=90为真时,也就是A级的条件
        printf("A");
    }else if(n>=80){//n>=90为假,即n<90,同时当n>=80时,B级
        printf("B");
    }else if(n>=70){//n<80,同时当n>=70时,C级
        printf("C");
    }else if(n>=60){//n<70,同时当n>=60时,D级
        printf("D");
    }else{//n<60,E级
        printf("E");
    }
}

这样的代码不太简洁,使用switch 句可以直接实现条件多路的分支,程序似乎可以简单一些

switch 语句

switch case 的一般形式为

switch(n){
    case 1:printf("@");break;//当n的值等于1时,程序执行时会直接跳到这里,执行冒号后面的代码,打印“@”符号随后退出整个switch语句
    case 2:printf("#");break;//当n的值等于2时,程序会跳过前面代码直接跳到这里,打印“#”符号,随后退出整个switch语句
    case 3:printf("$");break;
    case 4:printf("^");break;
    default:printf("&");break;//当n的值不等于上面所有值时,程序会直接跳到这里,打印“&”符号,上面的几个分支就都不执行了
}

注意

  1. switch后括号内的n必须为整型表达式或者变量
  2. case 后必须是整型常量表达式
  3. case 后跟一个冒号,后面是0或多条语句
  4. default 不是必须有的,一般放在最后
  5. break 的作用是用来跳出整个switch语句

当switch语句不使用break时,程序执行的顺序将会是这样

switch(n){
    case 1:printf("@");//当n的值等于1时,程序执行时会直接跳到这里,随后执行冒号后面的语句,随后顺序执行后面的所有语句
                       //也就是打印“@ # $ ^ & ”
    case 2:printf("#");//当n的值等于2时,程序会跳过前面代码直接跳到这里,随后执行下面所有的代码
                       ////也就是打印“# $ ^ & ”
    case 3:printf("$");
    case 4:printf("^");
    default:printf("&");break;//当n的值不等于上面所有值时,程序会直接跳到这里,上面的几个分支就都不执行了
                              //也就是直接只打印“&”,随后退出整个switch语句
}

简单来讲,switch语句的底层原理就是,当其中一个case后面的数值与switch后括号内的表达式的值相等时 程序就会跳入那个分支,随后执行冒号后面的所有语句,然后顺着执行所有case还有default后面的语句 如果添加了break语句,程序执行到break时将会跳出switch语句,也就是后面的语句都不执行了

对于break的使用可以按照需求还有思路来选择 一般来讲:

  1. 类似于范围分数评级的需要单一支路执行的程序,就需要都添加break

所以我们可以把前面的程序改进一下:

#include<stdio.h>
int main(){
    int n;//定义变量A来表示成绩

    printf("please enter the number: ");
    scanf("%d",&n);//输入成绩

    switch(n/10){//n/10并不难理解,因为我们的成绩评级都是90-99这样十位数相同的范围,除以十正好得到十位的数值
        case 10:printf("S");break;
        case 9:printf("A");break;
        case 8:printf("B");break;
        case 7:printf("C");break;
        case 6:printf("D");break;
        default:printf("E");break;
    }
}
  1. 如果在多个情况对应一种结果的时候,就可以不加break,把几个相同结果的条件按照顺序写在一起,只在最后一个case后面添加要执行的语句

假如这样一个场景,聪明的小明在写一个数学小测,一共有6道题目,答对4道题目及以上即为优秀,2道或3道题目为良好,1道题目为及格,0道为不及格

简单分析就知道,答对4、5、6道三种为第一种情况,2、3为第二种,1为第三种,0为第四种

可以写出下面程序

#include<stdio.h>
int main(){
    int n;//设置变量表示答对题目
    printf("please enter one number: ");
    scanf("%d",&n);//输入n

    switch(n){
        case 6://n等于6时,会直接跳到冒号后面,然后顺序执行,到了case 4 时,执行打印good,直到看到break,退出switch语句
        case 5://等于5也一样和6
        case 4:printf("good");break;//等于4时,直接跳过来执行打印good,随后跳出switch语句
        case 3:
        case 2:printf("well");break;
        case 1:printf("pass");break;
        case 0:printf("fail");break;
    }
}

通过注释,程序的基本构成可以大概了解 就相当于几个连续的门,无论你跳到任何一个门前,最后都会走到最后一个门,也就是有break的那个case那里

当然,比小明要聪明的你可能会想到,使用if else也可以解决,只需要使用逻辑运算符就可以了 表示优秀条件的表达式为(n==6||n==5||n==4),|| 就是逻辑或的符号,也就是三个条件任意一个为真,整体表达式就为真

逻辑运算的部分本文并没有过多演示,你们可以在实际程序设计中自行发掘掌握

至此,第三章内容结束