C语言学习笔记4
分支结构
分支结构
条件判断
条件判断定义:根据某个条件的成立与否,决定是否执行指定操作

条件判断为真的结果为逻辑值;
真:非0 值(一般用1作为真值)
假:0 值
面试题:
①C语言中,条件表达式(作为分支或者循环条件的表达式)支持任意类型的表达式(包括概关系、逻辑、赋值、算术等),但仅关系表达式和逻辑表达式能表达有意义的条件判断。
②C语言中,条件表达式的结果用非0表示真,0表示假,底层实际用1和0存储真假值。
关系运算符及其表达式
关系运算符及其优先级次序:

关系运算优先级低于算术运算符
举例:
int a = 5, b = 6;
printf("%d\\n", a > 5 != b > 5); // 输出:1
// 解释:先计算a > 5(结果0) 和b > 5(结果1),再比较0 != 1(结果1)
关系表达式
定义:由关系运算符链接两个表达式(操作数)构成的算式,结果为逻辑值(1和0)

逻辑运算符及其表达式
逻辑运算符及其优先级
逻辑运算符用于组合关系表达式或逻辑表达式,构成复合条件:

优先级规则:
1.逻辑运算符: ! (最高)
2.算数运算符:*、/、% 高于 + 、-
3.关系运算符:>,<>=,<=,高于 、!=,==
4.逻辑运算符:&& 高于 ||
5.赋值运算符:=,+=,等(最低)
逻辑表达式真值表

定义:用逻辑运算符连接关系表达式或者逻辑表达式构成的算式,结果为逻辑值(1或0)

面试题: ①表示数num 在1-100之间含边界:num >= && num <=100
②表示数num不在1-100之间:num > 100 || num < 0
逻辑运算符的短路特性
逻辑与( && ):左操作数为假时,右操作数不执行(结果为左操作数结果(假))
逻辑或( || ):左操作数为真时,右操作数不执行(结果为左操作数结果(真))
案例:设4=4,b=5

面试题:
int a = 2, b = 3;
if (!a && b++) // !2 && 3 → 0 && 3 → 0
{
b = 6;
}
printf("%d,%d\\n",a, b); // 2, 3
注意:逻辑运算符的操作数可为任意数字(字符型,实型,指针类型),系统均以0和非0判定真假。例如:
'c' && 'd' 结果为 1 (字符 'c' 'd' 的ASCII码值均为非0 )
用if语句实现分支结构
单分支(if…)
语法:
//复合语句(多语句)需要用{}包裹
if (条件表达式)
{
语句块;
}
// 单语句可省略{},以下两种写法等价
if (条件表达式) 语句;
if (条件表达式)
语句;
流程图:

面试题:
if (条件表达式) 语句1; 语句2;
请选择与上面代码完全一致的写法( A )
A. if (条件表达式) { 语句1; } 语句2;
B. if (条件表达式) { 语句1; 语句2; }
解析:语句2不受if条件控制,无论条件真假都会执行
功能:
条件表达式返回的是逻辑值,如果为真(非0);执行后续语句(块),再执行if语句后的其他语句代码
条件表达式为假(0):跳过后续语句(块),直接执行if语句后的其他代码
案例:计算分段函数
需求:计算并输出下列分段函数的值

流程图:

#include <stdio.h>
int main()
{
int x, y = -2; // 初始化y为x < 0的默认值
printf("请输入一个整数:");
scanf("%d", &x);
// 条件满足时修改y的值
if (x >= 0) y = 2;
printf("x=%d,y=%d\\n", x, y);
return 0
}
运行结果:


案例:求三个数的最大值
需求:从控制台输入a,b,c三个数,输出其中的最大值和最小值。
代码:
#include <stdio.h>
//主函数
int main(int argc, char **argv)
{
//定义变量abc,接受控制输入,通过控制台初始化
int a, b, c;
//定义变量max,min存储最大最小值
int min, max;
printf("请输入三个数:");
scanf("%d%d%d",&a,&b,&c);
//接收a值后再初始化最大最小值
min = max = a;
//求最大值
if (max < b) max = b;
if (max < c) max = c;
//求最小值
if (min > b) min = b;
if (min > c) min = c;
printf("%d,%d,%d中最大值为%d,最小值为%d\\n",a,b,c,max,min);
return 0;
}
运行结果:

