2016-01-30 2 views
-1

Я относительно новичок в C, и я пытаюсь запустить программу. Это программа, в которой перечислены все простые числа от 1 до 1000. Способ компиляции - это ввести gcc Primes.c в командную строку и запустить ее в NppExec.Программа будет компилироваться, но не исполнять

Код:

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

int x; 
int bool = 1; 
int y; 

main() { 

    for (x = 2; x <= 100; x++) { 
     bool = 1; 
     for (y = 0; y <= floor(x/2); y++) { 
      if (x % y == 0) { 
       bool = 0;  
      } 
     } 

     if (bool == 1) { 
      printf("%d\n", x); 
     } 
    } 
} 

I типа:

NPP_SAVE 
CD $(CURRENT_DIRECTORY) 
C:\MinGW32\bin\gcc.exe -g "$(FILE_NAME)" 
a 

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

+2

Не используйте 'bool' в качестве имени переменной, это действительно может быть определен тип в С. –

+0

Не пытайтесь оценить' х % y', когда 'y'' 0'. Это ошибка деления на нуль. Вам также не нужно использовать 'floor (x/2)'. Просто 'x/2' будет достаточно, так как' x' является целым числом. Вызов 'floor' не имеет никакой цели, кроме как преобразовать его в' double' без какой-либо полезной причины. –

+0

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

ответ

3

Существует ошибка и множество мелких проблем в коде:

  • Вы не должны определять x, bool и y как глобальные переменные, определить эти переменные внутри тела функции main ,
  • Прототип для main: int main(void) или int main(int argc, char *argv[]). main() - это устаревшая форма, которая больше не поддерживается стандартом C. gcc примет его, но clang по умолчанию не будет. Вы также должны добавить return 0; в конце main: хотя он был сделан неявным на C99, он более стильный и более портативный для старых компиляторов.

  • Нельзя использовать bool в качестве имени переменной, bool обычно используется как имя типа, назовите ваш флаг prime.

  • В соответствии с инструкцией вы должны зацикливаться до 1000.

  • y <= floor(x/2) не работает, как ожидалось: x/2 это целое выражение, он уже имеет значение, которое вы ожидаете, передавая его floor преобразует его в качестве double и возвращает то же значение, y будут автоматически преобразованы в double для сравнение. Все это не нужно, y <= x/2 хватает. floor - единственная функция, используемая от <math.h>, вы также можете удалить этот файл include.

  • Обратите внимание, что ваше состояние позволит программе выполнять слишком много итераций, вместо этого вы должны использовать y * y <= x.

  • Initializing y в 0 вызовет деление на ноль, когда вы вычислить x % y, вызывая неопределенное поведение, аварии вы наблюдаете. Вы должны инициализировать y до 2, потому что все числа делятся на 1.

  • Вы должны выйти из цикла, когда обнаруживаете, что x является составным, избегая ненужных итераций.

Вот исправленный вариант:

#include <stdio.h> 

int main(void) { 
    int x, y, prime; 

    for (x = 2; x <= 1000; x++) { 
     prime = 1; 
     for (y = 2; y * y <= x; y++) { 
      if (x % y == 0) { 
       prime = 0; 
       break; 
      } 
     } 
     if (prime == 1) { 
      printf("%d\n", x); 
     } 
    } 
    return 0; 
} 
+0

Я думаю, что обложки. Только nit - это пропущенное форматирование 'return 0' в конце маркированного абзаца № 2 (я позволю вам исправить это, мне не нравятся изменения в моих ответах по мелочам) –

+0

@ DavidC.Rankin: хорошая точка, я добавлены дополнительные замечания относительно 'return 0;' – chqrlie

+0

'floor (x/2)' не будут возвращены обратно в 'int', молча или иначе, как вы утверждаете. То, что произойдет, будет 'y' будет преобразовано в' double', и сравнение будет выполнено как 'double'. –

1

Вы

for (y = 0; y <= floor(x/2); y++) { 
    if (x % y == 0) { 

Вы инициализировать y до нуля, то вы сразу разделить на y (то есть ноль). Деление на ноль не работает, это приведет к сбою вашей программы.

1

Проблема эти 2 строки:

for (y = 0; y <= floor(x/2); y++) { 
    if (x % y == 0) { 

Что вы ожидаете получить с 2 % 0?

В соответствии со стандарта:

С99 6.5.5p5 - Результат/оператора является частным от деления первого операнда на второй; результатом оператора% является остаток. В обеих операциях, если значение второго операнда равно нулю, поведение не определено.

Аварии из-за оператора Modulo, когда y является 0.

how to check if there is a division by zero in c

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