2013-08-29 2 views
0

Я пишу программу, которая находит суммирование простых чисел. Он должен использовать перенаправленный ввод. Я написал его так, что он найдет наибольшее число для ввода, а затем использует его как nth prime. Затем он использует nth prime для установки размера массива. Он работает до тех пор, пока я не попытаюсь напечатать сумму. Я не могу понять, почему я получаю seg-ошибку там всего. Я думаю, что я правильно распределял массивы с помощью malloc. почему ошибка произошла при печати на не тогда, когда я использую свои массивы? Любые предложения по моему коду также приветствуются.Суммирование nth prime

EDIT использовал тестовый ввод формы 2000 года с 1 по 2000 год, и он работал, но полный тестовый файл 10000 форм от 1 до 10000 сбоев все еще изучает причины. Я предполагаю, что я не выделить достаточно места

EDIT Моя проблема была в моем решето я не принимать SQRT (nthprime), чтобы он нашел более простых чисел, то массив может держать

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


int nprime (int max); 
void sieve_sum (int *primes, int nthprime, int tests,int *input); 

int main(void) 
{ 
    int i=0; 
    int max=0; //largest input 
    int tests; //number of tests 
    int nthprime; //estimated nth prime 
    int *primes; //array of primes 
    int *input; // numbers to put in to P(n), where p(n) is the summation of primes 

    scanf("%d",&tests); //gets number of tests 
    input = malloc(sizeof(int)*tests); 

    //test values 
    for(i=0; i<=tests-1; i++) 
     scanf("%d",&input[i]); 

    //finds max test value 
    i=0; 
    for (i = 0; i < tests; i++) 
    { 
     if (input[i] > max-1) 
      max = input[i]; 
    } 

    // calls nprime places value in n 
    nthprime = nprime(max); 
    primes = malloc(sizeof(int)*nthprime); 

    // calls sieve_sum 
    sieve_sum(primes, nthprime, tests, input); 

    //free memory 
    free(input); 
    free(primes); 
    return 0; 
} 

//finds Primes and their sum 
void sieve_sum (int *primes, int nthprime, int tests,int *input) 
{ 
    int i; 
    int j; 

    //fills in arrays with 1's 
    for(i=2; i<=nthprime; i++) 
     primes[i] = 1; 

    //replaces non primes with 0's 
    i=0; 
    for(i=2; i<=sqrt(nthprime); i++) 
    { 
     if(primes[i] == 1) 
     { 
      for(j=i; (i*j)<=(nthprime); j++) 
        primes[(i*j)] = 0; 
     } 
    } 

    //rewrites array with only primes 
    j=1; 
    i=0; 
    for(i=2; i<=nthprime; i++) 
    { 
     if(primes[i] == 1) 
     { 
      primes[j] = i; 
      j++; 
     } 
    } 

    //sums 
    i=0; 
    for (i=1; i<=tests; i++) 
    { 
     int sum=0;//sum of primes 

     j=0; 
     for(j=1; j<=input[i-1]; j++) 
     { 
       sum = primes[j] + sum; 
     } 

     printf("%d\n", sum); 
    } 
    return 0; 
} 

//finds the Nth number prime 
int nprime (int max) 
{ 
    //aproximization of pi(n) (the nth prime) times 2 ensures correct allocation of memory 
    max = ceil(max*((log (max)) + log ((log (max)))))*2; 
    return (max); 
} 

Пример входного файла:

20 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
10 
9 
8 
7 
6 
5 
4 
3 
2 
1 

Пример вывода должен быть:

2 
5 
10 
17 
28 
41 
58 
77 
100 
129 
129 
100 
77 
58 
41 
28 
17 
10 
5 
2 
+6

это не так на нескольких уровнях - я даже не знаю с чего начать. –

+0

Скомпилируйте все предупреждения и информацию об отладке ('gcc -Wall -g' в Linux) и используйте отладчик (' gdb'), если у вас больше нет предупреждений о компиляции. –

+4

Возможно, начните с чтения руководства по malloc: http://www.manpagez.com/man/3/malloc/ (HINT: malloc ожидает, что количество байтов будет назначаться как аргумент. Вероятно, вы не видите '* sizeof (int) ') –

ответ

4

ОК , поэтому я собираюсь сделать это, не сказав слишком много, потому что похоже, что это может быть проблема домашних заданий.

Моя лучшая догадка заключается в том, что многие люди избегают даже взглянуть на ваш код, потому что это слишком грязно для их уровня терпения. Это не безвозвратно, но вы, вероятно, получите лучший ответ, если бы он был значительно чище.

Итак, во-первых, несколько критических комментариев к вашему коду, которые помогут вам его очистить: он недостаточно хорошо прокомментирован, чтобы ваши намерения были ясными на любом уровне, включая общую цель программы; он непоследовательно с отступом и разнесен в нетрадиционной форме; и ваш выбор имен переменных оставляет желать лучшего, что усугубляется отсутствием комментариев к объявлениям переменных.

Вы должны скомпилировать этот код что-то вроде (предполагается, что ваш исходный файл называется sumprimes.c):

gcc -std=c99 -pedantic -Wall -Wextra -o sumprimes sumprimes.c -lm 

Посмотрите предупреждениями это производит, и он будет оповещать вас несколько, правда, довольно незначительные , проблемы.

Основная проблема, которую я могу проверить путем проверки, заключается в том, что ваша программа, безусловно, будет segfault, потому что хранилище, которое вы выделили malloc(), является слишком маленьким в sizeof(int), которое вы пропустили.

Статический контроль ошибок, например splint, поможет вам выявить некоторые дополнительные проблемы; нет необходимости рабски следовать всем его рекомендациям, хотя: как только вы узнаете все, вы можете решить, какие из них последуют.

Несколько других замечаний:

  • «Магические числа», такие, как 100 в вашем коде, считаются очень плохой форме. Как правило, единственное число, которое должно появляться в коде буквально, равно 0 (ноль), а затем только иногда.Ваш 100 будет намного лучше представлен как что-то по имени (например, const int или, более традиционно, #define), чтобы дать указание на его значение.
  • Это нетрадиционный «Выступ» объявления переменных в порядке, сделано в коде
  • Если функция рекламируемый возвращать значение, вы должны всегда проверить его на наличие ошибок, например убедитесь, что возвращаемое значение malloc() не NULL, убедитесь, что возвращаемое значение scanf() (если вы его используете) ожидаемое значение, и т.д.
  • В общем плане стиля, обычно считается хорошей практикой в ​​C, чтобы объявить переменные по одному в строке с кратким пояснительным комментарием. Есть исключения, но это разумное правило.
  • Для любого вида ввода, scanf() является плохим выбором, поскольку он изменяет состояние stdin таким образом, что трудно предсказать, если входной сигнал не является точно, как и ожидалось, что вы никогда не может зависеть от. Если вы хотите читать целое число, гораздо лучше прочитать то, что доступно в stdin, с fgets() в буфер, а затем использовать strtol(), так как вы можете сделать гораздо более эффективную проверку ошибок и отчетность таким образом.
  • Не рекомендуется возвращать malloc().

Надеюсь, это поможет.

+0

Я исправил для него устаревшие переменные - спокойно, исправляя некоторые другие проблемы с самим вопросом. Хороший ответ. Вы можете упомянуть о проверке возврата из 'scanf()' явно, а также 'malloc()'. –

+0

Спасибо. Я исправил много из того, что вы предложили, повторил мой код – Arix

+0

Решил проблему поблагодарить вас за советы – Arix

Смежные вопросы