注意事项:
局部变量(函数中定义的变量)未赋值前的值是未定的(垃圾值),禁止在赋值前使用(否则结果不可预料):全局变量(函数外部定义的变量)或静态变量会被系统默认为初始化为0。
书写规范建议;
if (flag == 1)可以简化为: if ( flag ) (非0 即真)
if (flag == 0)可以简化为:if (!flag )(0的逻辑值为假)
双分支(if else )
语法:
// 复合语句需用{}包裹
if (条件表达式)
{
语句1; // 条件为真时执行
}
else
{
语句2; // 条件为假时执行
}
// 单语句可省略{},以下两种写法完全等价
if (条件表达式) 语句1;
else 语句2;
if (条件表达式)
语句1;
else
语句2;
核心规则:
else不能单独存在,必须与距离最近的未配对的 if 配对
条件无论真假,必须且执行语句1 或语句2中的一个
流程图:

功能说明:
if else 实现双分支选择,支持嵌套(建议嵌套≤3-4层,保证执行效率)
语句1和语句2均可为单语句或复合语句
案例1:计算分段函数
需求使用双分支实现如下分段函数:

流程图:

代码:
#include <stdio.h>
int main(int argc,char *argv[])
{
// 定义两个变量,x用来接收控制台输入
int x, y;
printf("请输入一个整数:");
scanf("%d", &x);
// 校验
if (x < 0)
y = -2;
else
y = 2;
printf("x=%d,y=%d\\n", x, y);
return 0;
}
案例2:判断闰年和平年
需求输入一个年份,判断其为闰年还是平年
闰年判断条件:(year % 4 == 0 && year %100 != 0 || year % 400 == 0)
代码:
#include <stdio.h>
//主函数
int main(int argc, char **argv)
{
//定义一个变量用来存储年份
int year;
printf("请输入年份:");
scanf("%d",&year);
//判断是否为闰年
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
printf("%d年是闰年!\\n",year);
else
printf("%d年是平年!\\n",year);
return 0;
}
运行结果:

双分支(三目运算符)
语法
:表达式1 ?表达式2 :表达式3;
核心说明:
①表达式1为真→执行表达式2,结果为表达式2的值
②表达式1为假→执行表达式3,结果为表达式3的值
③本质是单语句双分支if 的简写 ,仅适用单语句场景(不能代替复合语句)
示例验证:
a = b > c ? d : e 先执行三目运算符,再赋值(证明三目运算符优先级高于赋值运算符);
b > c && d < e ? 1 : 0 先执行逻辑与,再执三目(证明行三目运算符优先级低于逻辑运
算符);
#include <stdio.h>
int main(int argc,char *argv[])
{
int a = 4, b = 3, c = 2, d = 1, e = 0;
a = b > c ? d : e; // 1
printf("a=%d\\n", a); // a=1
printf("%d\\n",(b>c && d<e ? 1: 0)); // 0 面试题 等价于 ((b>c && d<e) ? 1: 0)
return 0;
}
案例:简化分段函数计算:
#include <stdio.h>
int main(int argc,char *argv[])
{
// 定义两个变量,x用来接收控制台输入
int x, y;
printf("请输入一个整数:");
scanf("%d", &x);
// 三目运算符简化
y = x < 0 ? -2 : 2;
printf("x=%d,y=%d\\n", x, y);
return 0;
}
案例:三目运算符嵌套求三个数最大值
代码:
#include <stdio.h>
int main(int argc,char *argv[])
{
int a,b,c,max,min;
printf("请输入三个整数:\\n");
scanf("%d%d%d", &a, &b, &c);
// 嵌套三目运算符求最大值,先比较a,b,再将比较结果与c比
max = (a > b) ? (a > c ? a : c) : (b > c ? b : c);
// 嵌套三目运算符求最小值,先比较a,b,再将比较结果与c比
min = (a < b) ? (a < c ? a : c) : (b < c ? b : c);
printf("%d,%d,%d中的最大值是%d,最小值是%d\\n", a, b, c, max, min);
return 0;
}
多分支(if else if else )
语法:
// 写法1:嵌套if..else..(不推荐,可读性差)
if (表达式1) 语句1;
else
if (表达式2) 语句2;
…
else
if (表达式n) 语句n;
else 语句n+1;
// 写法2:并列if..else if …else.. (推荐,可读性强)
if (表达式1) 语句1;
else if (表达式2) 语句2;
…
else if (表达式n) 语句n; // 可选
else 语句n+1; // 可选(无匹配条件时执行)
// 注意:复合语句必须用{}包裹起来,单语句可以省略{}
核心规则:
else 为可选部分,根据需求决定是否添加
同一时刻仅满足一个分支(条件判断按顺序执行,找到第一个真条件后执行对应语句,后续不再判断)
流程图:

案例:成绩评级
需求:根据学生成绩(0~100)评级:
成绩>=90 A级
成绩>=80 B级
成绩>=70 C级
成绩<60 D级
代码:
#include <stdio.h>
int main()
{
// 创建一个变量,用来存储学生成绩
int score;
printf("请输入一个整数(0~100):");
scanf("%d", &score);
// 评级
if (score >= 90) printf("A级\\n");
else if (score >= 80) printf("B级\\n");
else if (score >= 60) printf("C级\\n");
else printf("D级\\n");
return 0;
}
运行结果:

if else 结构注意点
1.语句1和语句2均可为复合语句(需要用{}包裹),或空语句(例如if(…);else;)
2.空语句实例:

空语句仅占语法位置,不执行任何操作
if语句的嵌套
语法:
if (条件1)
if (条件2) 语句1; // 条件1和条件2均为真时执行
else 语句2; // 条件1真、条件2假时执行
else
if (条件3) 语句3; // 条件1假、条件3真时执行
else 语句4; // 条件1假、条件3假时执行
流程图:

案例:带输入校验的成绩评级
需求:同多分⽀成绩评级,增加输⼊合法性校验(成绩必须在 0~100 之间)
代码:
#include <stdio.h>
int if_test1()
{
int score;
printf("请输入一个成绩:");
scanf("%d", &score);
// 第一层:输入合法性校验(0~100)
if (score >= 0 && score <= 100)
{
// 第二层:成绩等级校验(嵌套if)
if (score >= 90) printf("A级\\n");
else if (score >= 80) printf("B级\\n");
else if (score >= 60) printf("C级\\n");
else printf("D级\\n");
}
else
{
printf("请输入0~100之间的整数!\\n");
}
return 0;
}
用switch语句实现分支结构
switch 语句专用于实现多分支选择结构(多路分支)适用于条件为离散值(整型、字符型)的场景。
语法:
switch (表达式) // 表达式结果为离散值(int、char、枚举(本质上是整型常量))
{
case 常量表达式1: // 常量表达式:字面量、符号常量或枚举值(不可重复)
语句1;
break; // 跳出switch语句(可选,无则触发穿透)
case 常量表达式2:
语句2;
break;
…
case 常量表达式n:
语句n;
break;
default: // 无匹配case时执行(可选)
语句n+1;
break; // 若default在最后,break可省略,否则必须添加
}
注意:
switch 的{}不可省略(即使只有一个case),case 常量表达式 后面的 语句 ,也可以使用{},一般省略。
case 和 default 的顺序不是一定要固定语法。
表达式和常量表达式之间是等值的(==)判断。
流程图:

