2013-05-31 67 views
20

我碰到这段代码。我通常使用'& &'或'||'在for循环中分离多个条件,但此代码使用逗号来执行此操作。C'for'循环中的多个条件

令人惊讶的是,如果我改变条件的顺序,输出会发生变化。

#include<stdio.h> 

int main() { 
    int i, j=2; 

    for(i=0; j>=0,i<=5; i++) 
    { 
     printf("%d ", i+j); 
     j--; 
    } 
    return 0; 
} 

输出= 2 2 2 2 2 2

#include<stdio.h> 

int main(){ 
    int i, j=2; 

    for(i=0; i<=5,j>=0; i++) 
    { 
     printf("%d ", i+j); 
     j--; 
    } 
    return 0; 
} 

输出= 2 2 2

有人能解释一下原因吗?它似乎只检查最后一个以逗号分隔的条件。

+2

错误代码。你是对的;应使用&&或||连接多个条件。 – Caleb

+7

五个答案,每个人都直截了当地回答这个问题,并解释逗号的作用,而不是一个答案,表明这是可怕的,可怕的破碎。 –

回答

41

逗号运算符评估其所有操作数并得出最后一个操作数的值。所以基本上无论你写什么条件第一,它将被忽略,而第二一个将只有重大。

for (i = 0; j >= 0, i <= 5; i++) 

因此与

for (i = 0; i <= 5; i++) 

相当于这可能是也可能不是代码的意图笔者,这取决于他的意图是什么 - 我希望这不是生产代码,因为如果有程序员写这个想要表达条件之间的AND关系,那么这是不正确的,应该使用&&运算符。

+1

这里重要的一点是tat问题的代码是不正确的。 – Caleb

+0

@Caleb从何种意义上说?我想我会得到你想提出的建议,但我不确定它是否可以或应该被包含在答案中。 – 2013-05-31 14:03:33

+0

这个*不能*是作者的意图,因为它没有意义。我不相信这位作者的任何代码。 –

5

逗号表达式取值为最后(例如,最右边)的表达式。

所以在你的第一个循环中,唯一的控制表达式是i<=5;并且j>=0被忽略。

在第二个循环中,j>=0控制循环,并且忽略i<=5


至于原因 ......没有理由。此代码仅为错误。逗号表达的第一部分确实没有,除了混淆程序员。如果一个严肃的程序员写这个,他们应该为自己感到羞耻,并且撤销他们的键盘。

2

C中有一个运算符称为逗号运算符。它按顺序执行每个表达式并返回最后一条语句的值。这也是一个sequence point,这意味着每个表达式都保证在系列中的下一个表达式执行之前完全按顺序执行,类似于&&||

+0

这使得它在这种情况下无用 - 他首先检查条件没有任何用处。 – Caleb

+0

@EricPostpischil对不起,表情。啧。 –

3

Wikipedia告诉什么逗号操作的作用:

“在C和C++编程语言中,逗号(由令牌,表示),用于评估其第一操作数和丢弃结果的二进制运算符,然后评估第二个操作数并返回该值(和类型)。“

+0

-1来自维基百科的引用没有回答这个问题,这不是逗号所做的事情,而是为什么它在这里被使用。 – Caleb

+1

@Caleb,老实说,我不相信这个问题会问为什么。因为它说:“令人惊讶的是,如果我改变条件的顺序输出变化”。因此引用了答案。 – tafa

3

不要使用此代码;谁写它显然具有语言的基本误解,是不可信赖的表达:

j >= 0, i <= 5 

评估‘Ĵ> = 0’,则抛出它带走和然后它会评估“i < = 5”,并将其作为结束循环的条件。当左操作数具有副作用时,逗号运算符可以有意义地用于循环条件;你会经常看到类似的东西:

for (i = 0, j = 0; i < 10; ++i, ++j) . . . 

其中逗号用于潜入额外的初始化和增量语句。但是显示的代码没有这样做,或者其他任何有意义的代码。

4

当然这是正确的,你开始说,C logical operator&&||是你通常用来“连接”条件(表达式可以评估为真或假);逗号运算符不是一个合乎逻辑的运算符,它在该示例中的使用是没有意义的,正如其他用户所解释的那样。您可以使用它,例如在自身中“连接”语句:您可以用i初始化和更新j;或用逗号在otherways

#include <stdio.h> 

int main(void) // as std wants 
{ 
    int i, j; 

    // init both i and j; condition, we suppose && is the "original" 
    // intention; update i and j 
    for(i=0, j=2; j>=0 && i<=5; i++, j--) 
    { 
     printf("%d ", i+j); 
    } 
    return 0;   
} 
0

完成克罗克先生的回答,请注意++或 - 运算符或我不知道,也许其他运营商。 他们可以影响循环。例如我看到一个类似于这个在一个过程中的代码:

for(int i=0; i++*i<-1, i<3; printf(" %d", i)); 

结果将是$ 1 2 $。所以第一个语句影响循环,而下面的结果是很多零。

for(int i=0; i<3; printf(" %d", i));