【C语言】分支结构——if语句与switch语句

c语言是结构化的程序设计语言,它分为三大结构,分别是是顺序结构、选择结构、循环结构。其中顺序结构是最简单的结构,没多少可讲的,所以本篇我重点来介绍选择结构。                              我们可以使⽤ if 语句、switch语句 实现分⽀结构,下面我将详细解析这两种语句。

目录

1. if语句

1.1 if与else

1.1.1 基本句型

1.1.2 分⽀中包含多条语句

1.1.3 悬空else问题 (if与else的配对)

1.1.4 else if 句型的演变

1.2 关系操作符

1.3 条件操作符(三目运算符)

1.4 逻辑判断

1.4.1 逻辑操作符

1.4.2 经典习题:闰年判断

1.4.3 短路问题

2.switch语句

2.1 if语句和switch语句的对⽐

2.2 省去break的switch语句

2.3 default与case的顺序问题


1. if语句

1.1 if与else

1.1.1 基本句型

一、最简单的句型:

1        if(表达式)   

2             语句;               

在C语⾔中,0为假,⾮0表⽰真所以在if语句中,表达式的结果如果是0,则语句不执⾏表达式的结果如果不是0,则语句执⾏

例⼦1:输⼊⼀个整数,判断是否为奇数(不用判断是不是偶数)

#include <stdio.h>
int main()
{
 int num = 0;
 scanf("%d", &num);

 if(num % 2 == 1)
     printf("%d 是奇数\n", num);
 return 0;
}

该程序的执行逻辑是这样的:


如果⼀个数不是奇数,那就是偶数了,如果任意⼀个整数,我们要清楚的判断是奇数还是偶数怎么表示呢?这⾥就需要 if...else... 语句了,语法形式如下:

二、基本句型:

1        if(表达式)

2                语句1;

3        else

4                语句2;

例子1的延续: 输⼊⼀个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印数偶数

#include <stdio.h>
int main()
{
 int num = 0;
 scanf("%d", &num);

 if(num % 2 == 1)
     printf("%d 是奇数\n", num);
 else
     printf("%d 是偶数\n", num);
 return 0;
}

1.1.2 分⽀中包含多条语句

if语句默认只能控制一条语句。如果要控制多条语句,则需要用 { } 把代码括起来。else语句也是如此

举例:

               

                         //没有{}                                                                        //有{}

左边因为if语句默认控制一条语句,所以即使a不是1,程序还是执行了printf("abc")。

而右边用 { } 括起来后,if语句把下面两条语句都控制住了,所以什么也没有打印。

所以我们有了这种句型:

if(表达式)

{

        ……         //多条语句

}

else

{

        ……        //多条语句

}

1.1.3 悬空else问题 (if与else的配对)

就近原则:如果有多个 if 和 else , else 总是跟最接近的 if 匹配。

我们从下⾯的代码开始讲解:

#include <stdio.h>
int main()
{
     int a = 0;
     int b = 2;
     if(a == 1)
         if(b == 2)
             printf("你好\n");
     else
         printf("hello\n");
 return 0;
}

运行结果是什么?

  • 很多初学者一上来就认为,上边的 if与else在同一条竖直线上,所以就认为它们是配对的。然后发现a是0不是1,不会执行“if(b == 2)”的代码,所以认为最终结果是打印“hello”。

但是这样想是错的,让我们看看最终结果:

结果是什么都没有打印。这说明else没有跟同在竖直线的 if(a == 1) 配对,而是跟最近的 if( b == 2) 配对,这满足就近原则。                                                                                                                         把代码写成这样就好理解了:

int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
    {
        if (b == 2)
			printf("你好\n");
	    else
		    printf("hello\n");
    }
	return 0;
}

1.1.4 else if 句型的演变

  • 在if语句中,if( ) 可以与 else if( ) 连用,构成多重判断

else if句型:          //……省略号处表示多条语句

        if(表达式1)

                { …… } 

        else if(表达式2)

                { …… }

        else

                { …… }

但是else if句型是怎么来的呢?                                                                                                            我们从一个例子寻找答案:输入一个整数,判断它是0,还是正数或者负数

int main()
{
    int n = 0;
    scanf("%d", &n);
    if (n == 0)     //0是正数与负数的分割点
        printf("输入的是0");
    else           //n不是0时,要进一步判断
    {
        if (n > 0)
            printf("输入的是正数");
        else
            printf("输入的是负数");
    }
}

if(表达式)

      语句1;       

else

      语句2;

补充说明:if内部与else内部都只有一条语句时 ,那么这一整个“if……else……”都只是一条语句,而不是多条语句。

既然整个“if (n > 0)  printf("输入的是正数");   else  printf("输入的是负数");”都是一条语句,那我们可以把上面的代码省去一个{},缩写成如下形式:

int main()
{
    int n = 0;
    scanf("%d", &n);
    if (n == 0)     //0是正数与负数的分割点
        printf("输入的是0");
    else           //n不是0时,要进一步判断
        if (n > 0)
            printf("输入的是正数");
        else
            printf("输入的是负数");
}

我们发现第一个else与 if(n > 0) 之间隔了多个空格,而空格属于空白字符,所以一个空格 和 多个空格的作用是一样的。我们把多余的空格删去,就得到了最简便的版本。

这就是else if的演变过程。

1.2 关系操作符

C 语⾔的 关系表达式 中,⾥⾯使⽤的运算符就称 为“关系运算符”(relational operator),主要有下⾯6个。// if()中的表达式是可以进行运算的

  1.  > :⼤于运算符
  2.  < :⼩于运算符
  3.  >= :⼤于等于运算符
  4.  <= :⼩于等于运算符
  5.  == :相等运算符
  6.  !=  :不相等运算符

注意相等运算符 == 与 赋值运算符 = 是两个不⼀样的运算符,不要混淆。有时候,可能会不小心写出下面的代码,它可以运⾏,但会出现意料之外的结果

按理来说,x是等于0的,并不会输出“x是3”这句话,但是为什么会这样呢?                                      原因是这里使用了赋值运算符=,使得x被赋值成3,所以表达式的值最终为3,  而非0代表真,所以程序执行了 “printf("x是3");” 这条语句。改回相等运算符 == 就没事了:

为了防止出现这种错误,我们可以将变量写在等号的右边

如    if (3 == x) ...

1.3 条件操作符(三目运算符)

条件操作符也叫三⽬操作符(这是C语言唯一一个三目运算符),需要接受三个操作数的,形式如下:

exp1 ? exp2 : exp3         // exp表示 表达式

整个条件运算符(exp1 ? exp2 : exp3)运算完后会返回一个值。假设 m =(exp1 ? exp2 : exp3),下面给出m的结果。

        

条件操作符的计算逻辑是:如果 exp1 为真, exp2 计算,计算的结果是整个表达式的结果;如果 exp1 为假, exp3 计算,计算的结果是整个表达式的结果。

用 if 语句展示 ( b = a>5 ? 3 : -3)的计算逻辑:

if (a > 5)
   b = 3;
else
   b = -3;

1.4 逻辑判断

1.4.1 逻辑操作符

逻辑运算符提供逻辑判断功能,⽤于构建更复杂的表达式,主要有下⾯三个运算符。

  •   ! :逻辑取反运算符 (改变单个表达式的真假) 。

  • && :与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。

注意 :在c语音中,表示某个变量在两个数之间时,如1 < x <2 ,不能真的写成数学上的形式,                  而是写成这样 (1 < x && x < 2) 。​

  •  || :或运算符,就是或者的意思(两侧⾄少有⼀个表达式为真,则为真,否则为假)。

1.4.2 经典习题:闰年判断

输⼊⼀个年份year,判断year是否是闰年

闰年判断的规则:

  1. 能被4整除并且不能被100整除是闰年
  2. 能被400整除是闰年
