为什么这个if语句需要括号?

4
通常情况下,如果我在 if 语句后面只跟了一个语句,那么就不需要使用大括号。例如:
if (condition) statement1; statement2;

statement2将始终执行,但在这里并没有发生:

for (j = 0; j < size; j++) {
    if (size % 2) if (j % 2) *(minmat + j) *= -1.0;        
    else {
        …
    }
}

else语句应该与第一个if语句相关联,但实际上它与第二个语句相关联。为了纠正这个问题,我必须这样做:

for (j = 0; j < size; j++) {
    if (size % 2) { if (j % 2) *(minmat + j) *= -1.0; }
    else {
        …
    }
}

但是为什么会发生这种情况呢?在第一种情况下,第二个if语句被“隐含”在括号内,为什么还会出现这样的问题呢?


8
C11草案标准,第6.8.4.1§3节:else与其语法允许的最近的前置if相关联。 - EOF
3
else 和第一个 if 语句并没有关联,仅仅因为你的缩进可能让你觉得有关联。 - zubergu
不是MISRA-C的粉丝,但MISRA-C总是要求在“if”语句中使用 {}(即使里面只有一条语句)。 - ouah
5个回答

3
这种歧义被称为悬挂else问题。不管你觉得什么更直观,语言设计者已经决定else与最近匹配的if相关联。如果我考虑一下,我会觉得这个决定很自然,但这是有争议的。不可争辩的是必须做出决定,并且现在无法改变。

3
一条else语句会和最近的if语句关联。你也可以像这样进行修正:
for(j=0; j<size; j++{
    if(size%2) if(j%2) *(minmat+j) *= -1.0; else;        
    else {
        .
        .
        .
    }
}

2

不确定为什么您认为“隐含”的括号存在或适用于此处。 适当缩进后,您已写入:

for(j=0; j<size; j++{
  if(size%2) 
    if(j%2) 
      *(minmat+j) *= -1.0;        
    else {
    }
}

一个 else 会附加到最近的词法 if

1

来自C99标准:

6.8.4.1 if语句

...

3 else与语法允许的最近的上一个if相关联。

因此,

if(size%2) if(j%2) *(minmat+j) *= -1.0;        
else {
    .
    .
    .
}

等同于:

if(size%2)
{
   if(j%2) *(minmat+j) *= -1.0;        
   else {
    .
    .
    .
  }
}

which is equivalent to:

if(size%2)
{
   if(j%2) {
      *(minmat+j) *= -1.0;
   }
   else {
    .
    .
    .
  }
}

0

else 是一个比 if 更粘着相邻的 if 的操作符。因此,它“粘”在最近的 if 上。就像乘法在加法之前一样。

这是一个有意义的规则,否则没有括号的嵌套 if 会变得困难。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接