目录
(四)、switch语句中case和default的顺序问题
一、if语句
(一)、if
if语句的语法形式如下:
if ( 表达式 )
语句
表达式成立(为真),则语句执行;表达式不成立(为假),则语句不执行。
注:在C语言中,0为假,非0为真,也就是表达式的结果如果是0,则语句不执行,表达式的结果如果不是0,则语句执行。
例子:
(二)、else
在上述代码中,如果一个数不是奇数,那就是偶数,若给任意一个整数,我们要清楚的判断是奇数还是偶数。我们就需要if...else...语句,语法形式如下:
if ( 表达式 )
语句1
else
语句2
例子:
练习:
(三)、分支中包含多条语句
默认在 if 和 else语句中只能控制一条语句,如果想在if...else...语句中跟多条语句一定要带{ }。
if、else后使用的{ }控制多条语句——也叫程序块,或者复合语句。
代码如下:
(四)、嵌套 if
在if else语句中,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("handsome\n");
else
printf("ugly\n");
return 0;
}
//思考上述代码输出是多少呢?handsonme?ugly?
当我们拷贝到编译器中编译,结果却是什么都不输出,那么为什么会出现这种情况呢?
分析:这就是悬空else的问题,如果有多个if和else,可以记住这样一条规则,else总是跟最接近的if匹配。
开始的代码排版,让else和第一个if语句对齐,让我们误以为else是和第一个if匹配的,当if语句不成立的时候,自然想到的就是执行else子句,打印ugly,但实际上else是和第二个if进行匹配的,这样后边的if...else...语句就是嵌套在第一个if语句中的,如果第一个if语句就不成立,嵌套if和else就没机会执行了,最终什么都不会输出。
如果将代码改成如下就很好理解:
但是如果我们想让else语句确是与第一个if匹配可以将代码改成如下:
只要带上适当的大括号,代码的逻辑就会更加的清晰,因此我们在写代码过程中要注意括号的使用,让代码的可读性更高。
二、关系操作符
C语言用于比较的表达式,称为"关系表达式",里面使用的运算符就称为"关系运算符"。主要有以下6个:
⚪ > 大于运算符
⚪ < 小于运算符
⚪ >= 大于等于运算符
⚪ <= 小于等于运算符
⚪ == 相等运算符
⚪ != 不相等运算符
//例子
x > y;
x < y;
x >= y;
x <= y;
x == y;
x != y;
关系表达式通常返回0或1,表示真假。C语言中,0表示假,所有非零值表示真。
代码如下:
关系表达式常用于if或while结构。
注:相等运算符==与赋值运算符=是两个不一样的运算符,不要混淆。有时候,可能会不小心将==、=误用,容易造成意料之外的结果。
为了规避上述出现的问题,当我们在拿一个变量和一个常量比较是否相等的时候,我们可以将其位置调换,这样我们就可以发现错误及时进行代码调整。
另一个需要避免的错误是:多个关系运算符不宜连用。虽然语法上合法,不会报错,但是通常会达不到想要的结果。关系运算符是从左到右计算的。
i < j < k;
代码如下:
为什么编译器输出的结果跟我们判断的不一样呢?
分析:实际上,多个关系运算符i<j<k是从左到右计算的,所以执行的是(i<j)<k,即不是我们逻辑上认为的保证变量j的值在i和k之间,而是先判断i<j 返回0或1,最终是0或1与变量k进行比较。
如果我们想要判断变量j的值是否在i和k之间,应该使用如下写法:
i < j && j < k;
练习:
三、条件操作符
双目操作符: +、-、*、/、%
单目操作符: ++、--、+、-
三目操作符(条件操作符): 表达式1 ? 表达式2 : 表达式3
条件操作符也叫三目操作符,需要接受三个操作数,语法形式如下:
exp1 ? exp2 : exp3
//exp为表达式
条件操作符的计算逻辑是,如果exp1为真:exp2计算,计算的结果是整个表达式的结果;如果表达式1为假:exp3计算,计算的结果是整个表达式的结果。
例子:
练习:
四、逻辑操作符:!,&&,||
逻辑运算提供逻辑判断功能,用于构建更复杂的表达式,主要有三个运算符。
⚪ !:逻辑取反运算符(改变单个表达式的真假)。
⚪ &&:与运算符,就是并且的意思(两侧的表达式都为真,则真,否则为假。
⚪ ||:或运算符,就是或者的意思(两侧至少有一个表达式为真,则真,否则为假。
注:C语言中,0表示假,非0表示正。
① 逻辑取反运算符 !
代码如下:
注:如果一个局部变量不初始化,它的值是随机值,因此一般建议变量要初始化。而全局变量不初始化,它的值将是固定值为0。
② 与运算符 &&
&& 就是与运算符,也就是并且的意思,&&是一个双目操作符,使用的方法是a&&b,&&两边的表达式只有都为真,整个表达式才为真,否则为假。
代码如下:
③ 或运算符 ||
|| 就是或运算符,也就是或者的意思,||是一个双目操作符,使用的方式是a||b,||两边的表达式只要有一个是真,或者都为真,整个表达式就是真;两边的表达式都为假,才为假。
练习:
④ 短路
短路只存在于逻辑运算符中
C语言逻辑运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为"短路"。
1.对于&&
如前面的代码:
if (month >= 3 && month <=5)
表达式中&&的左操作数是month>=3,右操作数是month<=5,当左操作数month>=3的结果是0的时候,即使不判断month<=5,整个表达式的结果也是0。
所以,对于&&操作符来说,左边操作数的结果是0,右边操作数就不再执行。
2.对于||
如前面的代码:
if (month==3 || month==4 || month==5)
如果month==3,则不用再判断month是否等于4或者5,整个表达式的结果也是1 。
所以,||操作符的左操作数的结果不为0,就无需执行右操作数。
像这种仅仅根据左操作数的结果就能知道整个表达式结果,不再对右操作数进行的运算称为短路求值。
思考:
五、switch语句
除了if语句外,C语言还提供了switch语句来实现分支结构。
switch语句是一种特殊形式的if...else...结构,用于判断条件有多个结果的情况。它把多重的else if改成更易用、可读性更好的形式。 语法形式如下:
switch (exp){
case value1: 语句
case value2: 语句
...
default: 语句
}
根据表达式exp不同的值,执行相应的case分支。如果找不到case对应的值,就执行default分支。
注:switch后的exp必须是整形表达式;case后的值,必须是整型常量表达式。
(一)、if语句和switch语句的对比
case和后边的数字之间必须要有空格;
每一个case语句中的代码执行完成后,需要加上break,才能跳出这个switch语句。
(二)、switch语句中的break
分析:上面代码中我们发现,6除以3本来余数就是0,但是我们发现程序运行的结果多了两行"余数是1""余数是2"的打印。
因为switch语句也是分支效果的,只有在switch语句中使用break才能在跳出switch语句,如果某一个case语句的后边没有break语句,代码会继续往下执行,有可能执行其他case语句中的代码,直到遇到break语句或者switch语句结束。就比如上述代码就执行了case 1、case 2中的语句。
当然,break也不是每个case语句都得有,这得根据实际情况来看。(case是入口,beak是出口)
练习:1
(三)、switch语句中的default
在使用switch语句的时候,我们经常可能遇到一种情况,比如switch后的表达式中的值无法匹配代码中的case语句的时候,这时候要不就不做处理,要不就得在switch语句中加入default子句。
switch (exp){
case value1: 语句
case value2: 语句
...
default: 语句
}
switch后边的exp的结果不是value1,也不是value2......就会执行default子句。
代码如下:
(四)、switch语句中case和default的顺序问题
其实,在switch语句中case语句和default语句是没有顺序要求的,只要你的顺序是满足实际需求的且符合逻辑的就可以。
不过通常情况下是把default子句放在最后处理。