【研0自学100天 —— Day 4 分支结构(if、switch、while、for) 】

C语言入门(4/100)

在Day 3的学习,我们对于Day 2 的部分基本语法进行了补充,尤其是针对性地讨论了变量常量运算符号等话题。
Day 4 的学习中,将首次开始接触到简单的结构语句

  • 分支结构 :
    • if 语句
    • if-else 语句:简单、多重、嵌套
    • switch 语句:breakcasedefault

一、结构与语句

1.1 结构

  • 默认情况下,程序运行后,系统会按书写顺序从上至下依次执行程序中的每一行代码。
  • 但显然,这并不能满足我们所有的开发需求
  • 为方便控制程序的运行流程,就涉及到了流程控制结构,不同的流程控制结构可以实现不同的运行流程。
    • 顺序结构
    • 分支结构(选择结构)
    • 循环结构
      在这里插入图片描述

1.2 语句

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

(1)表达式语句(例如 y=x+3;假设变量y和x均已定义)

(2)函数调用语句(MAX(x,y);假设函数MAX()已经定义)

(3)控制语句

(4)复合语句(把多种语句复合在一起形成的语句)

(5)空语句(例如 ;分号本身就可以作为一条语句,称为空语句,至于空语句的作用,后续会讲到 )

无论上述哪一种语句,都必须以分号结束!

今天介绍的分支和循环语句就是控制语句。

1.3 分支结构(单分支)

1.3.1 简单 if 语句

简单 if 条件语句的基本结构如下:

if(表达式)
{
	执行代码块;
}

其语义是:如果表达式的值为真,则执行其后的语句,否则不执行该语句。

if(age >= 18) {
  printf("开网卡\n");
}
printf("买烟\n");

注意

if()后面没有分号,直接写{}

1.3.2 简单 if-else 语句

简单 if-else 语句的基本结构如下:

if(表达式)
{
	执行代码块1;
}
else
{
	执行代码块2;
}

语义是: 如果表达式的值为真,则执行代码块1,否则执行代码块2。
在这里插入图片描述
注意

else 后面也没有分号,直接写{}

#include<stdio.h>
int main()
{
	int n = 0;
	if (n == 0)
	{
		printf("hello\n");
	}
	else
	{
		printf("world\n");
	}
	return 0;
}

最后得到打印结为hello。

1.3.3 多重 if-else 语句

多重 if-else 语句的基本结构如下:

if(表达式1)
{
	执行代码块1;
}
else if(表达式m)
{
	执行代码块m;
}
else
{
	执行代码块n;
}

语义是:依次判断表达式的值,当出现某个值为真时,则执行对应代码块,否则执行代码块n。

注意

当某一条件为的时候,则不会再向下执行该分支结构的其他语句

