You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写全编译器兼容的C程序?正约数计数程序跨编译器异常求助

C语言正约数计算程序的异常问题排查与修复

我写了一个计算正整数正约数个数的C程序,在本地CodeBlocks的GCC编译器里运行正常,但学校的在线编译器中,部分输入会输出接近22000的数值(比如22019、21873)。比如输入10,本地输出正确的4,在线编译器却输出22019。而且把if语句的条件从if (n<0)改成if (0>n)后,异常数值还会变化(比如从22019变成其他22开头的数)。

原代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  int c, n, res = 0;
  int i = 1;

  scanf("%d", &n);
  if (0>n)
    printf("Wrong Input");
  else {
    while (n>=i)
      {
        res = n%i;
        if (res == 0) {
          c++;
          i++;
        }
        else {
          i++;
        }
      }
    printf("%d", c);
  }
  return 0;
}

问题原因

  • 核心问题:变量c未初始化。C语言中局部变量默认不会自动初始化为0,会保留内存中的随机垃圾值。本地编译器的栈内存刚好让c初始为0,所以结果正确;但在线编译器的内存布局不同,c的初始值是随机的大数值,导致最终输出异常。
  • 修改if条件后异常数值变化,是因为代码结构的细微调整改变了栈上变量的内存位置,c的初始垃圾值也跟着改变,和条件写法本身无关。

修复后的代码

只需要给c显式初始化为0即可:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  int c = 0, n, res = 0; // 初始化c为0
  int i = 1;

  scanf("%d", &n);
  if (n < 0) // 写法更直观,不影响逻辑
    printf("Wrong Input");
  else {
    while (n >= i)
      {
        res = n % i;
        if (res == 0) {
          c++;
          i++;
        }
        else {
          i++;
        }
      }
    printf("%d", c);
  }
  return 0;
}

额外优化建议

可以优化循环逻辑,只遍历到sqrt(n),大幅减少计算量,同时处理0的特殊情况:

#include <stdio.h>
#include <math.h>

int main()
{
  int c = 0, n;
  scanf("%d", &n);
  if (n < 0) {
    printf("Wrong Input");
    return 0;
  }
  if (n == 0) { // 0没有正约数
    printf("0");
    return 0;
  }
  int sqrt_n = sqrt(n);
  for (int i = 1; i <= sqrt_n; i++) {
    if (n % i == 0) {
      if (i == n / i) {
        c++; // 平方数的约数只算一次
      } else {
        c += 2; // 非平方数对应一对约数
      }
    }
  }
  printf("%d", c);
  return 0;
}

内容的提问来源于stack exchange,提问作者Petra Kotrona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:10:24