在 C 中执行 OR 操作数有什么问题
what is wrong with this execution of OR operand in C
当我将 str[i]
与它工作的所有元音分开时,当前执行有什么问题?
#include <stdio.h>
#include<string.h>
int main() {
int k = 0;
char str[100];
scanf("%[^\n]s", str);
for(int i = 0; i < strlen(str); i++){
if(str[i] == ('a' || 'e' || 'i' || 'o' || 'u')){
k++;
}
}
printf("%d",k);
}
它将 str[i]
与表达式 'a' || 'e' || 'i' || 'o' || 'u'
进行比较,后者的计算结果为 true
,其值等于 1
。将字符视为整数,char
对应于(在 ASCII 中),那么您的表达式将是 97 || 101 || ...
,这肯定是 true
.
要使这项工作按预期进行,您需要拆分所有比较:
str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u'
您可能忘记了应该使用带有两个操作数的运算符,以便编译器可以识别每个操作并将它们标记为 True 或 False。请改用此代码:
int main() {
int k=0;
char str[100];
scanf("%[^\n]s",str);
for(int i=0;i<strlen(str);i++){
if((str[i]== 'a')||(str[i] == 'e')||(str[i] == 'i')||(str[i] == 'o')||(str[i] == 'u')){
k++;
}
}
printf("%d",k);
}```
根据 C 标准(6.5.14 逻辑或运算符)
3 The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
所以这个主表达式在 if 语句的条件内
('a'||'e'||'i'||'o'||'u')
总是计算为整数 1
因为至少第一个操作数 'a'
不等于 0
.
所以实际上这个 if 语句
if(str[i]==('a'||'e'||'i'||'o'||'u')){
相当于
if( str[i] == 1 ){
并且仅在 str[i]
等于 1
.
的一种情况下计算为逻辑真
你需要写
if( str[i] == 'a' || str[i] == 'e'|| str[i] == 'i'|| str[i] == 'o'|| str[i] == 'u' ){
另一种方法是使用标准函数strchr
。例如
if ( strchr( "aeiou", str[i] ) ) {
//...
}
When I separate the str[i] with all the vowels it works...
这是因为您将一个字符与布尔表达式进行比较,该表达式将是 1
或 0
,这种比较永远不会为真,str
不会有任何带有 0
或 1
代码的字符,这些是不可打印的控制字符。
实际上('a'||'e'||'i'||'o'||'u')
相当于(97 || 101 || 105 || 111 || 117)
这些是每个字符的ASCII码为例,其他编码会有不同的代码,这是你的程序真正看到的。
无论如何,这个 OR
的序列将评估为 1
,所以假设 str[i]
是 'a'
,比较结果将是 97 == 1
,这当然是错误的,其他元音也一样,所以k
永远不会递增。
当然,将字符一一分开会起作用,因为每个单独的比较现在都会按预期进行。
如果你不喜欢长 if
你可以使用 :
#include <stdio.h>
#include <string.h>
int main() {
int k = 0;
char str[100];
scanf("%[^\n]", str);
for (int i = 0; i < strlen(str); i++) {
switch(str[i]){
case 'a': case 'e': case 'i': case 'o': case 'u':
k++;
}
}
printf("%d", k);
}
或者您可以使用 Vlad 发布的 strchr
。
附带说明,scanf("%[^\n]s", str);
应该是 scanf("%[^\n]", str);
,%[^\n]
说明符末尾不需要 s
,如果包含它,则意味着scanf
需要一个以 s
.
结尾的字符串
当我将 str[i]
与它工作的所有元音分开时,当前执行有什么问题?
#include <stdio.h>
#include<string.h>
int main() {
int k = 0;
char str[100];
scanf("%[^\n]s", str);
for(int i = 0; i < strlen(str); i++){
if(str[i] == ('a' || 'e' || 'i' || 'o' || 'u')){
k++;
}
}
printf("%d",k);
}
它将 str[i]
与表达式 'a' || 'e' || 'i' || 'o' || 'u'
进行比较,后者的计算结果为 true
,其值等于 1
。将字符视为整数,char
对应于(在 ASCII 中),那么您的表达式将是 97 || 101 || ...
,这肯定是 true
.
要使这项工作按预期进行,您需要拆分所有比较:
str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u'
您可能忘记了应该使用带有两个操作数的运算符,以便编译器可以识别每个操作并将它们标记为 True 或 False。请改用此代码:
int main() {
int k=0;
char str[100];
scanf("%[^\n]s",str);
for(int i=0;i<strlen(str);i++){
if((str[i]== 'a')||(str[i] == 'e')||(str[i] == 'i')||(str[i] == 'o')||(str[i] == 'u')){
k++;
}
}
printf("%d",k);
}```
根据 C 标准(6.5.14 逻辑或运算符)
3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
所以这个主表达式在 if 语句的条件内
('a'||'e'||'i'||'o'||'u')
总是计算为整数 1
因为至少第一个操作数 'a'
不等于 0
.
所以实际上这个 if 语句
if(str[i]==('a'||'e'||'i'||'o'||'u')){
相当于
if( str[i] == 1 ){
并且仅在 str[i]
等于 1
.
你需要写
if( str[i] == 'a' || str[i] == 'e'|| str[i] == 'i'|| str[i] == 'o'|| str[i] == 'u' ){
另一种方法是使用标准函数strchr
。例如
if ( strchr( "aeiou", str[i] ) ) {
//...
}
When I separate the str[i] with all the vowels it works...
这是因为您将一个字符与布尔表达式进行比较,该表达式将是 1
或 0
,这种比较永远不会为真,str
不会有任何带有 0
或 1
代码的字符,这些是不可打印的控制字符。
实际上('a'||'e'||'i'||'o'||'u')
相当于(97 || 101 || 105 || 111 || 117)
这些是每个字符的ASCII码为例,其他编码会有不同的代码,这是你的程序真正看到的。
无论如何,这个 OR
的序列将评估为 1
,所以假设 str[i]
是 'a'
,比较结果将是 97 == 1
,这当然是错误的,其他元音也一样,所以k
永远不会递增。
当然,将字符一一分开会起作用,因为每个单独的比较现在都会按预期进行。
如果你不喜欢长 if
你可以使用 :
#include <stdio.h>
#include <string.h>
int main() {
int k = 0;
char str[100];
scanf("%[^\n]", str);
for (int i = 0; i < strlen(str); i++) {
switch(str[i]){
case 'a': case 'e': case 'i': case 'o': case 'u':
k++;
}
}
printf("%d", k);
}
或者您可以使用 Vlad 发布的 strchr
。
附带说明,scanf("%[^\n]s", str);
应该是 scanf("%[^\n]", str);
,%[^\n]
说明符末尾不需要 s
,如果包含它,则意味着scanf
需要一个以 s
.