Related
So I have an assignment, and within it is a question that requires you to construct a 2D array with 5 rows and 4 columns, with each of them containing grades. The question requires you to determine how many grades are less than 60, between 60 and 70 and so on (till 100). Thing is when I try to search through it, there should only be 20 total grades, but my solution gives some far fetched number like 60,000 or whatever. I'm at a loss as to what is wrong with my code. I used two for loops to search through the array. Attached is what I've tried. Thanks a ton for any help
#include <stdio.h>
int main(){
double grades[5][4] = {
{69, 58, 95, 78},
{84, 75, 86, 32},
{75, 68, 65, 73},
{99, 54, 24, 88},
{65, 78, 84, 65}
};
int lessthan60, sixtyseventy, seventyeighty, eightyninety, greaterthan90;
for (int r = 0; r < 5; r++){
for (int c=0; c < 4; c++){
if (grades[r][c] < 60){
lessthan60++;
}
else if (grades[r][c] >=60 && grades[r][c] < 70){
sixtyseventy++;
}
else if (grades[r][c] >=70 && grades[r][c] < 80){
seventyeighty++;
}
else if (grades[r][c] >=80 && grades[r][c] < 90){
eightyninety++;
}
else{
greaterthan90++;
}
}
}
printf("Grades less than 60: %d\n", lessthan60);
printf("Grades between 60 and 70: %d\n", sixtyseventy);
printf("Grades between 70 and 80: %d\n", seventyeighty);
printf("Grades between 80 and 90: %d\n", eightyninety);
printf("Grades between 90 and 100: %d\n", greaterthan90);
return 0;
}
These variables having automatic storage duration
int lessthan60, sixtyseventy, seventyeighty, eightyninety, greaterthan90;
are uninitialized and have indeterminate values. You have to initialize them by zero explicitly
int lessthan60 = 0, sixtyseventy = 0, seventyeighty = 0, eightyninety = 0, greaterthan90 = 0;
Also if statements can be written simpler like
if (grades[r][c] < 60){
lessthan60++;
}
else if ( grades[r][c] < 70){
sixtyseventy++;
}
else if ( grades[r][c] < 80){
seventyeighty++;
}
else if ( grades[r][c] < 90){
eightyninety++;
}
else{
greaterthan90++;
}
Also instead of the magic numbers 4 and 5 it is better to use named constants as for example
enum { ROWS = 5, COLS = 4 };
double grades[ROWS][COLS] = {
{69, 58, 95, 78},
{84, 75, 86, 32},
{75, 68, 65, 73},
{99, 54, 24, 88},
{65, 78, 84, 65}
};
//...
for (int r = 0; r < ROWS; r++){
for (int c=0; c < COLS; c++){
//...
This way, you are starting with garbage values.
You need to initialize counters lessthan60, sixtyseventy, seventyeighty, eightyninety, greaterthan90 to zero.
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!
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).
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;
}
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
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.
From list of collatz sequence that are like 34,17,52,26,13...4,2,1.I want to print 40 characters for each line like "50, 25, 76, 38, 19, 58, 29, 88, 44, 22," will be first line of 40 characters and then next line and should stop when last number are 4, 2, 1
I am unable to stop the program when 4, 2, 1 sequence is encountered.
I have first created the required sequence of numbers. Post that tried to print numbers by for loop with while condition of 1.
int length;
int *ptr;
int i = 50, j = 0;
for (i; i >= 2; )
{
if (i % 2 == 0)
{
i = i / 2;
}
else if (i % 2 != 0)
{
i = (3 * i) + 1;
}
ptr[j] = i;
printf("Total Value: %d, \n", ptr[j]);
j++;
}
for (i = 0; i < 50; )
{
j = 10 + i;
while (i < j)
{
printf("%d, ", ptr[i]);
i++;
if (ptr[i] == 1)
{
break;
}
}
printf("\n");
}
Expected result:
50, 25, 76, 38, 19, 58, 29, 88, 44, 22,
11, 34, 17, 52, 26, 13, 40, 20, 10, 5,
16, 8, 4, 2, 1,
For starters, your code causes a segmentation fault on my machine. You declared ptr as a pointer to an integer int *ptr;, but you are treating it as an array and storing values into it ptr[j] = i;. If you want to put data into an array, then you will either need to malloc a buffer or declare ptr as an array on the stack, i.e., int ptr[SIZE].
A pointer is not a means of storage itself. If you want to have an array for storage, then you need to explicitly allocate an array either on the stack or on the heap.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I have to generate the set Z of the first 100 integers that satisfy the equation i = 2^a * 3^b, with a and b being integers.
That is, Z = {1, 2, 3, 4, 6, 8, 9, 12, ...}
What algorithm could I use ? I'll need to implement it in C.
In C
#include <stdio.h>
#include <math.h>
#include <stdint.h>
typedef unsigned long long int ull;
ull cmp(const void * a, const void * b) { return *(ull *)a - *(ull *)b; }
int main() {
int i = 0, a, b;
int A = 17,
B = 16;
int MAX = A * B;
ull z[MAX];
for (b = 0; b < B; ++b) {
for (a = 0; a < A; ++a) {
if (i >= MAX) break;
z[i++] = pow(2, a) * pow(3, b);
}
}
qsort(z, MAX, sizeof(ull), cmp);
printf("{ ");
for (i = 0; i < 100; ++i)
printf("%lld%c ", z[i], i < 99 ? ',' : 0);
printf("}");
return 0;
}
Output
{ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96, 108, 128, 144, 162, 192, 216, 243, 256, 288, 324, 384, 432, 486, 512, 576, 648, 729, 768, 864, 972, 1024, 1152, 1296, 1458, 1536, 1728, 1944, 2048, 2187, 2304, 2592, 2916, 3072, 3456, 3888, 4096, 4374, 4608, 5184, 5832, 6144, 6561, 6912, 7776, 8192, 8748, 9216, 10368, 11664, 12288, 13122, 13824, 15552, 16384, 17496, 18432, 19683, 20736, 23328, 24576, 26244, 27648, 31104, 32768, 34992, 36864, 39366, 41472, 46656, 49152, 52488, 55296, 59049, 62208, 65536, 69984, 73728, 78732, 82944, 93312 }
EDIT: Gives correct output now without overflow (see http://ideone.com/Rpbqms)
too much brute force...
let me propose a O(n*lg n) time O(n) space algorithm to achieve these.
i am not gonna provide any real code, but a piece of self invented pseudocode.
the idea is to use min-heap to maintain ordering:
func first-n-of-that(limit)
heap = min-heap()
heap.insert 1
results = []
while results.length < limit
to-add = heap.pop
results.add to-add
heap.insert 2 * to-add
heap.insert 3 * to-add
return results
the correctness is provable by deduction.
Brute force in Python (I know that C code is required):
sorted(2**a*3**b for a in range(100) for b in range(100))[:100]
And the result is …
I was trying to generate a random array of integers of length 16 inside a loop. The elements of the array will lie inside [0, 255]. I thought assigning random integers from [0, 255] would suffice; but it does not work (one random array is created which remains unchanged over iterations). Then I tried shuffling, but the situation does not improve (I also notice that the probability of 0 in the 'random' array is significantly larger).
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#define Shuffle
/* Generate a random integer array of length `size` with elements from [0, 255] */
int* random_sample(int size)
{
int i, j, k;
int *elements = malloc(size*sizeof(int));
/* Assign random integers */
for (i = size - 1; i > 0; --i)
{
elements[i] = rand() % 256;
}
/* Shuffle */
#ifdef Shuffle
for (i = size - 1; i > 0; --i) {
j = rand() % size;
k = elements[i];
elements[i] = elements[j];
elements[j] = k;
}
#endif
return elements;
}
int main(int argc, char const *argv[])
{
int LENGTH = 16, i, iteration;
int *random_array = random_sample(LENGTH);
srand(time(NULL));
for (iteration = 0; iteration < 10; ++iteration)
{
for (i = 0; i < LENGTH; ++i)
printf("%d, ", random_array[i]);
puts("");
}
return 0;
}
A typical output looks like:
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
0, 227, 251, 242, 171, 186, 205, 41, 236, 74, 255, 81, 115, 105, 198, 103,
I tried several variations of the above code, but none of them works. Need help!
EDIT
I was trying variations of the code, and mistakenly printed the same unchanged array (as pointed out by some others - thanks to them); originally I wrote
int main(int argc, char const *argv[])
{
int LENGTH = 16, i, iteration;
int *random_array;
srand(time(NULL));
for (iteration = 0; iteration < 10; ++iteration)
{
random_array = random_sample(LENGTH);
for (i = 0; i < LENGTH; ++i)
printf("%d, ", random_array[i]);
puts("");
}
return 0;
}
which print much more 0s.
EDIT (2)
Thanks to #pmg, I found the problem. Inside random_sample function, changing the first
for (i = size - 1; i > 0; --i) to for (i = size - 1; i >= 0; --i) works fine!
Thank you all.
Try the code below. For the array to contain different (random) values at every iteration, you need to put different values in it :)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#define Shuffle
/* Generate a random integer array of length `size` with elements from [0, 255] */
int* random_sample(int size)
{
int i, j, k;
int *elements = malloc(size*sizeof(int));
/* Assign random integers */
for (i = size - 1; i > 0; --i)
{
elements[i] = rand() % 256;
}
/* Shuffle */
#ifdef Shuffle
for (i = size - 1; i > 0; --i) {
j = rand() % size;
k = elements[i];
elements[i] = elements[j];
elements[j] = k;
}
#endif
return elements;
}
int main(int argc, char const *argv[])
{
int LENGTH = 16, i, iteration;
int *random_array;
srand(time(NULL));
for (iteration = 0; iteration < 10; ++iteration)
{
random_array = random_sample(LENGTH);
for (i = 0; i < LENGTH; ++i)
printf("%d, ", random_array[i]);
puts("");
free(random_array);
}
return 0;
}
Here's some comments on your code to clarify the problem.
int main(int argc, char const *argv[])
{
int LENGTH = 16, i, iteration;
int *random_array = random_sample(LENGTH); // ARRAY is created and filled in here.
srand(time(NULL)); // Random generator is initialized here.
// WAIT WHAT? You already filled in the array above!
// It is too late now to initialize the Generator!
In addition to what others have said above, I think its important to note the following on the rand function as written in the man page:
Note:
The versions of rand() and srand() in the Linux C Library use the same random number generator as random(3) and srandom(3), so the lower-order bits should be as random as the higher-order bits. However, on older rand() implementations, and on current implementations on different systems, the lower-order bits are much less random than the higher-order bits. Do not use this function in applications intended to be portable when good randomness is needed. (Use random(3) instead.)
There are two possible alternatives:
1) Use the random function as recommended by the note.
2) Use the higher-order bits of the random number as follows:
elements[i] = (rand() * 256) / RANDMAX;