尝试使用整个结构将最高等级排序到最低等级

时间:2015-10-23 15:01:21

标签: c arrays sorting struct typedef

我制作了一个学生的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]);
    }
}

2 个答案:

答案 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 intint