The_Bandit
The_Bandit

Reputation: 73

For Loop Not Counting Array Values

Super rookie here. Just doing a little learning before my C course this semester. I found a book practice problem asking to categorize temperature values in an array. Here's everything I have:

// write program to process collection of daily high temps

#include <stdio.h>
    
int main (void)
{
    int temp[26] = {55, 62, 68, 74, 59, 45, 41, 58, 60, 67, 
                    65, 78, 82, 88, 91, 92, 90, 93, 87, 80, 
                    78, 79, 72, 68, 61, 59};

    int i;
    float sum;
    float avg;
    int r1, r2, r3; // range 1, range 2, range 3

    // Loop to catagorize temperature values
    for(i = 0; i <= 26; i++)
    {
        if (temp[i] <= 60)
        {
            r1++;
        }
        else if ((temp[i] > 60) && (temp[i] <= 84))
        {
            r2++;
        }
        else 
        {
            r3++;
        }   

    }

    printf("\nThe number of cold days are: %d", r1);
    printf("\nThe number of pleasant days are: %d", r2);
    printf("\nThe number of hot days are: %d", r3);

    // Loop to take the average temperature
    for (i = 0; i <= 25; i++)
    {
        sum = sum + temp[i];
        avg = sum / i;
    }

    printf("\nThe average temperature of the set is: %f", avg);

    return 0;
}

The average computes correctly, however, the codes is not categorizing the temp values in the array correctly. I just learned arrays yesterday. Can anyone help? Thanks!

Upvotes: 1

Views: 74

Answers (4)

Yunnosch
Yunnosch

Reputation: 26703

In addition to the existing solutions in the other answers, I propose this solution which introduces you to the concept of programming defensively. In this case I focus on defending against inconsistencies in non-trivial code.

#include <stdio.h>
    
int main (void)
{
    int temp[/* auto */] =  {55, 62, 68, 74, 59, 45, 41, 58, 60, 67, 65, 78, 82,
    /* newline shows 2*13 */ 88, 91, 92, 90, 93, 87, 80, 78, 79, 72, 68, 61, 59 };
    /* in case space allows, this allows humans to grasp the total number and e.g.
       notice when the number of initialisers is incorrect; the compiler does not
       mind of course */

    int i=0; /* this init is paranoid, in case loop setup is unusually without init */
    float sum = 0.0f; /* this init is needed, see other answers */
    float avg = 0.0f; /* this init is needed, see other answers */
    int r1 = 0, r2 = 0, r3 = 0; // range 1, range 2, range 3

    size_t length = sizeof(temp)/sizeof(temp[0]); /* avoid need for magic numbers */

    // Loop to catagorize temperature values
    for(i = 0; i < length; i++) /* avoid need for magic numbers */
    {
        if (temp[i] <= 60)
        {
            r1++;
        } else if (temp[i] <= 84) /* avoid copy of first treshold */
        {
            r2++;
        } else 
        {
            r3++;
        }   
    }

    printf("The number of cold days are: %d\n", r1);
    printf("The number of pleasant days are: %d\n", r2);
    printf("The number of hot days are: %d\n", r3);

    // Loop to take the average temperature
    for (i = 0; i < length; i++) /* avoid need for magic number */
    {
        sum = sum + temp[i];
        avg = sum / i;
    }

    printf("The average temperature of the set is: %f\n", avg);

    return 0;
}

You might notice that avoiding magic numbers (using <) and a habit of initialising everything would have prevented both problems discussed and solved in the other answers.

You could also introduce a chance that a human spots a mistake, by outputting a little additional information, assuming of course that it does not conflict with your requirements. In which case the additional output could be created in a way to be removable conveniently for delivery, in a generic way in your team. Without that removal mechanism, this demonstrates "unobtrusive" additional info in output (noticably exaggerated, I admit):

printf("The average temperature of the set of %i temperatures "
       "(%i of which have been classified) is: %f\n", length, r1 + r2 + r3, avg);

The special way of aligning {} in if-else constructs is my favorite indentation style. In my opinion, but it is only an opinion, it also is defensive programming, because at least I do spot if-else-trees more easily like that and hence have a better chance of spotting mistakes. Using {} even for single-statement branches is also part of that, it defends against mistakes introduced by adding a statement to a single-statement else branch without {}.

Removing the logically unneeded (temp[i] > 60) && defends against mistakes like

if (temp[i] < 60)
{
    r1++;
} else if ((temp[i] > 60) && (temp[i] < 84))
{
    r2++;
} else 
{
    r3++;
}

Because it avoids copying code (in this case the check against treshold 60) and the risk of inconsistencies between the two copies. In this case the mistake I introduces would result in a wrong classification of the edge case temperature 60.

Upvotes: 0

Ancientmodern
Ancientmodern

Reputation: 11

You should initialize sum, avg, r1, r2, r3 as 0. Also the range of your array is 0-25, so for(i = 0; i <= 26; i++) should be changed to for(i = 0; i <= 25; i++).

// write program to process collection of daily high temps

#include <stdio.h>
    
int main (void)
{
    int temp[26] = {55, 62, 68, 74, 59, 45, 41, 58, 60, 67, 
                    65, 78, 82, 88, 91, 92, 90, 93, 87, 80, 
                    78, 79, 72, 68, 61, 59};

    int i;
    float sum = 0;
    float avg = 0;
    int r1 = 0, r2 = 0, r3 = 0; // range 1, range 2, range 3

    // Loop to catagorize temperature values
    for(i = 0; i <= 25; i++)
    {
        if (temp[i] <= 60)
        {
            r1++;
        }
        else if ((temp[i] > 60) && (temp[i] <= 84))
        {
            r2++;
        }
        else 
        {
            r3++;
        }   
    }

    printf("The number of cold days are: %d\n", r1);
    printf("The number of pleasant days are: %d\n", r2);
    printf("The number of hot days are: %d\n", r3);

    // Loop to take the average temperature
    for (i = 0; i <= 25; i++)
    {
        sum = sum + temp[i];
        avg = sum / i;
    }

    printf("The average temperature of the set is: %f\n", avg);

    return 0;
}

Upvotes: 1

avishak chakroborty
avishak chakroborty

Reputation: 312

For incrementing the value of a variable you need to initialize the value to the variable. In this case, the variables are r1,r2 & r3. The increment operator increases its value by 1. But if the value is not assigned before, the operator cant finds the value which would be increased. Here r1++ similar to r1=r1+1. so it should be initialized like

r1=0,r2=0,r3=0;

r1++; // which means r1=0+1=1

Upvotes: 0

a.koptan
a.koptan

Reputation: 1248

You invoked undefined behavior:

1- by using uninitialized variables int r1, r2, r3; float sum; float avg;, you should initialize them as zeros.

2- by accessing if (temp[i] <= 60) in your loop for(i = 0; i <= 26; i++), while size of temp is 26 (should only access 0 - 25).

Upvotes: 1

Related Questions