🌈前言
其实c语言是一门结构化的程序设计语言
c语言支持三种结构:
- 顺序结构
- 选择结构
- 循环结构
分支语句
🌈分支语句(选择结构)
1 单分支语句
1.1 if
语法结构:
if (表达式)
语句1;
结构讲解:程序运行至 if 时,如果满足表达式的条件(表达式为真),则进入 if 语句,执行语句1;若不满足(表达式为假),则程序直接跳过 if语句 继续向下执行。
语句1如果只有一条语句时,可以不加大括号,但当语句大于等于两句时,则需加上大括号。
建议:不论语句1包含多少语句,尽量都加上大括号,养成一个良好的习惯,也可以避免一些语法的细节错误(下2.2)
代码示例:
//如果输入小于18岁则打印未成年
#include <stdio.h>
int main ()
{
int age = 0;
scanf("%d",&age)
if (age < 18)
{
printf("未成年\n");
}//如果输入的数小于18才会打印,大于18则直接跳过。
return 0;
}
注:if 语句中,0即为假,非0则为真(负数也为真);但此0非彼0,此0是条件不成立。
2.双分支语句
2.1 if ……else语句
语法结构:
if (表达式)
语句1;
else
语句2;
//双分支语句相较于单分支语句,略有不同
//双分支语句中一定会有一条分支语句执行
结构讲解:程序执行至双分支语句时,如果满足if 语句的表达式的条件 ,则执行语句1,后面的else下的语句2则直接跳过,不予执行;当不满足if 语句的表达式时,则执行else下的语句2。
代码示例:
//当输入年龄小于18时,则输出未成年;否则输入成年。
#include <stdio.h>
int main ()
{
int age = 0;
scanf("%d",&age)
if (age < 18)
{
printf("未成年\n");
}
else
{
printf ("成年\n");
}
return 0;
}//此时输入年龄若大于18,则会弹出成年,若小于18,则会打印未成年。
2.2 if 和 else的关系实质(含悬空else问题)
if 和 else 在代码输入上是两个选择,两个输出的语句,但实质上其实是一条语句,因为最终一定有语句执行,且有且仅有一个语句会执行。
在c语言语法中,else 会和最近的 if 组成一条双分支语句,不论是否缩进。
代码示例:
我想表达的逻辑思路:是当a为1时,且b为2,此时打印hehe;当a不为1时,打印haha。
//反例:
//大家思考一下,下列代码的结果是什么?
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");//(这就是悬空else)
return 0;
}
答案就是,什么都不会输出。
经验教训:上述代码我是想用缩进来表达第二个if 属于上一个if 成立才能执行的语句,但else不会管缩进不缩进,都会和最近的if组成一个双分支语句,因此我们需要将逻辑用代码清楚的表达出来,避免歧义。
修正后:
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
{
if(b == 2)
printf("hehe\n");
}//大括号将之划分作用域
else
{
printf("haha\n");
}//输出即为haha,明确的表达了逻辑
return 0;
}
2.3 return关键字
return关键字相信大家并不陌生,在main函数和自己创建的有返回值的函数等等都能看见return。
return 是与创建的函数的类型遥相呼应的,将一个值返回给所创建的函数,代表着这一段代码运行结束,同时也返回一个值过去。
注:main函数返回0是一个历史遗留的习惯,代表着main函数的正常结束
代码如下:
#include <stdio.h>
int test()
{
int a = 0;
scanf("%d", &a);//用户输入8
if (a > 5)
return 1;
else
return 2;
printf("hehe3\n");
//此处因为if 和else中只能一条语句,且均有返回值,
//所以不论走那一条分支,该语句均不会执行。
}
int main()
{
printf("hehe1\n");//该语句会执行,且在用户输入之前就会打印
int ret = test();//用于接收函数text的返回值
printf("%d\n",ret);//该语句打印结果为 1
printf("hehe2\n");//该语句会在用户输入后执行
return 0;
}
2.4 if语句的书写
代码示例:
我想表达的逻辑是:我给num赋值1,当判断num为5时,则打印hehe;不是则不打印。
int main()
{
int num = 1;
if (num = 5)//不熟悉语法的人将==的判断成了= 的赋值
printf("hehe\n");//此时依旧会打印hehe
//因为num=1,if语句因为写错了,判断语句变成了赋值语句,
//将num从1变成了5,而5为非0,即为真,因此会打印hehe
//但与我想表达的逻辑大相径庭,能够成功打印,是误打误撞
return 0;
}
我们再来看看老6😝的写法:
在语法错误之后一样成功实现逻辑
int num = 1;
if(5 = num)//虽然此处的语法依旧使用错误,但是操作符的左值都是不可修改的
//因此就算语法使用错误,5是常量也不会被赋值为1
{
printf("hehe\n");
}
结论:
- 用代码表达逻辑时,需要代码清晰明了,而不是模棱两可,容易出现歧义。
- 当常量和变量进行比较时,将常量放于左边则不会出现bug
3 多分支语句
1.1 if…else if…else
语法结构:
if (表达式1)
语句1;//表达式1为真,则执行语句1,下面直接跳过;为假则向下判断
else if (表达式2)
语句2;//表达式1为假,表达式2为真,则执行语句2;为假则向下继续判断
……
……
……//根据自己需要判断是否需要更多的else if
else if (表达式n)//(n>2或n=0,当n=0时,则没有此else if)
语句n;
else
语句n+1//当上面所有表达式都为假时,则执行语句体n+1
上述语句依次按顺序判断,且最终依旧只有一个语句能执行。
代码示例:
#include <stdio.h>
int main()
{
int age = 0;
//输入
scanf("%d", &age);//用户输入年龄
if (age < 18)
{
printf("未成年\n");
printf("好好学习\n");
}
else if (age>=18 && age<30)
{
printf("青年\n");
}
else if (age >= 30 && age < 50)
{
printf("中年\n");
}
else if (age >= 60 && age < 90)
{
printf("老年\n");
}
else
{
printf("老寿星\n");
}
return 0;
}
3.2 switch语句
3.2.1 关键字break
switch 语句和if 大相径庭,swich 语句在多分支时,会按照分支顺序,依次执行所有的分支语句,那样其实也就不算分支语句,而只有搭配关键字break时才算真正的实现分支。
语法结构:
switch (整型表达式)//一定注意是整型
{
case 整型常量表达式:
语句1;
break;
default:
语句2;
break;
}
细节讲解:
- 字符也是整型,字符的存储都是以对应的ASCII码值进行存储的,因此字符也属于整型;
- case语句决定了程序代码执行的入口,并且在没有关键字break时,多个case就像一个个隧道一样,依次通过,且多个case可以只执行一个语句,而不是分支语句,只能走一个,因此想实现分支语句的功能必须加上关键字break;
- 关键字break决定了程序的出口,不论是分支语句还是循环语句在执行时碰到break都会直接走出该程序,跳出循环或分支。
代码示例:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch(day)
{
case 1:
case 2:
case 3:
case 4:
printf("工作日\n");
//输入4,本应打印工作日后出程序
//此处因为没有break,因此会继续向下执行;
//还是打印两个工作日
case 5:
printf("工作日\n");
//当输入为1—5,会打印两个工作日
break;//程序的出口
case 6:
printf("星期六\n");
break;//输入6,则打印星期六然后出程序
case 7:
printf("星期天\n");
break;//输入7,则打印星期六然后出程序
default://下详细讲
printf("输入错误\n");
break; //当输入错误时,则打印输入错误,并出程序
}
return 0;
}
注:一般用于点判断,也就是用来判断值,而if多用于范围的判断
3.2.2 default 子句
当用户输入规定范围内的值时,会得到回应,但当输入值与所有的case标签的值都不匹配怎么办?
其实也没什么,结果就是所有的语句都被跳过而已。 程序并不会终止,也不会报错,因为这种情况在C语言中并不认为是个错误。
但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢? 你可以在语句列表中增加一条default子句,说明情况。
语法说明:
- " default:"写在任何一个 case 标签可以出现的位置。 当 switch 表达式的值不匹配所有 case标签的值时,这个 default 子句后面的语句就会执行。 所以,每个switch语句中只能出现一条default子句。
- 但是它可以出现在语句列表的任何位置,而且语句就会像执行一个case标签一样执行default子句。
🏠 文章节束 🏠
如有纰漏还请各位斧正,如果对你有帮助的话还请点个赞支持一下博主,谢谢你!!!
如果有什么疑问或不同的见解,欢迎评论区留言嗷👀