Reputation: 73
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
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
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
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
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