为什么这个"if"语句不起作用?

why doesn't this "if"-statement work?

本文关键字:不起作用 语句 if 为什么      更新时间:2023-10-16
bool foo( int* p )
{
  return false;
}
int* bar (  )
{
  int* p;
  return p;
}
int main() {
  if ( int* p = bar() && foo( p ) )
  //if ( ((int* p = bar()) != NULL ) && (foo( p )) ) // another variant
  {
  }
  return 0;
}

error: cannot convert ‘bool’ to ‘int*’ in initialization GCC 4.3.4和VS 2008。如果只有if ( int* p = bar())一切正常。

我知道我可以在if -语句之前初始化p,但我对我展示的变体感兴趣。

int* p = bar() && foo( p )

首先计算逻辑表达式,然后分配

与写作相同:

int *p = ( bar() && foo(p) );

赋值运算符=的优先级低于布尔值,因此您&&

int* p = ( bar () && foo(p) )

这是尝试将bool分配给int*变量。

编辑:虽然在循环块(如for(int i = 0; i < n; ++i)(中声明和初始化变量通常是一种公认的做法,但我强烈建议不要对条件语句进行这样的构造,例如if(),因为它可能会导致一些非常迷人的副作用,你真的不想处理以及降低代码的可读性。

您的其他变体应该可以工作(除了我不确定您是否要将声明int*...的结果与 NULL 进行比较 - 该语言可能不喜欢(,但请参阅我上面关于代码清晰度的评论

if的语法需要在括号中有一个条件。 一个条件可以是表达式,也可以是声明(的类型,隐式转换为 bool (;它不能是组合其中。 在以下情况下:

if ( int* p = bar() && foo( p ) )

条件为"int* p = bar() && foo( p )",是一个简单的用bar() && foo( p )初始化的类型int*声明;因为bar() && foo( p )的类型不是int*的,也不能隐式转换为int*,您有一个错误。

如果你写:

if ( (int* p = bar()) != NULL )

,左括号表示这不能是声明(简单或否(,并且int* p = bar()不是合法(子(表达式。

要记住的关键点是你可以有一个声明,或者你可以有一个表达式,但你不能将它们组合在一起,C++不允许将声明作为表达式的一部分。 (另:声明必须具有副本初始化:

if ( int* p = bar() )

,则不允许直接初始化。

#include <iostream>
bool foo( int* p )
{
  return false;
}
int* bar (  )
{
  int* p;
  return p;
}
int main() {
  int* p;
  if ( (p = bar()) && foo( p ) )
  //if ( ((int* p = bar()) != NULL ) && (foo( p )) ) // another variant
  {
  }
  return 0;
}

int main() {
  if ( int* p = bar()){
      if ( foo( p ) ){ /*do something*/ }
  }
  return 0;
}

它运行

if语句的条件可以是声明表达式。声明不是表达式,因此不能像尝试的那样将其与另一个表达式组合在一起。换句话说,当你希望

(int* p = bar()) && foo(p)

这是无效的,因为int* p = bar()不是表达式。相反,它被解读为声明

int* p = (bar() && foo(p))

这是无效的,因为初始化器的类型错误。

在这种情况下,您必须在 if 语句之前声明指针;有几个选项是:

int* p = bar(); // pollutes surrounding scope; maybe wrap in another block
if (p && foo(p)) {}
if (int* p = bar()) {
    if (foo(p)) {  // extra nesting
    }
}

我相信这是运算符优先级。您实际上执行:

if ( int* p = (bar() && foo( p )) )

但你的意思是执行,我相信是:

if ( (int* p = bar()) && foo( p ) )

这不完全相同。

事实是您正在使用int* p = bar()进行赋值,并且该语句尝试比较两种类型:intbool,这是不可能的。

您应该在 IF 语句之前分配它。

希望这有帮助