【问题标题】:Command terminated when inputting large number输入大数时命令终止
【发布时间】:2014-06-07 17:31:43
【问题描述】:

当我尝试输入一个大数字(大约 1000 万)时,为什么会收到“命令终止”的消息?该程序显示该数字是否为质数。

见下面的代码:

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

int main ( int argc, char *argv[] )
{
   unsigned long long number;
   bool prime ( unsigned long long );

   printf ("Enter a positive integer greater than 1: ");
   scanf ("%llu", &number );

   prime( number ) ?
      printf ( "%llu is a prime.\n", number ):
      printf ( "%llu is not a prime.\n", number);

   return EXIT_SUCCESS;
}

bool prime ( unsigned long long number )
{
   unsigned long long i, j;
   bool isPrime[number + 1];

   for ( i = 2; i <= number; i++ )
      isPrime[i] = true;

   for ( i = 2; i <= number - 1; i++ )
      for ( j = 1; i*j <= number; j++ )
         isPrime[i*j] = false;

   return isPrime[number];
}

【问题讨论】:

  • bool isPrime[number + 1]编译没有错误?
  • @barakmanos 它是 C,而不是 C++(C99 支持可变长度数组)
  • 至少对我来说,是的。我正在使用 GCC。
  • @MarcoA:这对双方都有效!无论如何,1000 万个bool 数组可能没有足够的堆栈空间。
  • 你的筹码可能要炸了

标签: c primes sieve-of-eratosthenes


【解决方案1】:

问题是您试图在堆栈上创建一个数组isPrime,该数组大于可用内存。您应该改为在堆上创建它,使用

bool *isPrime;
isPrime = malloc((number + 1) * sizeof *isPrime);

显然只做一次,而不是每次调用函数prime

还请注意,如果您只想知道一个数字是否为素数,您只需搜索该数字的平方根即可找到一个因数 - 如果您找到了一个因数,您就完成了。这使得您必须创建的数组的大小更易于管理 - 但它确实涉及对您的算法进行一些更改。

事后考虑您在确定什么是素数的逻辑中存在问题 - 您的内部循环以 j=1 开头,这意味着即使素数也会被标记为非素数。以下是“略微改进”的代码 - 尽管您可以做更多的事情来让它变得更好:

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

int main ( int argc, char *argv[] )
{
   unsigned long long number;
   bool prime ( unsigned long long );

   printf ("Enter a positive integer greater than 1: ");
   scanf ("%llu", &number );

   prime( number ) ?
      printf ( "%llu is a prime.\n", number ):
      printf ( "%llu is not a prime.\n", number);

   return EXIT_SUCCESS;
}

bool prime ( unsigned long long number )
{
   unsigned long long i, j, sq;
   bool *isPrime;
   sq = ceil(sqrt(number));
   isPrime = malloc((sq + 1)*sizeof *isPrime);

   // generate primes up to the square root of the number
   for ( i = 2; i <= sq; i++ )
      isPrime[i] = true;

   for ( i = 2; i < sq; i++ ) {
      // only need to mark multiples if this is a prime:
      if(isPrime[i]) {
        // start this loop at 2, not 1!
        for ( j = 2; i*j <= sq; j++ ) {
          isPrime[i*j] = false;
        }
      }
    }

   for ( i = 1; i < sq; i++)
   {
    if (isPrime[i] && number%i==0) return false;
   }

   return true;
}

基本测试:

gcc -Wall 不会产生错误/警告

104729 是质数(它是);代码不会因输入 10000001(不是素数)而崩溃。

【讨论】:

  • /同意,我得到了 stackoverflow :)
  • 非常感谢您的帮助! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-21
  • 1970-01-01
  • 2012-10-29
  • 1970-01-01
相关资源
最近更新 更多