Search code examples
cfunctionrandomdice

Expected Expression Error when Calling a Function in C


I'm attempting to work with functions for the first time in C. I'm trying to write a classic roll the dice game that rolls a die 10,000 times and then prints out how many times each number has been rolled using functions.

In the code below I keep getting the error code "Expected expression" when trying to set result= roll_die (int num_sides);. It says that it's occurring on the int. When I remove int I get the error code "Use of undeclared identifier 'num_sides' ". How can I fix this?

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

int roll_die(int num_sides){
num_sides = rand() % 6;
num_sides = num_sides + 1;
return num_sides;
}

int main(void)
{
srand((int)time(0));
unsigned int counter, result, num1=0, num2=0, num3=0, num4=0, num5=0, num6=0;
unsigned int num_rolls = 10000;
for(counter=0; counter<=num_rolls; counter++)
{
    result = roll_die (num_sides);
    if(result==1)
        num1++;
    else if(result==2)
        num2++;
    else if(result==3)
        num3++;
    else if(result==4)
        num4++;
    else if(result==5)
        num5++;
    else if(result==6)
        num6++;
    else{
        printf("Error occurred. \n"); return 0;
    }
}
printf("Number of 1s rolled: %d \n", num1);
printf("Number of 2s rolled: %d \n", num2);
printf("Number of 3s rolled: %d \n", num3);
printf("Number of 4s rolled: %d \n", num4);
printf("Number of 5s rolled: %d \n", num5);
printf("Number of 6s rolled: %d \n", num6);
}

Solution

  • As I noted in comments, you need either to replace num_sides in main() with 6, or you need to define and initialize a variable (int num_sides = 6;). Your function hard-codes 6 as the number of sides and ignores the value passed in (it just uses the parameter as a local variable, ignoring what it was supplied as a value).

    Fixing these two issues leads to code like this:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    static int roll_die(int num_sides)
    {
        int result = rand() % num_sides + 1;
        return result;
    }
    
    int main(void)
    {
        srand((int)time(0));
        unsigned int counter, result, num1 = 0, num2 = 0, num3 = 0, num4 = 0, num5 = 0, num6 = 0;
        unsigned int num_rolls = 10000;
        for (counter = 0; counter <= num_rolls; counter++)
        {
            result = roll_die(6);
            if (result == 1)
                num1++;
            else if (result == 2)
                num2++;
            else if (result == 3)
                num3++;
            else if (result == 4)
                num4++;
            else if (result == 5)
                num5++;
            else if (result == 6)
                num6++;
            else
            {
                printf("Error occurred. \n");
                return 0;
            }
        }
        printf("Number of 1s rolled: %d \n", num1);
        printf("Number of 2s rolled: %d \n", num2);
        printf("Number of 3s rolled: %d \n", num3);
        printf("Number of 4s rolled: %d \n", num4);
        printf("Number of 5s rolled: %d \n", num5);
        printf("Number of 6s rolled: %d \n", num6);
    }
    

    Example output:

    Number of 1s rolled: 1670 
    Number of 2s rolled: 1653 
    Number of 3s rolled: 1656 
    Number of 4s rolled: 1687 
    Number of 5s rolled: 1696 
    Number of 6s rolled: 1639 
    

    You should also use an array instead of the 6 numX variables. For example, using int num[7] = { 0 }; would allow you to use the value returned by roll_die() as an index into the array. That compresses the code like this:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    static int roll_die(int num_sides)
    {
        return rand() % num_sides + 1;
    }
    
    int main(void)
    {
        srand(time(0));
        unsigned num[7] = { 0 };
        unsigned num_rolls = 10000;
        int num_sides = 6;
        for (unsigned counter = 0; counter <= num_rolls; counter++)
            num[roll_die(num_sides)]++;
        for (int i = 1; i <= num_sides; i++)
            printf("Number of %ds rolled: %d \n", i, num[i]);
        return 0;
    }
    

    Sample output – can you spot any difference from the previous output other than that due to the different random sequence? There shouldn't be any!

    Number of 1s rolled: 1705 
    Number of 2s rolled: 1651 
    Number of 3s rolled: 1653 
    Number of 4s rolled: 1616 
    Number of 5s rolled: 1631 
    Number of 6s rolled: 1745 
    

    And this makes it easy to generalize for N-sided dice, like this:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    static int roll_die(int num_sides)
    {
        return rand() % num_sides + 1;
    }
    
    int main(int argc, char **argv)
    {
        int num_sides = 6;
        if (argc == 2)
        {
            num_sides = strtol(argv[1], 0, 0);
            if (num_sides < 2 || num_sides > 999)
            {
                fprintf(stderr, "Number of sides of %d is not in the range 2..999\n", num_sides);
                exit(EXIT_FAILURE);
            }
        }
        srand(time(0));
    
        unsigned num[num_sides + 1];
        for (int i = 1; i <= num_sides; i++)
            num[i] = 0;
    
        unsigned num_rolls = 10000;
        for (unsigned counter = 0; counter <= num_rolls; counter++)
            num[roll_die(num_sides)]++;
    
        for (int i = 1; i <= num_sides; i++)
            printf("Number of %ds rolled: %d \n", i, num[i]);
    
        return 0;
    }
    

    And, if this program is called die83, then a sample run might look like:

    $ ./die83 8
    Number of 1s rolled: 1294 
    Number of 2s rolled: 1197 
    Number of 3s rolled: 1256 
    Number of 4s rolled: 1228 
    Number of 5s rolled: 1230 
    Number of 6s rolled: 1222 
    Number of 7s rolled: 1278 
    Number of 8s rolled: 1296 
    $