添加额外的“ int”关键字时,while循环不会中断吗?

时间:2019-07-08 01:14:53

标签: c

我在代码战中做一些练习,不得不做一个digital_root函数(将数字的所有数字递归加起来,直到只剩下一个数字为止)。 我相当有信心自己做对了,但是由于某种原因,即使打印显示len为1,我的while循环也不会中断。

#include <stdio.h>
#include <string.h>

int digital_root(int n) {
  char number[10];
  sprintf(number, "%d", n);

  int len = strlen(number);
  printf("Outer print: %s %d %d\n", number, n, len);
  int sum = 0;
  while(len > 1)
  {
    sum = 0;
    for(int i = 0; i<len; i++)
    {
      sum += number[i] - '0';
    }
    sprintf(number, "%d", sum);
    int len = strlen(getal);       //!!!
    printf("Inner print: %s %d %d\n", number, sum, len);


  }

  return sum;

}

我花了很长时间才弄清楚出了什么问题。我注意到在重新计算while循环中的len(标有!!!的行)时,我复制粘贴了'int'关键字。当我删除它时(因为不需要将它重新定义为int,它已经是),所有事情突然都按预期的方式工作。

这有点使我困惑。为什么会这样呢?我知道重新定义它是不好的做法,但是我不知道这会导致while循环不中断吗?

使用的编译器是Clan3.6 / C11。

(附言。当我在TIO中尝试相同的代码时,在两种情况下都有效...)

2 个答案:

答案 0 :(得分:4)

您不是在重新定义现有变量,而是在定义新变量。

考虑以下示例:

#include <stdio.h>

int main(void) {
    int x = 42;
    printf("Outside, start.     x (%p) = %d\n", (void *)&x, x);
    {
        printf("Inner block, start. x (%p) = %d\n", (void *)&x, x);
        int x = 123;
        printf("Inner block, end.   x (%p) = %d\n", (void *)&x, x);
    }
    printf("Outside, end.       x (%p) = %d\n", (void *)&x, x);
    return 0;
}

示例输出:

Outside, start.     x (0x7ffd6e6b8abc) = 42
Inner block, start. x (0x7ffd6e6b8abc) = 42
Inner block, end.   x (0x7ffd6e6b8ab8) = 123
Outside, end.       x (0x7ffd6e6b8abc) = 42

[Live demo]

该程序输出存储器地址和x的值。 x的大多数用法是指在main开头声明的外部变量。但是在内部块中,在int x = 123;之后,x的所有出现都引用了另一个单独的变量,该变量也被称为x(但在其他方面是独立的)。

当执行离开内部块时,外部x变量再次变为可见。

这也称为shadowing

在您的代码中,外部len从未修改,因此while(len > 1)始终为真。


顺便说一下,在大多数支持块作用域的语言中,阴影化是一个非常普遍的概念:

答案 1 :(得分:0)

您的第二个int len创建第二个并行变量,该变量在{}块的末尾消失。然后,原始的len恢复原状,完全没有变化。没有第二个int,原始变量将被更改。有了它,原始的len实际上就是一个不变的常数和无限循环。