【问题标题】:two initialisations seperated by seperated by semi colon in CC中用分号分隔的两个初始化
【发布时间】:2018-08-05 03:33:18
【问题描述】:
for(i=1;i=-1;i++)
if(i<5) break;
printf("%d\n",i);

我被要求编写以下代码的输出,我无法理解,因为第二个参数应该是一个条件,但这里是一个赋值,

output: -1

我不明白这是怎么可能的,所以我试着用代码做实验

int i=1;
while(i=-1)
{
    printf("condition is true\n");
    if(i<5) break;
}
printf("%d\n",i);

以下代码的输出是

output: condition is true
        -1

谁能解释一下以上两个代码是如何工作的 以及如何将 while(i=-1) 评估为 TRUE??

【问题讨论】:

  • 确实知道使用= 进行赋值和使用== 进行相等比较之间的区别吗?你也知道在 C 中所有非零都是 true,只有零是 falsebreak 声明的作用是什么?如果有什么你不知道的,那就找一本好的初学者书籍,从头开始阅读。
  • 是的,我知道其中的区别,但这是问的问题,但是当条件中给出 i=-1 时,是否将值分配给 'i' 然后评估为真?跨度>
  • 条件为i = -1。这将被完全评估,分配的结果是分配后的左侧,即分配后的the value of i`,即-1,如果非零,则为真。跨度>
  • 应该发出警告
  • @Someprogrammerdude 感谢您花时间解释,谢谢。

标签: c for-loop while-loop conditional-statements


【解决方案1】:

条件始终为真。因为赋值语句的值就是被赋值的值。所以-1 是非零的,非零值在 中被认为是真的,所以它总是真的。

正确的用法是==,它比较值并根据相等或不相等返回10

因此,当您执行 i = -1 并放入 while 循环条件时 - 归结为

while( -1 ){
  ...
   /* break here */
}

-1 中被视为真,因为它不为零 - 循环条件的计算结果为真。

这里给出break 语句,这样这个循环就不会变成无限循环。

【讨论】:

    【解决方案2】:

    C 中for 循环的语法是

    for(expr1, expr2; expr3)
        /* body of loop */
    

    现在,按照惯例,expr1 是循环初始化,expr2 是继续进行的条件,expr3 是循环之间的增量。但这只是一个约定——实际上,编译器只是安排执行一次expr1,然后expr2 来决定是否再次通过循环,然后在循环底部执行expr3。所以它或多或少相当于

    expr1;
    while(expr2) {
        /* body of loop */
        expr3;
    }
    

    或者,换一种说法:

    expr1;
    while(1) {
        if(!expr2) break;
        /* body of loop */
        expr3;
    }
    

    但是另一个关键点是,是的,表达式

    i = -1
    

    看起来不太像条件;它看起来像一个任务。但是在 C 中,当您使用表达式作为条件时(也就是说,在我们关心的是表达式是“假”还是“真”的上下文中,我们真正关心的是表达式的计算结果是零还是到非零。赋值表达式的值就是被赋值的值。所以

    i = -1
    

    为 -1,并且不为零,因此它被解释为“真”。所以如果你说

    while(i = -1) {
        /* body of loop */
    }
    

    条件始终为“真”,因此它将是一个无限循环,除非在某处的主体中存在break 语句(或return,或对exit() 的调用,或类似的东西) .

    【讨论】:

      【解决方案3】:

      第一个 for 循环不执行任何操作,如果启用优化,将从生成的代码中删除

      第二个进入循环一次。实际循环将被优化编译器删除,并由 puts、初始化和 printf 调用替换。

      https://godbolt.org/g/T5wgqt

      仅带有格式字符串的 printf 被 puts 替换

      【讨论】:

      • for 循环将 -1 分配给 I。那不是什么。不多,但也不算什么。
      • OP 想知道代码做了什么。所以这些优化的解释是无关紧要的(而且有些混乱)。优化不应该影响代码的作用,只影响它的速度。
      • @JonathanLeffler i 如果开启优化,也会被清除。
      • 嗯,由于循环条件中的赋值,打印的值将是-1。因此,结果中留下了循环的痕迹。循环不会被忽略——它会影响生成的输出。
      猜你喜欢
      • 2018-06-17
      • 2015-08-11
      • 1970-01-01
      • 2017-12-09
      • 1970-01-01
      • 1970-01-01
      • 2015-06-13
      • 2011-07-29
      • 2016-09-29
      相关资源
      最近更新 更多