Search code examples
calgorithmperformanceoptimizationprimes

Wrote a program to print prime numbers, How do I make it better?


I started learning C the previous day and I wrote a program to print within a given range. Minimum and Maximum of range is given by user.

#include <stdio.h>
int check(int number)
{
    if (number == 1)
    {
        return 0;
    }
    int count = 2;
    while (count < number)
    {
        if (number%count == 0)
        {
            return 0;
        }
        count++;
    }
    return 1;
}
void main()
{
    int i,min,max;
    printf("Enter start of range: ");
    scanf("%d",&min);
    printf("Enter end of range: ");
    scanf("%d",&max);
    for (i = min;i < max;i++)
    {
        if (check(i) == 1)
        {
            printf("%d\n",i);
        }
    }
}

I am getting the output as expected, but I want to know if there is any better way to return 0 if the number entered is 1 or not as it appears like duct tape code to me.

I inserted this block of code before the program goes through a while loop to check for numbers>1.

if (number == 1)
    {
        return 0;
    }

I am getting the output as expected but I want to know if there is a better way than just placing an if statement.

My question is different from the suggested question because I want to know if there is any better way to figure out if 1 is not a prime number. The suggested question was using an if statement, just like how I did. If statement was present in suggested question, I wanted to know any other alternatives that does not use the if statement to check for 1.

I find my question different from the suggested question.


Solution

  • Your program works as expected for valid input, which is a good start. Here are ways to improve the code, especially the check function as requested:

    • use the correct prototype for main without arguments: int main(void).
    • check for valid input: scanf() returns 1 is an integer was entered, otherwise you must handle the error explicitly.
    • use a more explanatory name for the check function such as isprime.
    • it is idiomatic in C for boolean functions to return 0 for false and non zero for true. Just testing if (isprime(i)) is more readable.
    • check for more values to reject: if (n < 2) instead of if (n == 1). If you cannot assume that the argument n is at least 2, you need to use a test like this to reject lower values. With a different loop, you could try and avoid this test, but it is not worth the effort: this test is simple and readable and will cost almost nothing if most values are valid.
    • testing for division remainders should stop as soon as the quotient is smaller than the divisor.
    • testing 2 explicitly before the loop and only testing odd divisors in the loop would further improve performance.
    • to compute prime numbers in a range, trial division is less efficient than the ancient Sieve of Eratosthenes.

    Here is a modified version:

    #include <stdio.h>

    int isprime(int number)
    {
    if (number < 2) {
    return 0;
    }
    if (number % 2 == 0) {
    return number == 2;
    }
    for (int divisor = 3;; divisor += 2) {
    // optimizing compilers will likely compute both the
    // quotient and remainder with a single instruction
    int quotient = number / divisor;
    int remainder = number % divisor;
    if (quotient < divisor)
    return 1;
    if (remainder == 0)
    return 0;
    }
    }

    int main(void)
    {
    int i, min, max;

    printf("Enter start of range: ");
    if (scanf("%d", &min) != 1) {
    fprintf(stderr, "invalid input\n");
    return 1;
    }
    printf("Enter end of range: ");
    if (scanf("%d", &max) != 1) {
    fprintf(stderr, "invalid input\n");
    return 1;
    }
    for (int i = min; i < max; i++) {
    if (isprime(i)) {
    printf("%d\n", i);
    }
    }
    return 0;
    }