This is a follow up to this question:
sorting structs in C with pointers
I’ve revised my revised code and I think the sort should be working but I get the feeling that I’m not using the pointers correctly. My printf statements aren’t showing up on the console, they are labeled in the comments.
I’m new to C so this may be obvious but I’m just lost as to how to debug when print statements don’t print.
Current compiler warnings:
Q1.c: In function 'generate':
Q1.c:28: warning: implicit declaration of function 'time'
Q1.c:35: warning: implicit declaration of function 'dupe'
Q1.c: In function 'output':
Q1.c:61: warning: implicit declaration of function 'sort'
Q1.c: At top level:
Q1.c:68: warning: conflicting types for 'sort'
Q1.c:61: warning: previous implicit declaration of 'sort' was here
Q1.c: In function 'sort':
Q1.c:82: warning: implicit declaration of function 'deallocate'
Q1.c: At top level:
Q1.c:90: warning: conflicting types for 'deallocate'
Q1.c:82: warning: previous implicit declaration of 'deallocate' was here
The code is:
#include <stdio.h>
#include<stdlib.h>
#include<math.h>
int SIZE = 10;
static char c[] = "------------------------------\n";
struct student{
int id;
int score;
};
struct student* allocate(){
/*Allocate memory for ten students*/
struct student *s = malloc(SIZE* sizeof*s);
/*return the pointer*/
return s;
}
void generate(struct student* students){
/*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/
srand((unsigned int)time(NULL));
int id[SIZE];
int y;
for (int i = 0; i < SIZE; i++){
do{
y = rand() % SIZE + 1;
} while(dupe(id, i, y));
id[i] = y;
}
for (int j = 0; j < SIZE; j++){
students[j].id = id[j];
students[j].score = rand() % 101;
printf("ID: %d\tScore: %d\n", students[j].id, students[j].score);
}
}
int dupe(int id[], int SIZE1, int i){
for (int x = 0; x < SIZE1; x++){
if(id[x] == i)
return 1;
}
return 0;
}
void output(struct student* students){
/*Output information about the ten students in the format:
ID1 Score1
ID2 score2
ID3 score3
...
ID10 score10*/
sort(students);
printf("post sort students.\n %s", c);
for(int x = 0; x < SIZE; x++){
printf("ID: %d\tScore: %d\n", students[x].id, students[x].score); //print stmt not showing
}
}
void sort(struct student* students){
struct student *sd = allocate();
struct student *stud;
for(int i = 0; i < SIZE; i++){
stud = &students[i];
sd[stud->id -1] = *stud;
}
printf("sorted SD.\n %s", c);
for(int x = 0; x < SIZE; x++){
printf("ID: %d\tScore: %d\n", sd[x].id, sd[x].score); //print stmt not showing
}
students = sd;
deallocate(sd);
}
void summary(struct student* students){
/*Compute and print the minimum, maximum and average scores of the ten students*/
}
void deallocate(struct student* stud){
/*Deallocate memory from stud*/
free(stud);
}
int main(){
struct student* stud = NULL;
/*call allocate*/
stud = allocate();
/*call generate*/
generate(stud);
/*call output*/
printf("%s", c);
output(stud);
/*call summary*/
/*call deallocate*/
deallocate(stud);
return 0;
}
“My printf statements aren’t showing up on the console”
Are you sure that your program didn’t crash before it got that far?
Since
studhas typestudent*,&studhas typestudent**, but you are passing it to functions that expectstudent*… just passstud, not&stud. Turn on warnings in your compiler and it will tell you about such things.This is improper practice.
assertshould only be used to test for logic errors, not for normal failure conditions such as out of memory.This is ok, but I recommend
as it is less verbose and doesn’t depend on the type.
In C, this is not a constant (and doesn’t become one by adding a
constkeyword). Since you use it as the size of local arrays, you are invoking the VLA (variable-length array) feature that is not available in all C compilers. In C, it’s more normal to door
This is going to cause you trouble:
(aside from the fact that it should say “1 and SIZE”). You allocate a SIZE element array and then use your student IDs as indices, but only 0..SIZE-1 are valid indices … SIZE is not. So you need to index by
student->id - 1, or make your IDs 0-indexed.That can be written as
However, I don’t think this does what you want it to do. You’re assuring that the student ID is different from the index, but there’s no reason to do that. What you want to assure is that no two student IDs are the same, but you aren’t doing that. One possibility is to scan all the previously assigned IDs and pick another one if it was already assigned. Another way is to put all the IDs, 1 .. SIZE, in an array, then pull items out of the array at random, moving the top element of the array into that slot and decreasing the size of the array by 1 until you’ve emptied the array and assigned all the IDs.
C has some equivalence rules:
*(x + y)===x[y], andx->y===(*x).y. So,(students + j)->id===(*(students + j)).id===students[j].id, which is the preferred way to write that.This statement doesn’t do anything since
studentsisn’t used after it, and it’s a type error (&sdhas typestudent**), which, again, your compiler will warn you about if you turn on warnings (-Wall for gcc).What you’re trying to do here is change students in the caller, but this doesn’t do that. You need to either pass the address of students in (i.e., have a
struct student** pstudentsargument which you then dereference to getstudents) or, better,returnthe new array (which must not be deallocated until you’re done using it).This list of issues is not necessarily exhaustive.