C语言基础——分支与循环结构(一)

2023-03-30 00:00:00 语句 执行 代码 表达式 常量
序文
欢迎阅读  霖海岛LHaisland  原创的C语言合集的第六篇文章,本文字数为4535字,全文阅读需要约15分钟。由于笔者能力有限,如有疏漏或错误的地方,希望读者朋友们不吝斧正,谢谢大家。
上篇文章地址:C语言基础——认识C语言(五)
本文开始我们介绍第二章——分支与循环结构中的分支结构

在前文中,我们简单介绍了C语言有三大结构:顺序结构、分支(选择)结构、循环结构,从本章节开始我们对此进行详细介绍。

在这里补充一下顺序结构
顺序结构的程序设计是简单的,只要按照解决问题的顺序写出相应的语句就行,它的执行顺序是自上而下,依次执行
语句:

在C语言中,语句可以分为以下五类:

(1)表达式语句 (2)函数调用语句 (3)控制语句 (4)复合语句 (5)空语句(;)

分支结构(选择结构)
C语言提供了可以进行逻辑判断的语句,由这些选择语句可构成程序的选择结构,也称之为分支结构选择结构用于判断给定的条件,根据判断的结果判断某些条件,根据判断的结果来控制程序的流程。选择结构是结构化程序设计的三种基本结构之一。
C语言中提供了两大选择语句, 分别是ifswitch

if语句

下面我们来从单选择、双选择、多选择来分别阐述if语句的使用方法。

(1)单选择:

if(表达式){  代码块;}后续代码;

解释:如果表达式为真,则执行代码块,否则不执行代码块,执行后续代码。

举例:判断19是否是3的倍数。

显然,19并不是3的倍数,所以printf语句并没有执行。

(2)双选择:


if(表达式){  代码块1;}else{  代码块2;}
解释:如果表达式为真,则执行代码块1,否则执行代码块2
举例:输入一个数,判断其是否能被3整除。若能被3整除,则输出“Yes”,否则则输出“No”。
稍微解释一下这段代码,因为在执行if语句时,首先会计算表达式的值,如果表达式的值为零,语句不会执行,若非零,则执行语句
补充说明一下%——整数求余运算符,在我们之前的文章也提到过。
%是求余运算10%3=1 (10/3=3·······1)。
笔者这里给出的表达式为i%3,所以当我们输入6时,6%3=0,等同于if(0),所以表达式为假,执行代码块2。
这里我们再换一种写法:
这里笔者补全了表达式——i%3==0,也就是说当i%3的结果为0时,执行代码块1,否则执行代码块2。
读者朋友要注意这里的区别。
(3)多选择:


if(表达式1){  代码块1;}else if(表达式2){  代码块2;}else if(表达式3){  代码块3;}else{  代码块4;}
  • 如果表达式1为真,则执行代码块1,否则判断表达式2
  • 如果表达式2为真,则执行代码块2,否则判断表达式3
  • 如果表达式3为真,则执行代码块3,否则执行后else中的代码块4

注:众多的大括号中,只有一个大括号的代码块会被执行。

若前面添加的所有判断条件(else if)都不满足,才会执行else中的内容。

举例:给出一个人的BMI(体质指数)(中国标准),判断他的体质类别是哪一种。

#include <stdio.h>int main(){  int i = ;  scanf("%d", &i);  if (i < 18.5)  {    printf("偏瘦\n");  }  else if (i >= 18.5 && i < 24)  {    printf("正常\n");  }  else if (i >= 24 && i < 28)  {    printf("超重\n");  }  else if (i >= 28 && i < 30)  {    printf("肥胖\n");  }  else if (i >= 30 && i < 40)  {    printf("重度肥胖\n");  }  else  {    printf("极重度肥胖\n");   }  return ;}



以上为示例结果,这里只作为演示,上述代码段可以将i的类型改为float类型,因为笔者使用的int(整形)并不能输入小数(可以输入小数,但是结果错误)。

输入格式也要从%d换成%f。

(4)if嵌套:

if中可以继续嵌套if, else中也可以继续嵌套if。

if (表达式1) {    语句块1;    if (表达式2)     {        语句块2;    }}else {    if (表达式3)     {        语句块3;    }    else     {        语句块4;    }}

