我制作了一个学生的typdef结构,包括学生ID,ClassId,currentGrade和lettergrade。
现在我要排序从最高到最低等级。我已经完成了,但struct的其他部分没有用它排序。如何使结构与排序保持一致?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
short id;
short enrolledClassID;
float currentGrade;
char letterGrade;
} Student;
void printStudentInfo(Student student);
void printStudentArray(Student* student,int sizeOfArray);
void sortByGrade(Student* student,int sizeOfArray);
int main()
{
Student studentArray[5] = {
{25,278,95,'A'},
{ 27,278,56,'F' },
{ 29,321,74,'C' },
{ 31,321,63,'D' },
{ 15,278,81,'B' }
};
Student* pStudents = &studentArray;
printStudentArray(pStudents,5);
sortByGrade(pStudents, 5);
printStudentArray(pStudents, 5);
//studentArray[0].currentGrade;
system("Pause");
}
void sortByGrade(Student* student, int sizeOfArray) {
int min, i;
Student temp;
while (sizeOfArray > 0)
{
min = 0;
for (i = 1; i < sizeOfArray; i++)
if (student[i].currentGrade < student[min].currentGrade)
min = i;
temp.currentGrade = student[sizeOfArray - 1].currentGrade;
student[sizeOfArray - 1].currentGrade = student[min].currentGrade;
student[min].currentGrade = temp.currentGrade;
sizeOfArray--;
}
}
void printStudentInfo(Student student) {
printf("The student ID is %i, class ID is %i, current grade in class is %0.2f\n, and letter grade is %c\n", student.id, student.enrolledClassID,student.currentGrade,student.letterGrade);
}
void printStudentArray(Student* student,int sizeOfArray) {
for (int i = 0; i < sizeOfArray; i++) {
printStudentInfo(student[i]);
}
}
答案 0 :(得分:1)
你只是在当前等级附近移动,而不是整个结构。所以不要这样:
temp.currentGrade = student[sizeOfArray - 1].currentGrade;
student[sizeOfArray - 1].currentGrade = student[min].currentGrade;
student[min].currentGrade = temp.currentGrade;
这样做:
temp= student[sizeOfArray - 1];
student[sizeOfArray - 1] = student[min];
student[min] = temp;
答案 1 :(得分:0)
使用qsort()对数组进行排序并不困难。第一个参数是数组本身,第二个是数组中元素的数量,第三个是每个数组元素的大小(sizeof (Student)
),第四个是一个函数指针,如果比较则返回-1元素的顺序是正确的,如果相等则为0,如果顺序错误,则为+1。
所以:
int compareByGrade(const void *ptr1, const void *ptr2)
{
const Student *const s1 = ptr1;
const Student *const s2 = ptr2;
if (s1->currentGrade > s2->currentGrade)
return -1; /* Correct order */
else
if (s1->currentGrade < s2->currentGrade)
return +1; /* Wrong order */
else
return 0; /* Same grade */
}
虽然我个人想把它重写为
int compareByGrade(const void *ptr1, const void *ptr2)
{
const float val1 = ((const Student *)ptr1)->currentGrade;
const float val2 = ((const Student *)ptr2)->currentGrade;
return (val1 > val2) ? -1 : (val1 < val2) ? +1 : 0;
}
完全相同,但表达更简洁。使用您发现的更容易阅读,理解和维护的(从长远来看)。
在这两种情况下,sortByGrade()
功能都只是
void sortByGrade(Student *const array, const size_t elements)
{
if (array != NULL && elements > 1)
qsort(array, elements, sizeof array[0], compareByGrade);
}
请注意,对于非负内存大小,应使用size_t
类型 - size_t
通常是无符号的(不能表示负值) - ,例如数组中的元素数,数组索引,字符串长度, 等等。这是该类型的目的。
在当前的64位体系结构中,int
只有32位,所以如果你习惯使用int
来获取内存大小,那么你的代码只能引用2 GB记忆对于旧程序来说,这是一个真正的问题,因为他们的程序员并不认为它会成为一个问题。 (实际上,Linux内核必须一次将文件写入限制在2GB以内。)
所以,请比那些有问题的老式程序员更好,并学习如何使用size_t
代替unsigned int
或int
。