C语言 while(ch = getchar(),
ch != ‘#’) 和 while(ch = getchar() &&
ch != ‘#’) 的区别
C
语言中,while(ch = getchar(),
ch != ‘#’) 和 while(ch = getchar()&&
ch != ‘#’) 这两种写法有本质区别,导致后者不能正确工作。以下是详细解释:👇🏻
1. 运算符优先级问题 🍭
逗号运算符 ,
:🎀
先计算左侧表达式(
ch = getchar()
),再计算右侧表达式(ch != '#'
),最后返回右侧的结果作为整个表达式的值。
逻辑与运算符 &&
:🎀
优先级高于赋值运算符
=
,所以ch = getchar() && ch != '#'
会被解析为:
ch = (getchar() && (ch != '#'))
这会导致:👇🏻
1、先读取一个字符并判断其是否为真(非零)
2、再判断ch != '#'
(此时ch
是未初始化的垃圾值)
3、将两个条件的逻辑与结果赋值给ch
2. 实际行为对比 🍭
(1) 正确写法 ✅:while(ch = getchar(),
ch != ‘#’) 🌈
while(ch = getchar(), ch != '#') {
// 循环体
}
执行顺序:
- 1、调用
getchar()
读取字符并赋值给ch
- 2、检查
ch != '#'
是否为真- 3、若为真则进入循环体
(2) 错误写法 ❎:while(ch = getchar() &&
ch != ‘#’) 🌂
while(ch = getchar() && ch != '#') {
// 循环体
}
- 实际解析为:👇🏻
while(ch = (getchar() && (ch != '#'))) {
// 循环体
}
- 问题:💥
ch
会被赋值为0
或1
(逻辑与的结果),而不是字符本身。ch != '#'
中的ch
在第一次判断时是未定义的(可能为垃圾值)。
3. 示例验证 🍭
假设输入字符
A#
:
- 正确写法 ✅:
- 读取
'A'
→ch = 'A'
→'A' != '#'
为真 → 进入循环- 读取
'#'
→ch = '#'
→'#' != '#'
为假 → 退出循环- 错误写法 ❎:
getchar()
返回'A'
(ASCII 65,非零为真)ch != '#'
中的ch
是未初始化的值(垃圾值)- 逻辑与结果可能是
0
或1
(随机),导致行为不可预测
4. 解决方案 🍭
若想避免逗号运算符,可以改为:👇🏻
while((ch = getchar()) != '#') {
// 循环体
}
- 原理:
- 明确优先级,先赋值再比较。
5. 关键总结 🍭
写法 | 解析顺序 | 赋值结果 | 是否可用 |
---|---|---|---|
while(ch = getchar(), ch != '#') | 先赋值,再比较 | ch =字符 | ✅ 正确 |
while(ch = getchar() && ch != '#') | 先逻辑与,再赋值 | ch =0/1 | ❌ 错误 |
while((ch = getchar()) != '#') | 先赋值,再比较 | ch =字符 | ✅ 推荐 |
最佳实践:使用括号明确优先级,避免依赖运算符优先级规则。❀