核心说明:
①表达式类型限制:结果必须是整型(int、long)或字符型(char),不能是浮点型或字符串。
②case常量唯一性:每个case后的常量表达式值必须不同(否则编译报错),如同一个switch中不能出现两个case2:
③执行顺序:先计算表达式值,匹配对应的case常量表达式并执行后续语句;无匹配时执行default。
④break穿透;若case后无break,执行完当前case语句后会继续执行下一个case,直到遇到break或switch结束。
⑤多case公用语句:多个case可共享同一组执行语句(无需重复编写)
break 穿透示例:
int num = 1;
switch (num)
{
case 1:
printf("A\\n"); // 无break
case 2:
printf("B\\n"); // 有break
break;
case 3:
printf("C\\n");
break;
}
//执行结果 A B
多case共用语句示例:
// 需求:根据月份判断季节(春季:2~4月,夏季:5-7月,秋季:8-10月,冬季:11~1月)
int month = 1;
switch (month)
{
case 2:
case 3:
case 4:
printf("春季\\n");
break;
case 5:
case 6:
case 7:
printf("夏季\\n");
break;
case 8:
case 9:
case 10:
printf("秋季\\n");
break;
case 11:
case 12:
case 1:
printf("冬季\\n");
break;
default:
printf("请输入1~12的月份!");
break; // 此时break可以省略
}
案例:根据等级输出分数段
需求:输入成绩的等级(A,B,C,D),输出对应的百分制分数段;
A级:85-100段
B级:70-84段
C级:60-74段
D级:<60段
其他:错误
代码:
#include <stdio.h>
void switch_test1()
{
// 创建一个char型变量,用来接收输入的等级
char grade;
printf("请输入一个英文字符(A~D):");
scanf("%c", &grade);
getchar(); // 将缓冲区的\\n读走,此时缓冲区为空,方便下次重新输入字符
switch (grade) {
case 'A':
printf("85~100段\\n");
break;
case 'B':
printf("70~84段\\n");
break;
case 'C':
printf("60~69段\\n");
break;
case 'D':
printf("<60段\\n");
break;
default:
printf("错误\\n");
break;
}
return 0;
}
案例:根据分数输出等级
需求:输入百分制成绩(1-100),输出等级:
90-100:A级
80-89:B级
70-79:C级
60-69:D级
其他 :E级
改造方案:将成绩整除10,将逻辑值转换为离散值(90-100→9,10等)
代码:
#include <stdio.h>
int main()
{
int score;
printf("=====成绩等级判断=====\\n");
printf("请输入成绩:");
scanf("%d",&score);
//成绩合法性校验
if (score < 0 || score > 100)
{
printf("请输入0-100以内的数!\\n");
}
else
{
switch (score/10) {
case 10:
printf("A级\\n");
break;
case 9:
printf("A级\\n");
break;
case 8:
printf("B级\\n");
break;
case 7:
printf("C级\\n");
break;
case 6:
printf("D级\\n");
break;
default:
printf("E级\\n");
break;
}
}
return 0;
}
案例:简易计算器
需求:实现两个数的+-*/运算,支持输入运算符,处理除数为0和无效运算符的情况。
#include <stdio.h>
//主函数
int main(int argc, char **argv)
{
//定义三个变量用来存储运算符和运算数
char op;
double num1, num2;
printf("=====简易计算器=====\\n");
printf("请输入两个运算数(用空格或回车分隔):");
//校验输入是否正确
if (scanf("%lf%lf",&num1,&num2) != 2)
{
printf("请正确输入两个运算数!\\n");
while (getchar() != '\\n');
return 1;
}
printf("请输入运算符(+、-、*、/):");
getchar (); //清空缓冲区,放在读取控制输入之前
scanf("%c",&op);
//运算
switch (op) {
case '+':
printf("%.2lf+%.2lf=%.2lf",num1,num2,num1+num2);
break;
case '-':
printf("%.2lf-%.2lf=%.2lf",num1,num2,num1-num2);
break;
case '*':
printf("%.2lf*%.2lf=%.2lf",num1,num2,num1*num2);
break;
case '/':
if (num2 != 0)
printf("%.2lf/%.2lf=%.2lf",num1,num2,num1/num2);
else
printf("错误!除数不能为0!\\n");
break;
default:
printf("错误!运算符无效!");
break;
}
return 0;
}



