hob*_*131 3 c sorting struct pointers
这是对这个问题的跟进:
我修改了修改后的代码,我认为排序应该正常,但我觉得我没有正确使用指针.我的printf语句没有出现在控制台上,它们在注释中标出.
我是C的新手,所以这可能是显而易见的,但我只是在打印不打印时如何调试.
当前的编译器警告:
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
Run Code Online (Sandbox Code Playgroud)
代码是:
#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;
}
Run Code Online (Sandbox Code Playgroud)
Jim*_*ter 10
"我的printf语句没有显示在控制台上"
你确定你的程序在它到达之前没有崩溃吗?
既然stud有类型student*,&stud有类型student**,但是你把它传递给期望的函数student*......只是通过stud,而不是&stud.打开编译器中的警告,它会告诉你这些事情.
assert(s != 0);
Run Code Online (Sandbox Code Playgroud)
这是不正确的做法.assert应仅用于测试逻辑错误,而不是用于正常故障情况,例如内存不足.
struct student *s = malloc(size*(sizeof(struct student)));
Run Code Online (Sandbox Code Playgroud)
这没关系,但我建议
struct student* s = malloc(size * sizeof *s);
Run Code Online (Sandbox Code Playgroud)
因为它不那么冗长,也不依赖于类型.
static int size = 10;
Run Code Online (Sandbox Code Playgroud)
在C中,这不是常量(并且通过添加const关键字不会成为常量).由于您将其用作本地数组的大小,因此您正在调用所有C编译器中都不可用的VLA(可变长度数组)功能.在C中,这样做更为正常
#define SIZE 10
Run Code Online (Sandbox Code Playgroud)
要么
enum { SIZE = 10 };
Run Code Online (Sandbox Code Playgroud)
这会给你带来麻烦:
ID being between 1 and 10
Run Code Online (Sandbox Code Playgroud)
(除了它应该说"1和SIZE"这一事实).您分配一个SIZE元素数组,然后使用您的学生ID作为索引,但只有0..SIZE-1是有效索引... SIZE不是.所以你需要索引student->id - 1,或者让你的ID被索引.
y = rand() % size + 1;
while(dupe(id, i, y)){
y = rand() % size + 1;
}
Run Code Online (Sandbox Code Playgroud)
这可以写成
do
{
y = rand() % size + 1;
} while(dupe(id, i, y));
Run Code Online (Sandbox Code Playgroud)
但是,我认为这不符合您的要求.您确定学生ID与索引不同,但没有理由这样做.您要保证的是,没有两个学生ID是相同的,但您没有这样做.一种可能性是扫描所有先前分配的ID,如果已经分配了ID,则选择另一个ID.另一种方法是将所有ID,1 .. SIZE放在一个数组中,然后随机将数据从数组中拉出,将数组的顶部元素移动到该插槽中,并将数组的大小减小1,直到你'已清空阵列并分配了所有ID.
(students + j)->id
Run Code Online (Sandbox Code Playgroud)
C有一些等价规则:*(x + y)=== x[y]和x->y=== (*x).y.所以,(students + j)->id=== (*(students + j)).id=== students[j].id,这是写它的首选方式.
students = &sd;
Run Code Online (Sandbox Code Playgroud)
这个语句没有做任何事情,因为students它没有在它之后使用,而且它是一个类型错误(&sd有类型student**),如果你打开警告(-Wall for gcc),你的编译器也会警告你.
你在这里要做的是改变呼叫者的学生,但这不是那样做的.您需要传递学生的地址(即,有一个struct student** pstudents参数然后取消引用才能获得students),或者更好的是,return新数组(在您使用它之前不得取消分配).
这份问题清单不一定是详尽无遗的.
| 归档时间: |
|
| 查看次数: |
360 次 |
| 最近记录: |