carraysfunctionstruct

Passing struct array to function and calculating average in C?


Beginner here, I've been trying this for hours and can't get it to work, searched online too and couldn't find an answer.

I'm trying to write a program where you input people by putting their age and height then calculate the average of each, and the average ratio of age to height. Whenever I pass the struct to my getAverage function, it returns the address (I think) instead of the averages.

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

typedef struct person
{
    int age;
    double height;
} Person;

double getAv (Person people[50], int max)
{

    int i;
    double total, retval;
    total = 0;
    for (i=0; i<=max; i++)
    {
        total = total + people[i].age;
    }

    retval = total / max;
    return retval;
}


int main (void)
{
    Person people[50];
    int i;

    while (i++, people[i].age>=0)
    {
        printf ("Person #%d\n", i);

        printf ("enter an age: ");
        scanf ("%d", &people[i].age);

        if (people[i].age<0)
            break;

        printf ("enter a height: ");
        scanf ("%lf", &people[i].height);

        printf ("\n");
    }

    double averageAge;
    averageAge = getAv (&people[50], i);
    printf ("%.1lf\n", averageAge);
}

Haven't implemented average height or ratio yet, just trying to get average of ages to work for now. When I try taking the & out of averageAge = getAv(&people[50], I); I get a compile error that tells me it needs the &. Any help would be appreciated.


Solution

  • There are serveral issues in you code, the first one:

    Person people[50];
    int i;
    
    while (i++, people[i].age>=0)
    

    You are using i uninitialized, thus, incrementing a variable containing garbage (or 0 as intended, but it is impossible to guarantee)

    To avoid such problems in the future enable warnings on your compiler, the compiler would have told you something like:

    ā€˜i’ is used uninitialized in this function [-Wuninitialized]
    

    So switch to

    Person people[50] = {0};
    int i = 0;
    

    It seems (based on the pre-increment operator ++i) that you want to use arrays with base 1, there is nothing wrong with that, but in your average function you are starting from 0, so use a for:

    for (i = 0; ; i++)
    {
       ...
       if (people[i].age <= 0) break;
       ...
    }
    

    Another issue:

    double averageAge;
    averageAge = getAv (&people[50], i);
    

    In this way you are passing only element 50 which is not part of your array (remember arrays are base 0 in C), to pass the entire array:

    averageAge = getAv (people, i);
    

    or

    averageAge = getAv (&people[0], i);
    

    The last one:

    for (i=0; i<=max; i++)
    

    You are including the element discarded when you was checking for age > 0, switch to:

    for (i=0; i<max; i++)
    

    A minor issue:

    Iif the user enters 0 for the first element of people you end up dividing by 0

    double averageAge;
    averageAge = getAv (&people[50], i);
    printf ("%.1lf\n", averageAge);
    

    should be

    if (i > 0)
    {
        double averageAge;
        averageAge = getAv (people, i);
        printf ("%.1f\n", averageAge); // No need to use lf (long double)
    }