C语言是结构化的程序设计语言,这里的结构指的是顺序结构、选择结构、循环结构,C语言是能够实现这三种结构的,其实我们如果仔细分析的话,我们日常所见的事情都可以拆分为这三种结构或者这三种结构的组合。
我们可以使用if、switch语句实现分支结构,使用for、while、do while语句实现循环结构,顺序结构是最简单的,就是从头到尾写下来,顺下来,其实我们每次写代码都是在写顺序结构,从开头到结尾。OK,简单介绍了一下这三种结构,接下来我们来介绍它们的语句,通过语句来实现它们对应的结构。
一.if语句
1.if
if语句的语法形式:
1 if (表达式)
2 语句
表达式为真或成立,则语句执行,表达式为假或者不成立,则语句不执行。在C语言中,0为假,非0为真,也就是表达式的结果如果是0,则语句不执行,表达式的结果如果不是0,则语句执行。
我们直接上练习理解:输入一个整数判断是否为奇数。
在C语言中一个等号是为赋值,两个等号来进行判断相等。
我们再看图理解一下
2.else
如果一个数不是奇数,那就是偶数了,如果任意一个整数,我们要清楚的判断是奇数还是偶数怎么表示呢?
这里就要用到 if…else…语句了,语法形式如下:
1 if(表达式)
2 语句1
3 else
4 语句2
练习例子:输入一个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印偶数。
记住:在c语言中可以只有if,但不能只有else!!!
一般像学这些语句的,我们多举一些例子来练习理解,我们再来看一个例子:输入一个年龄,大于等于18岁就输出:成年,否则就输出:未成年。
在c语言中大于等于是这样写的:>=,小于等于是这样写的:<=。
3.分支中包含多条语句
其实默认在if和else语句中默认都只控制一条语句,但是如果想要在它们俩下面多加语句的话,就要在它们俩下面加上大括号了,把想加的语句放在大括号里面。
如:
如果我们不加上大括号,会出现什么情况呢?
我们会有一个疑问:它为什么又打印出了不沉迷游戏了呢?
这是因为没有加上大括号,else后面它默认只控制一条语句,那个 printf(“不能沉迷游戏\n”);语句,不受它的控制,这条语句它是独立的,无论是if或者else语句结束的时候都会打印它,就是不管if语句的条件的真假,它都会被执行,所以if或者else语句后面加上多条语句的时候,一定要加上大括号。
if和else后使用{}控制多条语句—这个块也叫:程序块或者复合语句。
4.嵌套if
在if else语句中,else可以与另一个if语句连用,构成多重判断。比如:要求输入一个整数,判断输入的整数是零,还是正数或者负数。请看例子:
可以将if语句嵌套在if或者else语句后面,别忘带大括号。上面的代码else后面大括号其实是一条语句,因为只会执行其中的一条,所以我们也可以将该代码进行简化:
上面那两个代码意思是一样的。再来一个例子:输入一个整数,如果是正数,再判断是奇数还是偶数,并输出,如果不是正数则输出:非正数。
其实在if后面也可以嵌套,我们也可以省略大括号,因为它也只是一条语句,因为只会执行它们其中的一条,语法上也是支持的,但是不太好看,逻辑不够清晰,所以我们写的时候最好带上。
练习:输入一个人的年龄,如果年龄小于18岁,打印"少年",如果年龄在18岁至44岁打印"青年",如果年龄在45岁至59岁打印"中老年",如果年龄在60岁至89岁打印"老年",如果90岁及以上打印"老寿星"。
5.悬空else问题
我们直接来看一个例子,看这段代码运行的结果是什么?
该程序运行结果是无。为什么没有运行结果呢?我们首先要记住一个知识点:else是与最近的if进行匹配的,它们嵌套在第一个if语句中,else并不是与第一个if匹配。所以当第一个if语句条件没有成立的时候,就没有运行结果。
当我们想要第一个if与else匹配的时候,在第一个if后面加上大括号,这个时候第1个if条件不成立,就要打印哈哈了。
我们要知道悬空的else一定是与它离的最近的if进行匹配的,如果想要代码逻辑清晰的话,可以适当的加上大括号,来改变代码的可读性。
推荐书籍规范写代码:高质量的C/C++编程。
二.关系操作符
C语言用于比较的表达式,称为"关系表达式"(relational expression),里面使用的运算符就称为"关系运算符"(relational operator),主要有下面6个。
.>大于运算符
.<小于运算符
.>=大于等于运算符
.<= 小于等于运算符
.== 相等运算符
.!=不相等运算符
关系表达式通常返回0或1,表示真假,这是语法规定的,看例子:
C语言中,0表示假,所有非零值表示真。比如:20>12返回1,12>36返回0。关系表达式常用于if或while结构。注意:相等运算符==与赋值运算符=是两个不一样的运算符,不要混淆,有时候,可能会不小心写出的代码可以运行,但很容易出现意料之外的结果。
例子:当一个变量和常量比较相等的时候,将常量放在等号的左边是好的习惯。
这个时候如果我们将相等运算符与赋值运算符弄错的话会报错。
另一个需要避免的错误是:多个关系运算符不宜连用。如:i < j < k。这个示例中,连续使用两个小于运算符,这是合法表达式,不会报错,但是通常达不到想要的结果,即不是保证变量 j 的值在 i 和 k 之间,因为关系运算符是从左到右计算的,所以实际执行的是下面的表达式。
( i < j )< k
上面式子中,i < j 返回0或1,所以最终是0或1与变量 k 进行比较。如果想要判断变量 j 的值是否在 i 和 k 之间,应该使用这样的写法:i < j && j < k。
实例:
三.条件操作符
条件操作符也叫三目操作符,需要接受三个操作数的,形式如下:
1 exp1 ? exp2 : exp3
条件操作符的计算逻辑:如果exp1为真,exp2计算,计算的结果是整个表达式的结果,如果exp1为假,exp3计算,计算的结果是整个表达式的结果。
上例子:
改造一下
练习:使用条件表达式实现找两个整数中较大值。
四.逻辑操作符
逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。
.!:逻辑取反运算符(改变单个表达式的真假)。
.&&:逻辑与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
.||:逻辑或运算符,就是或者的意思(两侧至少有一个表达式为真,则为真,否则为假)。
注意:C语言中,非0表示真,0表示假。我们来一个一个的介绍。
1.逻辑取反运算符 !
一般是应用到条件为假的时候,要做什么事。如:
2.逻辑与运算符&&
&&就是与运算符,也是并且的意思,&&是一个双目操作符,使用的方法是a&&b,&&两边的表达式都是真的时候,整个表达式才为真,只要有一个是假,则整个表达式为假。
例子:如果我们说月份是3月到5月是春天,该怎么写代码?
3.逻辑或运算符||
那它什么时候用呢?我们来看一个例子:我们说一年中月份是12月或者1月或者2月是冬天,那我们该怎么写代码呢?
练习:闰年的判断。输入一个年份year,判断year是否是闰年。
4.短路
C语言逻辑运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为"短路"。
如前面的代码:
1 if(month >= 3 && month <= 5)
表达式中&&的左操作数是month >= 3,右操作数是 month <= 5,当左操作数 month >= 3 的结果是0的时候,即使不判断 month <= 5,整个表达式的结果也是0(不是春季)。所以,对于**&&操作符**来说,左边操作数的结果是0的时候,右边操作数就不再执行。
对于 || 操作符是怎么样呢?我们结合前面的代码:
1 if(month == 12 || month==1 || month ==2)
如果month == 12,则不用再判断month是否等于1或者2,整个表达式的结果也是1(是冬季)。所以,||操作符的左操作数的结果不为0时,就无需执行右操作数。
像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进行计算的运算称为短路求值。简短总结一下:对于与运算符,左边为假,右边就不算了,对于或运算服符,左边为真,右边就不算了。
练习:
a++是后置++中,先使用,再加加,所以并且左边就是0,那就不用往后看了,这就发生了短路,因为与运算符只要左边有假的,后面就不再计算了。所以答案是1 2 3 4。
该运算符为或运算符,只要左边有正确的后面就不再进行运算了,a=1为真,所以只有a进行了加1。
五.switch语句
除了 if 语句外,C语言还提供了** switch 语句来实现分支语句。switch 语句是一种特殊形式的if…else结构**,用于判断条件有多个结果的情况。它把多重的else if 改成更易用,可读性更好的形式。
1 switch(expression){
2 case value1:statement
3 case value2:statement
4 default:statement
5 }
上面代码中,根据表达式expression不同的值,执行相应的case分支。如果找不到对应的值,就执行default分支。
用一个例子来进行if语句和switch语句的对比:
为什么用switch语句会打印出来这种结果呢?
因为switch语句表达式的值,它只是用于在哪个case分支进去,执行完一个分支之后,它并不会停下来,所以它继续往后打印,除非遇到break。
当我们在case分支后面加break的时候,程序结果就发生了改变。
注意:switch 后的expression 必须是整型表达式,case 后的值,必须是整型常量表达式。
必须是整型表达式,算出来的是整型,字符也可以,因为它对应的ASCII值也是整型。
必须是整型常量表达式。也可以写成1+2,它是一个常量表达式,算出来的结果为整形。如果不这样写会报错:
当我们想要一个case分支执行完成之后,不想要继续往下执行其他情况时,就加上break让它停止。
练习:输入一个1~7的数字,打印对应的星期几
例如:
输入:1 输出:星期一
输入:2 输出:星期二
输入:3 输出:星期三
输入:4 输出:星期四
输入:5输出:星期五
输入:6 输出:星期六
输入:7 输出:星期天
那有没有在后面**不加break情况呢?**当上面的代码需求发生变化时,变为:输入1到5,输出的是工作日;输入6到7,输出休息日。
switch语句中的default
在使用switch语句的时候,我们经常可能遇到一种情况,比如 switch后的表达式中的值无法匹配代码中的case语句的时候,这时候要不就不做处理,要不就得在 switch语句中加入 default子句。
1 switch (expression) {
2 case valuel: statement
3 case value2: statement
4 default: statement
5 }
switch 后边的 expression 的结果不是 value1,也不是value2的时候,就会执行default子句。就比如前面做的打印星期的练习,如果 day 的输入不是1~7的值,如果我们要提示:输入错误,则可以这样完成代码:
switch语句中的case和default的顺序问题
在switch语句中 case 子句和 default 子句有要求顺序吗? default 只能放在最后吗?
其实,在switch语句中case 语句和 default 语句是没有顺序要求的,只要你的顺序是满足实际需求的就可
以。不过我们通常是把 default 子句放在最后处理的。
OK,今天先写到这里,因为写的比较详细,为了方便查看简洁,更好复习,分两章写,不再一口气写完了,后面的部分将在下一个文章里,最近开学没时间调整,没更新,现在规划好了,会不断的持续更新的,非常感谢大家的支持!!!