C++ 多条件语句

C++ 多条件语句,c++,c,if-statement,C++,C,If Statement,我想知道在C/C++中如何处理多个条件。我有一些代码可以很好地工作,但我担心这涉及到运气因素,我不想被发现。考虑: if ( (/*condition1*/) || (/*condition containing invalid reference*/) ) { // do something } 只要“条件1”为真,第二个条件似乎不会产生错误,即使条件本身会产生故障。例如: int main() { char string1[] = "StackOverflow";

我想知道在C/C++中如何处理多个条件。我有一些代码可以很好地工作,但我担心这涉及到运气因素,我不想被发现。考虑:

if ( (/*condition1*/) || (/*condition containing invalid reference*/) )
{
    // do something
}
只要“条件1”为真,第二个条件似乎不会产生错误,即使条件本身会产生故障。例如:

int main()
{
    char    string1[] = "StackOverflow";
    char    *string2 = 0;

    // (1) This will work because string1 is valid
    if (strlen(string1) != 0)
        printf("%s", string1);

    // (2) This will cause an error
    if (strlen(string2) != 0)
        printf("%s", string2);

    // (3) But this if(OR) works fine
    if ((strlen(string1) != 0)||(strlen(string2) != 0))
        printf("no problem!");

    // (4) And of course this doesn't
    if ((strlen(string2) != 0)||(strlen(string1) != 0))
        printf("I don't believe it!");

    return 0;
}
它可以通过一个或条件列表看到,if()的'question'在第一个TRUE语句处停止,从左到右读取,不管后面发生什么。但是,将编号(3)更改为:

尽管第一个条件为false,但仍将失败,从而使整个事件变为false-即问题不会像或示例那样停止

概括而言,我观察到以下几点:

if ( (TRUE) or (INVALID) )   -> no problem

if ( (FALSE) or (INVALID) )  -> error

if ( (TRUE) and (INVALID) )  -> error

if ( (FALSE) and (INVALID) ) -> error    // see the EDIT
这些结果在所有情况下都是通用的,还是依赖于编译器/平台

我是否可以按照上述规则编写代码,或者我是否应该永远不要陷入其中一个条件无效的情况

我正在为我的老板检查一些旧代码,上面到处都是类似(3)的例子。捕获它们并修改代码以避免任何无效条件需要相当长的时间。虽然(3)和(4)可以很容易地调整为位于
if(string2!=0){/}
块中,但对于我所拥有的代码来说,实际上并不容易

编辑:

由于再次检查,
if((FALSE)和(INVALID))
确实运行无误。我不知道为什么以前失败了;如果它一开始起作用,我甚至可能不会提出这个问题。我会把这归咎于巫术和注意力不集中

最终,虽然答案已经被暗示,但没有被逐字确认,但这种对短路评估的依赖(感谢维基链接!)似乎是一种合法的技术。我很高兴我不必重新编写任何代码

    if (strlen(string2) != 0)
    printf("%s", string2);
此处
string2
不是字符串,因此
strlen
调用调用未定义的行为

if ((strlen(string1) != 0)||(strlen(string2) != 0))
在C语言中,
|
运算符的左操作数的计算结果为
1
时,保证不计算右操作数。这里,
|
的左操作数的计算结果为
1
,因此永远不会调用未定义行为的
strlen(string2)

此处
string2
不是字符串,因此
strlen
调用调用未定义的行为

if ((strlen(string1) != 0)||(strlen(string2) != 0))

在C语言中,
|
运算符的左操作数的计算结果为
1
时,保证不计算右操作数。在这里,
|
的左操作数的计算结果为
1
,因此
strlen(string2)
,这是一种未定义的行为,永远不会被调用。

是的,这是众所周知的行为,它可以在任何遵循标准的C/C++编译器中工作。正如Jesse在他的评论中提到的,这被称为短路,并且经常用于指针:

void func( int *ptr )
{
   if( ptr && *ptr ) {
      // pointer is valid and integer that it points to is not 0
   }
}
你最后的陈述:

if ( (FALSE) and (INVALID) ) -> error

这是不正确的想法。如果left为false,aka&&将不会计算right操作数。

是的,这是众所周知的行为,它在任何遵循标准的C/C++编译器中都可以工作。正如Jesse在他的评论中提到的,这被称为短路,并且经常用于指针:

void func( int *ptr )
{
   if( ptr && *ptr ) {
      // pointer is valid and integer that it points to is not 0
   }
}
你最后的陈述:

if ( (FALSE) and (INVALID) ) -> error

这是不正确的想法。如果左边是假,则AKA & &将不会评估右操作数。

< P>在C和C++中,一旦确定布尔表达式,就停止对布尔表达式的求值,因此,当某个事物返回真值时,操作符总是停止评估,而左边部分优先,当和某个东西返回假时,& &停止。 你可以把你想要的东西放在右边,它不会评估


记住,你用“无效”的表达式来定义不确定的行为,如果它工作,就没有办法知道会发生什么。

< P>在C和C++中,一旦确定布尔表达式,它就停止对布尔表达式的求值,因此,操作符总是在某个事物返回真的时停止评估。在左部分优先的情况下,&&会在返回false时立即停止

你可以把你想要的东西放在右边,它不会评估


<>记住,你用“无效”的表达,如果没有工作,就没有办法知道会发生什么。

< P>你所说的被称为“短路”,它是C++中的一个普遍特征。它的工作方式是(TRUE | | anything)总是会为TRUE,因此一旦知道表达式为TRUE,就不会对其进行进一步计算。这同样适用于(FALSE&&anything),因为这将始终是FALSE

这是一个非常有用的例子:

int x = 0;
cin >> x;
if (x != 0 && 10 / x == 2) {
    // ...
}
在x上进行此检查时,如果用户输入0,则不会出现10/0,从而将程序从除以0的状态保存下来


<>你可以一直依赖这个特性,涉及到& &和<

< p>你所说的被称为“短路”,它是C++的一个普遍特征。它的工作方式是(TRUE | | anything)总是会为TRUE,因此一旦知道表达式为TRUE,就不会对其进行进一步计算。这同样适用于(FALSE&&anything),因为这将始终是FALSE

这是一个非常有用的例子:

int x = 0;
cin >> x;
if (x != 0 && 10 / x == 2) {
    // ...
}
在x上进行此检查时,如果用户输入0,则不会出现10/0,从而将程序从除以0的状态保存下来

如果((FALSE)和(INVALID))->error不为true,则其计算结果为FALSE,而不计算第二个条件。除非您键入并使用了
&
而不是
&
。否则将调用它。
如果((FALSE)和(INVALID))->error
不为true,则会计算为FALSE而不计算第二个条件。除非您键入并使用
&
而不是
&