【问题标题】:N modulo 0 in for loop returns N in C?for循环中的N模0返回C中的N?
【发布时间】:2021-11-23 22:49:14
【问题描述】:

我正在编写一个 C 程序,我想在其中创建一个函数,该函数接受一个“n”整数,并返回它具有的除数。

int divisors(int n) {
int amount = 0;
for(int i = 0; i <= n; i++) {
    printf("%d mod %d = %d\n", n, i, n % i);
    if(n % i == 0) {
        amount++;
    }
}

return amount;
}

printf 显然是用于调试的。会导致问题的代码部分是循环从 0 开始,这意味着在第一次迭代中,程序必须打印 N mod 0。但是,我只是通过分配一些 int a 给这个函数来测试这个函数在 main() 中输入 8,程序会打印:

8 mod 0 = 8
8 mod 1 = 0
8 mod 2 = 0
8 mod 3 = 2
8 mod 4 = 0
8 mod 5 = 3
8 mod 6 = 2
8 mod 7 = 1
8 mod 8 = 0

所以 0 模数运行没有问题,而是返回 n。有趣的是,如果我明确告诉程序printf("%d", 8 % 0);,那么我会得到我期望的错误。那么有谁知道为什么 n mod 0 在循环中在 C 中运行时没有错误?

注意:该程序是使用 GCC 编译的,编译时甚至不会抛出任何警告/错误。

编辑:添加 gcc --version。

配置为:--prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1 苹果 clang 版本 13.0.0 (clang-1300.0.29.3) 目标:arm64-apple-darwin20.6.0 线程模型:posix 安装目录:/Library/Developer/CommandLineTools/usr/bin

【问题讨论】:

  • 这是未定义的行为
  • 除以 0 是未定义的行为。 UB 并不意味着程序必须按照您认为应该的方式运行。它可能会崩溃,它可能会产生错误的值,它可能会在任何时候产生“正确”的值或任何其他行为。
  • 编译器不够聪明,无法捕捉到问题,因为它不会模拟i 可以获得的所有可能值。所以现在这是一个运行时问题,因为除以 0 最有可能导致异常。
  • 另外,编译器是clang,而不是GCC。出于历史原因,gcc 可能是硬链接。请注意,/usr/bin/cc/usr/bin/gcc/usr/bin/clang 都具有相同的大小和实际上相同的内容。

标签: c function for-loop division modulo


【解决方案1】:

当模运算符的第二个操作数为 0 时,行为未定义。您几乎可以从此操作中获得任何结果,正如您所见,对于同一操作,一次获得 8,另一次程序终止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2015-07-04
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多