int main()
{
	int a = 1, b = 0;
	if (a == 1)
	{
		printf("a\n");
	}
	else if (b == 0)  //这里改变了变量
	{
		printf("b\n");
	}
	else
	{
		printf("no\n");
	}
	return 0;

在最后得到打印结果为a
在这里插入图片描述

1.3.4 嵌套 if-else 语句

嵌套 if-else 语句的意思,就是在 if-else 语句中,再写 if-else 语句。
一般形式为:

if(表达式1)
{
	if(表达式2)
	{
		执行代码块2;
	}
	else
	{
		执行代码块3;
	}
}
else
{
	执行代码块4;
}
1.3.5 if 语句注意点
  • if else 后面只有一条语句时, if else 后面的{}可以省略。
// 极其不推荐的写法
    int age = 17;
    if (age >= 18)
        printf("开网卡\n");
    else
        printf("喊家长来开\n");
  • if else 后面的{}被省略时, else 会自动和距离最近的一个 if 匹配。
    如下图所示的代码,请给出输出结果。
    在这里插入图片描述
    最后的打印结果是“hehe”?还是“haha”?
    在此先告诉大家结果,输出结果是空白
     悬空if
    原因就是,else 总是跟最近的 if 进行匹配!
    让我们再看一遍代码。
    在这里插入图片描述

  • 首先对 if(a==1) 进行判断,不成立,然后后面的 if(b==2)else 语句均不执行了

  • 如果进一步优化这段代码,结果就更加清晰了
    在这里插入图片描述
    所以,代码规范很重要!

  • 如果if else省略了大括号, 那么后面不能定义变量

#include <stdio.h>
int main()
{
    if(1)
        int num = 10; // 系统会报错
    printf("number = %i\n", num);
}
#include <stdio.h>
int main()
{
    if(0)
    {
        int num = 10; 
    }
    else
        int value = 20; // 系统会报错
    printf("value = %i\n", value);
}
  • C语言中分号( ; )也是一条语句, 称之为空语句
// 因为if(10 > 2)后面有一个分号, 所以系统会认为if省略了大括号
// if省略大括号时只能管控紧随其后的那条语句, 所以只能管控分号
if(10 > 2);
{
	printf("10 > 2");
}
// 输出结果: 10 > 2

1.4 分支结构(多分支)

1.4.1 switch 语句

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

给出下面的情况,让你写出相应的代码!
输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六
输入7,输出星期日
  • 如果用if …else if 进行多分支的话形式太复杂,代码太过于冗长
  • 因此, switch 就应运而生了,他跟 if else if 互为补充关系。
  • switch 语句的语法形式:
switch(控制表达式)
{
        case 常量: 
        语句;
        case 常量: 
        语句;
        default: 
        语句;
}

  • switch语句后面的()内可以跟整型变量、整型常量、整形表达式(当然这些也可以是字符型,不过字符型的本质仍然是整型),
  • case 后面只能跟整型常量,或者字符型常量,必须是常量
  • const 修饰的常变量是不可以的,因为其本质上仍是变量
  • switch case 条件表达式的类型必须是整型 int, 或者可以被提升为整型的值(charshort);
  • case的值只能是常量, 并且还必须是整型, 或者可以被提升为整型的值(charshort);
  • case 后面常量表达式的值不能相同
  • 常量可以是常数,也可以是常数计算的表达式
1.4.2 switch case 语句
  1. 首先计算表达式的值;
  2. 然后,和case的值依次进行比较,遇到相对应的值就会匹配对应的结果,遇到break,就会退出整个循环;
  3. 如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉

简言之,就是根据表达式的结果,寻找匹配的 case ,并执行 case 后面的语句,一直到 break 为止

  • 如果没有遇到 break ,那就接着执行下面的语句。
    • 如果所有的 case 都不匹配,那么就执行 default 后面的语句;
    • 如果没有 default ,那么程序就什么都不会执行,直接跳过switch case 语句。
switch(表达式){
    case 常量表达式1:
        语句1;
        break;
    case 常量表达式2:
        语句2; 
        break;
    case 常量表达式n:
        语句n;
        break;
    default:
        语句n+1;
        break;
}

在这里插入图片描述

1.4.3 breakcase

首先,说出最终结论

case 相当于支路入口,break 相当于支路出口

break 在程序中是代表 “结束” 的意思
switch 语句中,我们没办法直接实现分支,搭配 break 使用才能实现真正的分支
例如,

#include <stdio.h>
int main()
{
    int day = 0;
    scanf("%d", &day);
    switch (day)
    {
    case 1:
        printf("星期一!");
        break;
    case 2:
        printf("星期二!");
        break;
    case 3:
        printf("星期三!");
        break;
    case 4:
        printf("星期四!");
        break;
    case 5:
        printf("星期五!");
        break;
    case 6:
        printf("星期六!");
        break;
    case 7:
        printf("星期天!");
        break;
    }
    return 0;
}

执行截图:
在这里插入图片描述
如果去掉所有break,运行结果为:
在这里插入图片描述

  • switch语句可以看作是一种基于计算的跳转
  • 计算控制表达式的值后,程序会跳转到相匹配的 case分支标号)处。
    • case(分支标号)只是说明switch内部位置的路标
    • 在执行完分支中的最后一条语句后,如果没有遇到 break ,那就接着执行下面的语句。
      • 直到遇到一个 break 就结束 ,或者直到 switch 语句结束为止。

