在 C 中执行 OR 操作数有什么问题



当我将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'

当我将 str[i] 与所有元音分开时,它起作用了......

这是因为您正在将字符与布尔表达式进行比较,布尔表达式将是10,这种比较永远不会是真的,str不会有任何带有01代码的字符,这些是不可打印的控制字符。

实际上('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);
}

或者您可以使用弗拉德发布的strchr


附带说明一下,scanf("%[^n]s", str);应该是scanf("%[^n]", str);的,%[^n]说明符不需要在末尾s,如果包含它,则意味着scanf将期望以s结尾的字符串。

根据 C 标准(6.5.14 逻辑 OR 运算符)

3 如果 || 运算符的任一操作数比较,则其应生成 1 不等于 0;否则,它产生 0。结果的类型为 int。

所以这个主表达式在 if 语句的条件内

('a'||'e'||'i'||'o'||'u')

的计算结果始终为整数1,因为至少第一个操作数'a'不等于0

所以实际上这个如果语句

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] ) ) {
//...
}

您可能忘记了应该使用具有两个操作数的运算符,以便编译器可以识别每个操作并将其标记为 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);
}```

相关内容

  • 没有找到相关文章

最新更新