举例:

要求用户输入一个分数,根据输入的分数输出对应的等级

80~100  

良好 70~79

及格 60~69

不及格或输入错误 0~59

if需要注意的事项:
(1)当if、else、else if后面的大括号被省略时,条件成立就执行距离条件近的语句。
(2)当if else后面的大括号被省略时, else会自动和距离近的一个if匹配。
(3)C语言中分号(;)也是一条语句,称之为空语句。
(4)如果if else省略大括号,那么后面不能定义变量。

下面进行一些举例:


#include <stdio.h>int main() {      if ()      if (1)      printf("A\n");      else       printf("B\n");      else       if (1)      printf("C\n");      else      printf("D\n");}

读者朋友们可以思考一下这段代码的结果。

根据我们上面叙述过的内容,如果表达式的值为零,语句不会执行,若非零,则执行语句当if else后面的大括号被省略时, else会自动和距离近的一个if匹配。

面对这样的代码,我们可以将相互匹配的if、else打上{}


#include <stdio.h>int main() {      if ()        {        if (1)          printf("A\n");        else           printf("B\n");        }      else         {        if (1)          printf("C\n");        else          printf("D\n");        }}

这样能够更好地理解,也间接展现了一个良好的代码风格的重要性。所以if(0)为假,执行else中的代码块,因为if(1)为真,所以输出C,结果为C。

下面我们再举几个例子

#include<stdio.h>int main(){  int age = 20;  if(age>=18)    printf("成年\n");  else    printf("未成年");  printf("不可以上网吧");}
结果如下:

这里为什么age=20,还不可以上网吧呢?

当if、else、else if后面的大括号被省略时,条件成立就执行距离条件近的语句,所以else控制的只有第9行。

下面我们再举一个例子:

#include<stdio.h>int main(){    if (1 > 2);    {        printf("1 > 2");    }    return ;}
这里我们需要注意,if(1>2)后存在一个;(空语句),所以这里默认省略了大括号,所以if执行距离近的语句,也就是空语句。所以无论if中表达式的条件是否成立,下面的printf不受其影响。结果如下:

下面我们再来举一个例子:


#include<stdio.h>int main(){    int a = 8;    if (a = 10)    {        printf("Test\n");        printf("%d", a);    }    return ;}

请思考输出结果,结果如下:

这里我们需要注意:

“=”:表示赋值运算符,表示将“=”右边的值赋值给左边。

双等号“==”是逻辑判断运算符,表示将“==”左右的值进行比较。

所以当我们遇到比较一个常量等于或者不等于某一个常量的时候,可以将常量放在前面。(良好代码风格)


这样即使没有写双等号,编译器也会报错,来提醒我们。

对if语句的一些补充:

  • if(条件表达式)其后没有分号。一般来说,有"{}"就没有";",有";"就没有"{}"
  • if语句所控制的语句如果是一条语句,我们可以不写大括号。
  • 如果控制的是两条以上的语句,必须加大括号。
  • if语句的控制体没有加大括号是其后跟的一条语句。
建议:永远加上大括号。避免不必要的错误。

该表达式通常是逻辑表达式或关系表达式,但也可以是其它表达式,如赋值表达式等,甚至也可以是一个变量。例如:if(a=5) 语句;if(b) 语句;都是允许的。只要表达式的值为非0,即为“真”。如在:if(a=5)中表达式的值永远为非0,所以其后的语句总是要执行的,当然这种情况在程序中不一定会出现,但在语法上是合法的。

所以请读者朋友们再次注意=和==的区别。
Switch语句:

switch语句也是一种分支语句。常常用于多分支的情况。

当分支过多时,用 if else 处理会不太方便,而且容易出现 if else 配对出错的情况。

switch语句使用格式:

switch (表达式) {case 常量表达式1:    语句1;    break;case 常量表达式2:    语句2;    break;case 常量表达式n:    语句n;    break;default:    语句n + 1;    break;}

语义:

计算"表达式"的值, 逐个与其后的"常量表达式"值相比较,当"表达式"的值与某个"常量表达式"的值相等时, 即执行其后的语句, 然后跳出switch语句
如果"表达式"的值与所有case后的"常量表达式"均不相同时,则执行default后的语句。
示例:实现用户输入一个数字来判断今天是星期几。
#include <stdio.h>int main() {    int a;    printf("Input integer number:");    scanf("%d", &a);    switch (a) {    case 1: printf("Monday\n"); break;    case 2: printf("Tuesday\n"); break;    case 3: printf("Wednesday\n"); break;    case 4: printf("Thursday\n"); break;    case 5: printf("Friday\n"); break;    case 6: printf("Saturday\n"); break;    case 7: printf("Sunday\n"); break;    default:printf("error\n"); break;    }    return ;}

结果示例:

可以看见,当我们输入1时,也就将1赋给了变量a,对应着case1,于是输出了Monday。

当我们输入8时,与所有的case后的常量表达式均不相同,于是执行default下的error。

switch注意事项如下:

switch条件表达式类型必须是整形,或者是可以被提升为整形的值

case的值只能是常量(常量表达式),并且必须是整形或者是可以被提升为整形的值(指char、short)。例如case 'a'。

case的值不能重复,例如在一段switch中出现两个case1。

switch只要与任意一个case匹配后,其他的case和default都会失效。所以case和default后如果没有break就会出现穿透问题。

switch中,default可以省略,default也不需要放在所有的case之后,只有与所有case不匹配后才会执行default。

这里读者朋友们可能会对break、default感到疑惑,现在我们来解释。

break语句(四大跳转语句之一)

break 在一些计算机编程语言中是保留字,其作用大多情况下是终止所在层的循环。在 C语言 的 switch(开关语句)中,break 语句还可用来在执行完一个 case(分支)后立即跳出当前 switch 结构。在某些程序调试过程中则使用break设置断点。

break语句的特点:

  • break如果用于循环是用来终止所在层循环的;
  • break如果用于switch,则是用于终止switch
  • break不能直接用于if,除非if属于循环内部的一个子句;

像这里,当switch(1)已经与case1匹配,所以剩下的case与default失效(不具有匹配效果),内部的语句都会执行,直到遇到break或者将整体的switch语句执行完毕,才会结束。

举例:

当我们在case5后加上break,虽然我们输入的是1,但是遇到了break,在case5的Friday后停了下来。

这里请读者朋友们思考一下,既然我们知道了break的作用,那我们如果想实现输入1-5输出weekday,输入6-7输出weekend,该怎么做呢?

代码如下:

#include <stdio.h>int main(){    int day = ;    switch (day)    {        case 1:        case 2:        case 3:        case 4:        case 5:            printf("weekday\n");            break;        case 6:        case 7:            printf("weekend\n");            break;    }    return ;}

break语句的实际效果是把语句列表划分为不同的分支部分。

良好习惯:在后一个case语句的后面加上一条break语句。(之所以这么写是可以避免出现在以前的后一个case语句后面忘了添加break语句)
当我们下一节说到循环结构时,会再叙述break语句的作用。
default子句
如果表达的值与所有的case标签的值都不匹配怎么办?
其实也没什么,结果就是所有的语句都被跳过而已。
程序并不会终止,也不会报错,因为这种情况在C语言中并不认为是个错误。 
但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢? 
你可以在语句列表中增加一条default子句,
把"default: "写在任何一个case标签可以出现的位置。
当switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。
所以,每个switch语句中只能出现一条default子句。 
但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。

在每个switch语句中都放一条default子句是个好习惯,甚至可以在后边再加一个break。

对switch语句的一些补充:

switch语句也是一个典型的以空间换时间的例子。

Q:那么,我们什么时候用if,什么时候用switch呢?

A:if else if 针对于范围的多路选择;switch 是针对点的多路选择。

至此我们已经了解分支(选择)结构大致内容

由于篇幅有限,下一次内容我们将分享循环结构的内容
如果您在阅读中发现内容错误或者有好的想法以及建议,欢迎在公众号内给我们留言,我将不胜感激!
感谢您能够阅读到这里,我们下次再会!

编辑:   霖海岛LHaisland

审核:   霖海岛LHaisland

图文来源:   霖海岛LHaisland


相关文章