总结一下,
case 实现的是匹配功能,或者说是判定功能,而break 实现的是分支功能(当然,也可以说break 实现的是退出功能。)

有时候我们的需求变了:

  1. 输入1-5,输出的是“weekday”;
  2. 输入6-7,输出“weekend”;

所以我们的代码就应该这样实现了:

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

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

注意

  1. case 语句的后面不一定非要加break !
  2. 需求不同,代码不同!

switch中只要任意一个case匹配, 其它所有的casedefault都会失效. 所以如果 casedefault 后面没有 break 就会出现穿透问题

#include <stdio.h>
int main()
 {
    int num = 2;
    switch(num)
    {
    case 1:
        printf("星期一\n");
        break;
    case 2:
        printf("星期二\n"); // 被输出
    case 3:
        printf("星期三\n"); // 被输出
    default:
        printf("回火星去\n"); // 被输出
        break;
    }
}
1.4.4 default 子句

如果表达的值与所有的case标签的值都不匹配怎么办呢?

case相当于上帝给你开的门,default 相当于上帝把门都关上了后留下的窗

当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。

  • 每个switch语句中只能出现一条default子句
  • 但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。

  • default 语句可前可后,但我们一般习惯把它放在最后
  • 同时case 最好按照从小到大来排,方便后续代码的查看和修改
    • 最好把执行频率高、容易被匹配的放在前面,在一定程度上能够提高代码的执行效率!
1.4.5 实际操作

实践一下switch 语句:

某学校毕业设计成绩评定等级的规则如下:
成绩 >= 90分,为优秀;
80分 <= 成绩 <90分,为良好;
70分 <= 成绩 <80分,为中等;
60分 <= 成绩 70<分,为及格;
成绩<60分,为不及格。
请编写程序,根据输入成绩,计算并输出成绩评定等级。

代码示例:


#include <stdio.h>
 
int main()
{
    //定义一个grade变量用来存放成绩
	int grade;
    
	printf("请输入您毕业设计的成绩:");
	scanf("%d",&grade);
	   
    //判断输入的成绩是否超过100
	if(grade<=100){
    
    //如果没有超过一百,据题意那就保留十位数部分去掉个位数部分
	grade=grade/10;
    
	switch(grade)
    {
        /* 因为不管是100还是90以上都是:优秀。所以根据switch case 语句的语法
        如果没有遇到 break 那就接着执行下面的语句 */
		case 10:
		case 9:
			printf("恭喜您!您的成绩为:优秀");
			break;
		case 8:
			printf("您的成绩为:良好");
			break;
		case 7:
			printf("您的成绩为:中等");
			break;
		case 6:
			printf("您的成绩为:及格");
			break;
		default :
			printf("很遗憾您的成绩为:不及格\n要加油啊!不要挂科。"); 
	}
	
    }else            //如果输入的数超过100,则输出:输入错误 
    {
		printf("输入错误!"); 
	}
	return 0;
}

运行结果:
在这里插入图片描述


学习参考对象

  1. c语言入门这一篇就够了-学习笔记(一万字)

  2. 13 万字 C 语言从入门到精通保姆级教程2021 年版

  3. 史上最强C语言教程----分支和循环(1)

  4. 史上最强C语言教程----分支和循环(2)

  5. switch语句和case语句的特性

  6. 看完这篇文章,保你学会C语言switch case 语句

  7. C语言程序设计 —— 中国大学mooc

  8. C语言初阶——手把手教零基础/新手入门(万字心得笔记)

  9. 【2023年官方C语言】9小时快速精通C语言,动画讲解C语言视频教程 —— Bilibili

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值