版本1:
int main()
{
	int year = 0;
	scanf("%d", &year);

	if (year % 4 == 0 && year % 100 != 0)
		printf("是闰年\n");
	else if (year % 400 == 0)
		printf("是闰年\n");

	return 0;
}

 我们用 或运算|| 来取代 “if…else if…”可以简化代码:

版本2:
int main()
{
	int year = 0;
	scanf("%d", &year);

	if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
		printf("是闰年\n");

	return 0;
}

1.4.3 短路问题

C语⾔逻辑运算符有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。

如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式进行运算。这种情况称为“短路”

&&的短路:左边为0

逻辑与 中,当左边的表达式已经为假时,右边的表达式不再运算。

 || 的短路:左边为1

 在逻辑或 中,当左边的表达式已经为真时,右边的表达式不再运算。

2.switch语句

除了 if 语句外,C语⾔还提供了 switch 语句来实现分⽀结构。 switch 语句是⼀种特殊形式的 if...else 结构,⽤于判断条件有多个结果的情况。它把多重 的 else if 改成更易⽤、可读性更         好的形式。

switch (表达式)
{
     case value1:        //value为整数值
          ……(语句)    
          break;
     case value2:
          ……(语句)
          break;
     default:
          ……(语句)
}

上⾯代码中,根据表达式不同的值,执⾏相应的 case 分⽀。如果找不到对应的值, 就执⾏ default 分⽀

注意:

  • switch 后的表达式(exp)必须是整型表达式
  • case 后的值,必须是整形常量表达式。(如:1、4、1+3、2*3)
  • 每⼀个 case 语句中的代码执⾏完成后,需要加上 break,才能跳出这个switch语句
  • 关键字switch和case是必需的,关键字break和default是非必需的 (后面会讲)

2.1 if语句和switch语句的对⽐

例子:输⼊任意⼀个整数值,计算除3之后的余数

用 if 语句来实现这样的:

int main()
{
	int n = 0;
	scanf("%d", &n);
	if (n % 3 == 0)
		printf("整除,余数为0\n");
	else if (n % 3 == 1)
		printf("余数是1\n");
	else
		printf("余数是2\n");
	return 0;
}

而用 switch语句实现是这样的:

int main()
{
	int n = 0;
	scanf("%d", &n);
	switch (n % 3)
	{
	case 0:
		printf("整除,余数为0\n");
		break;
	case 1:
		printf("余数是1\n");
		break;
	case 2:
		printf("余数是2\n");
		break;
	}
	return 0;
}

2.2 省去break的switch语句

在前面的代码中,如果我们把所有情况(case)的break都去掉,会发生什么呢?

明明3除以3的余数是0,为什么会把 “余数是1” 和 “余数是2” 都打印出来了呢?

只有在 switch 语句中使⽤ break 才能在跳出 switch 语 句,如果某⼀个 case 语句的后边没有 break 语句,代码会继续玩下执⾏,有可能执⾏其他 case 语句中的代码,直到遇到 break 语句或者 switch 语句结束。

所以该代码从case 0进去,一直执行完case 2的内容才结束。

更通俗的讲,如果我们 把case看作一个房间的入口,把break看作房间的出口,把switch表达式的值看作房间的门牌号。那么当没有出口break时,上下相邻的两个房间是连通的,直到走完整个switch语句才算离开。

2.3 default与case的顺序问题

switch后的表达式中的值 ⽆法匹配 case语句 的时候,这时候要不就不做处理,要不就得在 switch 语句中加⼊ default ⼦句。

default 可以处理 case 外的情况,那default一定要放在最后吗?

答案是否定的,default 语句是没有顺序要求的,只要你的顺序是满足需求的就可以。

不过我们通常是把 default ⼦句放在最后处理的。 


这里可以看出,default 内部没有break的话也是一直往下执行代码,直到遇到其他地方的case或者switch语句结束才离开。


同样的,case后的整形常量表达式也是没有顺序要求的。


好了,C语言的分支结构我已经讲完了,你学会了吗

下一期我将会讲解c语言的循环结构,下期见~~

  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值