2

考虑以下代码,

int i;
while(i=0)
    printf("Hello");

现在一般来说 i=0 是一个assignment而不是一个condition检查while。但是GCC编译器让它发出警告,甚至正确评估它(不执行打印语句)。

为什么?我通常会为真值加上括号,但我的后辈们觉得我错了,括号里的括号没有真正的理由!

编辑:归零“实际”疑问,请考虑以下测试用例

int callme(){
    return 0;
}

int main(int argc,char*argv[]){
    int c;
    while(c = callme()){
        printf("Calling...\n"); 
    }
    return 0;    
}
4

4 回答 4

9

这个表达式i = 0做了两件事:

  • 有储存o的副作用i
  • 产生值 0

我通常会为真值加上括号,但我的后辈们觉得我错了,括号里的括号没有真正的理由

它通常是对编译器的暗示,意思是“我真的想要这个,我没有忘记=,闭嘴”。


对于您的具体情况,没有理由写if (i = 0):您已经知道 if (0) 会做什么。但它在用作以下用途时非常有用:

if ((i = some_function()))
    ...
于 2012-05-30T04:34:31.637 回答
2

i=0总是一个赋值(除非你把它作为int i = 0;初始化的一部分)。但是任何非 void 表达式都可能出现在while循环的条件内,如果它的计算结果为非零,则循环体将被执行,如果它为零,则循环体将不会被执行。

符号:

while (i = 0)
    printf("Hello\n");

总是等价于:

i = 0;

编写循环的理由很少。

人们确实会写其他表达方式:

while (c = getchar())
    ...process EOF or a non-null character...

但这通常是一个错误。你更有可能写:

while ((c = getchar()) != EOF)
    ...process a character - possibly null...

甚至:

while ((c = getchar()) != EOF && c != '\0')
    ...process a non-null character...

第一个getchar()循环收到来自 GCC 的警告;后两者不是因为对赋值的值进行了显式测试。

写这样一个条件的人:

while ((c = getchar()))

真的很烦我。它避免了来自 GCC 的警告,但它不是(IMNSHO)一种好的编码方式。

于 2012-05-30T04:42:52.273 回答
2

当您使用赋值运算符时,例如

a=0;

您将值分配给“a”,但仍返回数字 0。


为了测试你的问题,我尝试了这些代码行:

int a;
printf("%d", a=0);

这些行显示为 0。

然后,我测试了另一组代码:

int b;
printf("%d", b=15);

在这里,行显示 15。


所以,如果你这样做:

while(a=0)
{
    printf("zero");
}

(a=0) 语句将返回 false,因此不显示任何内容。

但如果你这样做:

while(a=15)
{
    printf("fifteen");
}

“十五”会无限显示,因为语句(a=15)会返回一个非零值,即15,不为假,不为零,因此为真。:)

于 2012-05-30T04:53:58.810 回答
1

正如 cnicutar 上面所说的,赋值也产生零值。

一些附加信息:

人们省略一个额外的“=”是一个常见的编码错误,因此比较变成了一个赋值。

避免这种情况的一种简单方法是编写如下比较,在这种情况下,即使错过了 '=' 编译器也会给出错误

while(0 == i)
{
  prinf("Hello");
}
于 2012-05-30T04:37:21.153 回答