【问题标题】:how this works:while (scanf("%d %d", &a, &b), (a || b))这是如何工作的:while (scanf("%d %d", &a, &b), (a || b))
【发布时间】:2016-06-25 09:40:47
【问题描述】:

我的问题是,在下面的程序中,代码如何

while (scanf("%d %d", &a, &b), (a || b))

正在评估?

程序获取两个数字并打印总和:

int a, b; 
while (scanf("%d %d", &a, &b), (a || b))
    printf("%d\n", a + b); 

【问题讨论】:

  • C 和 C++ 是不同的语言,所以请正确标记您的问题
  • a || b 是循环控制,但程序未能对来自scanf 的返回值进行必要的检查。
  • 是的,我知道 C 和 C++ 是不同的语言,但我问的问题对他们来说是共同的

标签: c while-loop scanf


【解决方案1】:

阅读有关C 及其standard library 的更多文档。

首先仔细阅读scanf的文档。

然后阅读comma operator,logical operators(例如||&&

此外,使用所有警告和调试信息 (gcc -Wall -g) 编译您的代码,并在调试器 (gdb) 中逐步运行它。这将使您对计算机如何运行代码有一些(部分)直觉。

不要忘记阅读 undefined behavior,尤其是 C.Lattner 的博客:What every C programmer should know about undefined behavior

更好的代码可能是:

int a, b; 
while ((a=b=0), (scanf("%d %d", &a, &b)==2) && (a || b))
   printf("%d\n", a + b); 

【讨论】:

    【解决方案2】:

    程序存在逻辑错误 - 输入少于两个数字并关闭流会使程序进入无限循环。如果您在第一次迭代时关闭流,您也会得到未定义的行为,因为ab 将在写入之前被读取。

    这样做的原因是comma , operator 丢弃了对其第一个操作数的求值结果:

    while (scanf("%d %d", &a, &b), (a || b))
    

    将致电scanf("%d %d", &a, &b),并继续评估a || b,无论结果如何。这是不正确的,因为scanf 可能会在读取两个整数之前返回流已结束的指示。

    编写此程序的更好方法如下:

    while ((scanf("%d %d", &a, &b) == 2) && (a || b))
    

    这也更直观,因为&& 比逗号更突出。

    注意:a || ba != 0 || b != 0 的含义相同,即ab 中的至少一个不为零。

    【讨论】:

      【解决方案3】:

      它是如何运行的:
      如果用户输入两个整数,它将打印这两个整数的总和,
      并要求两个下一个输入,直到用户输入两个零整数,
      如果用户输入的不是整数值,如aaa,它将打印以前的a+b 值并永远循环,而无需询问新的输入

      所以这是糟糕的代码

      1. 尽量写得简单(结合C语句没有意义)
      2. 始终检查错误
      3. 在需要时使用与系统无关的类型,例如 int32_t#include<stdint.h>
      4. 初始化变量

      我推荐的样本:

      #include<stdint.h>
      #include<stdio.h>
      int main()
      {
          int32_t a, b;
          do{
              if (scanf("%d%d", &a, &b) != 2) {
                  printf("incorrect  input\n");
                  return 1;
              }
              printf("%d + %d = %d\n", a, b, a + b);
      
          } while (a || b);
          return 0;
      }
      

      终端输出(+输入):

      10
      20
      10 + 20 = 30
      0
      0
      0 + 0 = 0
      

      【讨论】:

        猜你喜欢
        • 2012-01-27
        • 1970-01-01
        • 1970-01-01
        • 2021-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-13
        相关资源
        最近更新 更多