昨天内容补充:
scanf的返回值是一个 int 类型,表示成功读取并赋值的数据项数量。
当int i = 12;int j = 45;时,此时返回值为2,输出12 + 45 = 57
在缓冲区会出现
1 | 2 | 4 | 5 | \n |
当int i = 12; int j = abc;时,输入的 j 不是整数,程序会陷入无限循环,不断的打印错误错误提示“Error!Please re-enter”。
原因:此时的返回值ret是1而不是2,从而进入while(ret != 2),此时缓冲区
1 | 2 | a | b | c | \n |
此时12读取成功,所以i= 12,但是失败的abc会残留在输入缓冲区中,下次循环中 scanf 又会再次读取到这些无效字符,导致又一次失败。形成无限循环。
解决办法:使用getchar函数清除缓冲区的残留字符
补充注意:scanf函数可以指定总宽度,不可以指定小数点后的位数。
5.1关系运算符和关系表达式
关系运算符
优先级 | 运算符 | 含义 | 要求运算对象个数 | 结合方向 |
6 | < | 小于运算符 |
2 双目运算符 | 自左向右 |
> | 大于 | |||
<= | 小于等于 | |||
>= | 大于等于 | |||
7 | == | 等于运算符 |
2 双目运算符 | 自左向右 |
!= |
不等于 |
关系表达式
用关系运算符将两个表达式连接起来的式子,称为关系表达式。
关系表达式的类型是整形
在 C 语言中,关系表达式的结果是是一个逻辑值,一个整型,用于表示“真”或“假”。
当关系表达式成立时(条件为真),结果为1。
当关系表达式不成立时(条件为假),结果为0。
例如:5 > 3 的结果是 1(真) 5 == 3 的结果是 0(假)
练习
关系运算符的结合方向是自左向右,
先计算 -4 < i:这里 i = -2,-4 < -2 成立,结果为 1(真)。
再用第一步的结果(1)与 j 比较,即 1 < j:这里 j = 0,1 < 0 不成立,结果为 0(假)。
因此,最终输出的是第二步的结果 0。
在C语言中,连续比较(如 a < b < c)不会像数学中那样表示“a 小于 b 且 b 小于 c”,而是按从左到右的顺序分步计算,可能导致逻辑错误。因此,需避免直接使用连续比较,改用逻辑运算符明确表达条件关系。
5.2逻辑运算符和逻辑表达式
逻辑运算符
优先级 | 运算符 | 含义 | 要求运算对象个数 | 结合方向 |
2 | ! | 逻辑非运算符 |
1 单目运算符· | 自右至左 |
11 | && | 逻辑与运算符 |
2 双目运算符 | 自左至右 |
12 | || | 逻辑或运算符 | 自左至右 |
与或非
逻辑表达式
逻辑表达式的值应该是一个逻辑量“真”或“假”。C 语言中规定逻辑运算结果时,以1代表真,以0代表0;但是判断一个量是否为真时,以0代表假,以非零代表真。
5.3if语句
在C语言中,if语句有三种基本形式:
1. 单分支 if 语句
形式:
if (条件表达式)
{
// 条件为真(非0)时执行的语句块
}
说明:当条件表达式的结果为真(非0值)时,执行{}中的语句块;若为假(0),则跳过该语句块,继续执行后续代码。
2. 双分支 if-else 语句
形式:
if (条件表达式)
{
// 条件为真时执行的语句块
}
else
{
// 条件为假时执行的语句块
}
说明:当条件为真则执行if后的语句块,为假则执行else后的语句块,两者不会同时执行。
练习:(1)输入三个整数,判断三个数中的最大值并输出最大值。
(2)输入一个年份和月份,输出给月份的天数
3. 多分支 if-else if-else 语句
形式:
if (条件1)
{
// 条件1为真时执行
}
else if (条件2)
{
// 条件1为假、条件2为真时执行
}
else if (条件3)
{
// 前两个条件为假、条件3为真时执行
}
// ... 可多个else if
else
{
// 所有条件都为假时执行(可选)
}
说明:从第一个条件开始判断,一旦某个条件为真,执行对应语句块后跳出整个结构;若所有条件都为假,执行else语句块(若有)。
练习:输入一个字符,如果输入的字符为26个英文字母,则输出相应的英文字母,如果输入的字符为0到9的整数,则输出相应的整数,输出其他字符,则输出“其他”。
在使用 if 语句时的注意事项:
1. 条件表达式的正确性: 避免赋值运算符 = 误用为比较运算符 ==:
错误写法:if (a = 5)(实际是赋值,条件恒为真)
正确写法:if (a == 5)(判断是否相等)
注意浮点数比较:由于精度问题,避免直接用 == 比较浮点数,可通过判断差值是否小于极小值(如 if (fabs(a - b) < 1e-6))。
2. 语句块的括号 {} 使用:单行语句也建议加括号:即使 if 或 else 后只有一行代码,加上 {} 可避免后续添加代码时因缩进错误导致的逻辑问题。
3. else 的匹配规则:else 总是与最近的未匹配 if 配对:避免因缩进错误误解逻辑。
5.4switch语句
switch 语句是C语言中用于多分支选择的控制结构,适用于根据一个表达式的值从多个选项中选择执行对应的代码块,比多个 if-else 结构更简洁清晰。
基本语法
switch(表达式)
{
case 常量1:
// 当表达式的值等于常量1时执行的代码
break; // 跳出switch语句
case 常量2:
// 当表达式的值等于常量2时执行的代码
break;
// ... 更多case分支
default:
// 当表达式的值与所有case常量都不匹配时执行的代码(可选)
break;
}
关键特点
1. 表达式要求:表达式的结果必须是整数类型(int、char、枚举等,不能是浮点数或字符串)。
2. case 常量:case 后必须跟常量(如字面量 1、'+',或 #define 定义的宏),且不能重复。
3. break 语句:用于跳出 switch 语句,若省略,会继续执行下一个 case 的代码(称为“穿透”),需根据需求决定是否使用(有时可利用穿透特性简化代码)。
4. default 分支:可选,当所有 case 都不匹配时执行,通常放在最后,可省略 break(但建议加上,保持一致性)。
注意事项:(1)避免在 case 后使用变量或表达式作为常量(如 case a + 1: 是错误的)。
(2)若多个 case 需要执行相同代码,可利用穿透特性合并(省略中间 break):
case 'A':
case 'B': // A和B执行相同代码
printf("合格");
break;
练习: