为什么我不能在 C 中仅使用 1 个相等运算符来检查多个条件?
Why can't I check multiple conditions using only 1 equality operator in C?
在我下面的代码中,a 是一个字符数组,我的 if 语句正在检查特定字符是否为 A
、D
、O
、Q
, R
或 P
。
在if
条件中检查条件的常规方法如下代码所示。
/代码段/
scanf("%s",a);
len=strlen(a);
for(i=0;i<len;i++)
{
if(a[i]=='A'||a[i]=='D'||a[i]=='O'||a[i]=='Q'||a[i]=='R'||a[i]=='P')
//Do something
}
我的疑问:
1) 假设我这样写 if 语句:
if(a[i]=='A'||'D'||'O'||'Q'||'R'||'P')
为什么它的行为方式与我在上面代码片段中的 if 语句的行为方式不同?这个声明是如何工作的?
2) 如果我想检查多个条件(比方说成百上千个条件)怎么办,我怎样才能只使用一个相等运算符进行检查,而不必像这样使用多个相等运算符:
if(a[i]=='A'||a[i]=='D'||a[i]=='O'||a[i]=='Q'||a[i]=='R'||a[i]=='P')
可以吗?如果是,如何?如果不是,为什么?
a[i]=='A'
==
运算符作用于 LHS 和 RHS 上的操作数,所以如果你有
(a[i] == 'A' || 'B' ||......)
然后 ==
将处理 a[i] == 'A'
,如果结果为 TRUE,则其余操作数不会被评估为 (1 || 0 == 1)
答案是您不能使用单个 ==
运算符来检查多个条件。
有两件事要检查,
Operator Precedence,这表明 ==
比 ||
具有更高的优先级
||
运算符本身,它要求[第 6.5.14 章,C99
]
the || operator guarantees left-to-right evaluation; there is
a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.
答案 1)
所以,对于
这样的表达式
if(a[i]=='A'||'D'||'O'||'Q'||'R'||'P')
评价会这样,
if a[i]=='A'
为TRUE,则if
returnsTRUE/成功,其他操作数不求值。
或
if a[i]=='A'
为 FALSE,然后检查下一个操作数 D
[ASCII 值],其计算结果始终为 TRUE。
无论哪种方式,只有 一个 与 a[i]
值进行比较。 ||
的其他操作数只是 values。没有比较。
答案2)
因此您无法使用单个 ==
来检查多个值的(不)相等性。但是,您可以改用 switch
语句。
如果 a[i]
的值与 case
中的 任何 匹配,将执行所需的代码块。
switch (a[i])
case 'A':
case 'D':
case 'O':
case 'Q':
case 'R':
case 'P':
//some code
break;
在 c 中,每个非空值的计算结果都为真。
当你这样写的时候:
if(a[i]=='A'||'D'||'O'||'Q'||'R'||'P')
你可以这样想:
if(a[i]=='A' || true || true , ...)
所以你的陈述永远是正确的!
有更多的可能性可以做这样的检查,这取决于哪一个是最好的:
switch(a[i]) {
case 'A':
case 'D':
case 'O':
case 'Q':
case 'R':
case 'P':
// your if code here
break;
default:
// your else code here
break;
}
或
char check[6] = {'A','D','O','Q','R','P'};
for(int j = 0; j < 6; j++)
if(check[j]==a[i]) {
// your code
break;
}
或者如果您可以对值进行分组:
if(a[i] > 'A' && a[i] < 'D' || a[i] > 'P' && a[i] < 'T') // warning! other values, just for demo!
还有更多。
您可以像这样将您感兴趣的角色添加到数组中:
#include <stdio.h>
int main(){
char a[10] = { 0 };
printf("enter string sequence:");
scanf("%s", a);
int len = sizeof(a)/sizeof(a[0]);
char review[] = { 'A','D','O','Q','R','P' };
int rLen = sizeof(review) / sizeof(review[0]);
int found = 0;
for (int i = 0; i<len; i++)
{
for (int j = 0; j < rLen; j++){
if (a[i] == review[j]){
printf("found atlast !!!");
found = 1;
break;
}
}
if (found == 1)
break;
}
if (found == 0)
printf("Could not be found");
}
通过使用这样的数组:char review[] = { 'A','D','O','Q','R','P' };
,跟踪检查的内容变得非常容易。
并且由于您的代码需要更改要检查的字符,因此您只需在一个地方进行更改。
2) 您可以使用查找 table 通过单次比较来确定字符是否在给定的集合中。这实际上是一些编译器如何实现 isupper
isalpha
和相关的 functions/macros 定义的 <ctype.h>
.
代价是您要么需要手动编写 256 个条目的 table,要么需要代码在运行时填写 table。这还假设您不关心 unicode 字符,因为这会使 table 大很多。
以下代码在启动时初始化 table,并定义一个宏,允许您检查字符是否在集合 {'A', 'D', 'O', 'Q', 'R', 'P'}
中,甚至无需使用一个相等运算符。
#include <stdio.h>
#include <string.h>
#define isSpecial(x) (specialArray[x])
char specialArray[256];
int specialList[] = { 'A', 'D', 'O', 'Q', 'R', 'P', EOF };
int main( void )
{
memset( specialArray, 0, sizeof(specialArray) );
for ( int i = 0; specialList[i] != EOF; i++ )
specialArray[specialList[i]] = 1;
if ( isSpecial( 'A' ) )
printf( "A is special\n" );
else
printf( "A is normal\n" );
if ( isSpecial( 'B' ) )
printf( "B is special\n" );
else
printf( "B is normal\n" );
}
在我下面的代码中,a 是一个字符数组,我的 if 语句正在检查特定字符是否为 A
、D
、O
、Q
, R
或 P
。
在if
条件中检查条件的常规方法如下代码所示。
/代码段/
scanf("%s",a);
len=strlen(a);
for(i=0;i<len;i++)
{
if(a[i]=='A'||a[i]=='D'||a[i]=='O'||a[i]=='Q'||a[i]=='R'||a[i]=='P')
//Do something
}
我的疑问:
1) 假设我这样写 if 语句:
if(a[i]=='A'||'D'||'O'||'Q'||'R'||'P')
为什么它的行为方式与我在上面代码片段中的 if 语句的行为方式不同?这个声明是如何工作的?
2) 如果我想检查多个条件(比方说成百上千个条件)怎么办,我怎样才能只使用一个相等运算符进行检查,而不必像这样使用多个相等运算符:
if(a[i]=='A'||a[i]=='D'||a[i]=='O'||a[i]=='Q'||a[i]=='R'||a[i]=='P')
可以吗?如果是,如何?如果不是,为什么?
a[i]=='A'
==
运算符作用于 LHS 和 RHS 上的操作数,所以如果你有
(a[i] == 'A' || 'B' ||......)
然后 ==
将处理 a[i] == 'A'
,如果结果为 TRUE,则其余操作数不会被评估为 (1 || 0 == 1)
答案是您不能使用单个 ==
运算符来检查多个条件。
有两件事要检查,
Operator Precedence,这表明
==
比||
具有更高的优先级
||
运算符本身,它要求[第 6.5.14 章,C99
]
the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.
答案 1)
所以,对于
这样的表达式if(a[i]=='A'||'D'||'O'||'Q'||'R'||'P')
评价会这样,
if a[i]=='A'
为TRUE,则if
returnsTRUE/成功,其他操作数不求值。
或
if a[i]=='A'
为 FALSE,然后检查下一个操作数D
[ASCII 值],其计算结果始终为 TRUE。
无论哪种方式,只有 一个 与 a[i]
值进行比较。 ||
的其他操作数只是 values。没有比较。
答案2)
因此您无法使用单个 ==
来检查多个值的(不)相等性。但是,您可以改用 switch
语句。
如果 a[i]
的值与 case
中的 任何 匹配,将执行所需的代码块。
switch (a[i])
case 'A':
case 'D':
case 'O':
case 'Q':
case 'R':
case 'P':
//some code
break;
在 c 中,每个非空值的计算结果都为真。
当你这样写的时候:
if(a[i]=='A'||'D'||'O'||'Q'||'R'||'P')
你可以这样想:
if(a[i]=='A' || true || true , ...)
所以你的陈述永远是正确的!
有更多的可能性可以做这样的检查,这取决于哪一个是最好的:
switch(a[i]) {
case 'A':
case 'D':
case 'O':
case 'Q':
case 'R':
case 'P':
// your if code here
break;
default:
// your else code here
break;
}
或
char check[6] = {'A','D','O','Q','R','P'};
for(int j = 0; j < 6; j++)
if(check[j]==a[i]) {
// your code
break;
}
或者如果您可以对值进行分组:
if(a[i] > 'A' && a[i] < 'D' || a[i] > 'P' && a[i] < 'T') // warning! other values, just for demo!
还有更多。
您可以像这样将您感兴趣的角色添加到数组中:
#include <stdio.h>
int main(){
char a[10] = { 0 };
printf("enter string sequence:");
scanf("%s", a);
int len = sizeof(a)/sizeof(a[0]);
char review[] = { 'A','D','O','Q','R','P' };
int rLen = sizeof(review) / sizeof(review[0]);
int found = 0;
for (int i = 0; i<len; i++)
{
for (int j = 0; j < rLen; j++){
if (a[i] == review[j]){
printf("found atlast !!!");
found = 1;
break;
}
}
if (found == 1)
break;
}
if (found == 0)
printf("Could not be found");
}
通过使用这样的数组:char review[] = { 'A','D','O','Q','R','P' };
,跟踪检查的内容变得非常容易。
并且由于您的代码需要更改要检查的字符,因此您只需在一个地方进行更改。
2) 您可以使用查找 table 通过单次比较来确定字符是否在给定的集合中。这实际上是一些编译器如何实现 isupper
isalpha
和相关的 functions/macros 定义的 <ctype.h>
.
代价是您要么需要手动编写 256 个条目的 table,要么需要代码在运行时填写 table。这还假设您不关心 unicode 字符,因为这会使 table 大很多。
以下代码在启动时初始化 table,并定义一个宏,允许您检查字符是否在集合 {'A', 'D', 'O', 'Q', 'R', 'P'}
中,甚至无需使用一个相等运算符。
#include <stdio.h>
#include <string.h>
#define isSpecial(x) (specialArray[x])
char specialArray[256];
int specialList[] = { 'A', 'D', 'O', 'Q', 'R', 'P', EOF };
int main( void )
{
memset( specialArray, 0, sizeof(specialArray) );
for ( int i = 0; specialList[i] != EOF; i++ )
specialArray[specialList[i]] = 1;
if ( isSpecial( 'A' ) )
printf( "A is special\n" );
else
printf( "A is normal\n" );
if ( isSpecial( 'B' ) )
printf( "B is special\n" );
else
printf( "B is normal\n" );
}