【问题标题】:Understanding C++ code - "Get the number of digits in an int"了解 C++ 代码 - “获取 int 中的位数”
【发布时间】:2019-06-05 19:07:45
【问题描述】:

我无法理解这段代码的具体工作原理:

int length = 1;
int x = 234567545;
while (x /= 10)
   length++;

它应该计算 int 变量中的位数。我不明白while 循环是如何工作的。循环是否默认为零并停止?还有,为什么长度是从1开始的?

【问题讨论】:

  • 使用调试器单步调试程序并观察 x 变量的值。顺便说一句,/= 表示x = x / 10
  • 顺便说一句:获取正数位数的更简单方法是ceil(log10(x))
  • @duskwuff ... 当 x
  • 为什么这个问题跑题了?
  • @PeterMortensen 我同意。如果有的话,给出的原因是题外话。 OP 没有要求关于书籍或工具等的建议。

标签: c++ while-loop


【解决方案1】:

如果您是 C++ 初学者,您可能会怀疑以下三件事:

第一件事可能是运算符/=,它将整数除法(即没有余数)与赋值相结合。所以x /= 10实际上和x = x / 10是一样的。

其次,C++ 中的每个表达式在被评估后都有一个值。对于像(x = 0) 这样的赋值,结果是赋值后x 的值,在这种情况下为0

第三,像if (x) ...x是整数类型的条件在C++中与if(x != 0)的含义相同,即如果x等于0,则为false,则为@987654333 @ if x 不是 0

All together:while ( x /= 10 ) 表示将整数除以10 的值分配给x,然后将该值与0 进行比较。如果达到0,则循环结束。

顺便说一句:length1 开头,因为任何数字,甚至是0,都至少包含一位数字。

【讨论】:

  • 我怀疑第三点的解释会引起一些人的误解,因为它有点歪曲事实,但我个人认为对于这种难度级别的抽象是可以接受的。
  • 在这种情况下,只需添加“for x with type int”。
【解决方案2】:

循环

while (x /= 10) {
  length++;
}

将持续到x /= 10 的结果评估为false,因为0 意味着false 它会持续到x /= 100。整数除法截断,确保达到条件。这可以通过添加一个简单的调试语句来说明,即

while (x /= 10) {
  length++;
  std::cout << length << " " << x << std::endl;
}

哪些输出

2 23456754
3 2345675
4 234567
5 23456
6 2345
7 234
8 23
9 2

【讨论】:

    【解决方案3】:

    这有助于理解两个部分:

    • 什么是“/=”
    • 循环何时终止

    解释“/=”

    这个:

    x /= 10
    

    等同于:

    x = x / 10
    

    说明循环何时终止

    while 循环在条件为假时终止。而 0 则相当于 false。

    while (condition) {
        length++;
    }
    

    所以 x 是,每次通过循环,除以 10,直到是 0。这终止了循环。

    所以,条件是同时存在两件事:

    • 它是一个值,与 0 进行比较。循环一直持续到此 计算结果为 0。
    • 这是一个赋值:x 在每次评估时都会获得一个新值。它除以 10,因此收敛到 0。

    【讨论】:

      【解决方案4】:

      这是您在 C/C++ 中经常看到的一点愚蠢,利用了 TRUE 实现为非零,而 FALSE 实现为零*这一事实。所以 x 被反复除以 10,表达式最终变为零,所以循环停止。

      虽然令人困惑,但这仍然有效 - 直到有一天有人匆忙将 x 从 int 更改为 double :-) 写“while (x /= 10 >= 1)”会更清晰,更不容易出错,或者甚至将数学放在循环体中而不是条件中。

      *恕我直言,C 的少数缺点之一是它没有明确的逻辑类型,就像 FORTRAN 那样。

      【讨论】:

      • 最好不要对 C++ 中你不喜欢的东西进行咆哮...
      • 1) 过于固执己见。 2) 绝对不限于 C/C++,而是很多编程语言通用的。 3) 为了捕捉到诸如“有人匆忙更改类型”之类的事情(你永远不应该“匆忙”更改工作代码),我们正在编写和执行测试。 4) 将逻辑收缩到这样的条件下,除了编程初学者之外,任何人都不会感到困惑。 (接下来你会争论从零开始的索引...) 5) 问题是 C++,而不是 C,并且 C++ 确实 具有显式逻辑类型(自 C99 以来的 C 也是如此)。
      • 6) 您的“修复”不适用于负数。 7) 代码计算 int 中的位数,无论如何对于 double 都是未定义的。
      • 您的更改不起作用,因为 &gt;= 的优先级 (en.cppreference.com/w/cpp/language/operator_precedence) 高于 /=。因此,10 &gt;= 1 被评估为 1x /= 1 保持 x 的值不变,导致无限循环。
      【解决方案5】:

      x /= 10 连续地将 x 除以 10,这将使其最终变为 0 并导致 while 循环终止,因为 0 被解释为假(而 0 以外的任何其他值都被解释为真)。

      它从长度 = 1 开始的原因是因为数字中总是至少有 1 位数字:如果 x 是从 0 到 9 包括在内,那么 x /= 10 将导致 x 立即变为 0,这意味着在循环将执行。因此,如果长度从 0 开始,它永远不会递增到 1,如果 x 是个位数大,这将是错误的。

      手动计算这个例子:

      1. 234567545 / 10 = 23456754,这是真的,所以while循环继续,长度变为2。

      2. 23456754 / 10 = 2345675,是的。长度变为 3。

      3. 2345675 / 10 = 234567,正确。长度变为 4。

      4. 234567 / 10 = 23456,正确。长度变为 5。

      5. 23456 / 10 = 2345,正确。长度变为 6。

      6. 2345 / 10 = 234,正确。长度变为 7。

      7. 234 / 10 = 23,正确。长度变为 8。

      8. 23 / 10 = 2,正确。长度变为 9。

      9. 2 / 10 = 0,错误。 while 循环在长度等于 9 时停止。

      【讨论】:

        【解决方案6】:

        整数除法会截断余数,所以不断用整数除法将一个数除必然会导致零。

        将数字 n 除以 10,同时将计数器 i 递增一次,每次结果商(存储回 n)不为零时,将导致 i 包含数字的位数n 的 base-10 表示。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-21
          • 2018-01-21
          • 2017-06-11
          • 1970-01-01
          相关资源
          最近更新 更多