2017-04-08 3 views
1

C++ : 평균 미디어로 클래스에 저장된 일부 학생을 정렬하려고합니다.C++ qsort를 사용하여 클래스 배열 정렬

qsort만이 std :: sort의 조언을 제공하지 않습니다. 감사합니다.

를 qsort 기능 비교 :

int cmp(Student *a, Student *b) { 
    return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media()); 
} 

qsort가 호출 :

qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp); 

에는 컴파일러 오류가 없습니다, 그러나 분류되지 않습니다.

#define _CRT_SECURE_NO_WARNINGS 
#include <iostream> 
using namespace std; 

class Student { 
private: 
    char name[20]; 
    char surname[20]; 
    int *marks; 
    int group; 
    float avg_mark; 
public: 
    Student() 
    { 
     char na[20], sur[20]; 
     int group; 
     cout << "\nEnter name: "; 
     cin >> na; 
     cout << "\nEnter surname: "; 
     cin >> sur; 
     cout << "\nEnter group: "; 
     cin >> group; 
     init(na, sur, group); 
    } 
    ~Student() 
    { 
     cout << "\ndestructor"; 
     delete []marks; 
    } 
    void init(char *n, char *p, int gr) 
    { 
     strcpy(name, n); 
     strcpy(surname, p); 
     group = gr; 
     marks = new int[6]; 
     for (int i = 0; i < 6; i++) 
     { 
      cout << "\nEnter mark " << i + 1 << ": "; 
      cin >> *(marks + i); 
     } 
     avg_mark = media(); 
    } 
    float media() 
    { 
     int s = 0; 
     for (int i = 0; i < 6; i++) 
      s += marks[i]; 
     return ((float)s/6); 
    } 
    void set_name(char *n) 
    { 
     strcpy(name, n); 
    } 
    char* get_name() 
    { 
     return name; 
    } 
    void set_surname(char *p) 
    { 
     strcpy(name, p); 
    } 
    char* get_surname() 
    { 
     return surname; 
    } 
    int get_group() 
    { 
     return group; 
    } 
    float get_media() 
    { 
     return avg_mark; 
    } 
}; 

int cmp(Student *a, Student *b); 

int comparator(void *a, void *b) { 
    return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media()); 
} 



void main(void) 
{ 
    int n; 
    cout << "\nEnter n: "; 
    cin >> n; 
    Student *tab = new Student[n]; 
    for (int i = 0; i < n; i++) 
     cout << i + 1 << ". " << tab[i].get_name() << " " << tab[i].get_surname() << " Group:" << tab[i].get_group() << " Average mark: " << tab[i].get_media() << endl; 
    //qsort(&tab[0], (size_t)n, sizeof(tab), (int*)cmp); 
    cout << endl; 
    qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp); 
    for (int i = 0; i < n; i++) 
     cout << i + 1 << ". " << tab[i].get_name() << " " << tab[i].get_surname() << " Group:" << tab[i].get_group() << " Average mark: " << tab[i].get_media() << endl; 
    cin.ignore(); 
    cin.get(); 
} 

int cmp(Student *a, Student *b) { 
    return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media()); 
} 
+3

'a'와'b'는 이미'Student *'이고'Student *'로 캐스팅하고 있습니다. 그러나 함수 포인터 타입을 형변환해야 할 때, 그것은 큰 붉은 깃발입니다. 'qsort'와 일치하는 함수를 만들어야하며, 다른 것을주지 말고 그것이 원하는 것처럼 가장해야합니다. – chris

+3

trivially copyable하지 않은 타입에서'qsort'를 사용하는 것은 정의되지 않은 동작입니다. 나는 당신이'std :: sort'를 사용하기를 원하지 않는다고 말하는 것을 알고 있지만 정말로해야한다. 또한 복사 생성자가 정의되어 있지 않아 메모리 누출 및/또는 정의되지 않은 동작 인 double을 삭제할 수 있습니다. 전체적으로 C++을 사용한다면 C++을 사용해야하고 C와 C++을 함께 사용하지 않아야합니다. 문제는'std :: vector','std : string','std :: sort'를 사용하여 해결할 수 있습니다. – NathanOliver

+0

해당 캐스트가 없으면 코드를 실행하는 동안 오류가 발생합니다. 어느 쪽이 더 큰지를 리턴하는 클래스 내부의 메소드 함수를 추천 하시겠습니까? 함수의 결과는 cmp 함수에 의해 반환되거나 qsort 호출에서 직접 사용되어야합니까? – AndreiD

답변

0
qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp); 

&tab 포인터 tab의 주소입니다. 배열의 첫 번째 요소의 주소를 전달하려고합니다. 그것은 &tab[0]이거나 간단히 tab입니다.

또한 포인터의 크기가 아니라 Student 개체의 크기를 전달해야합니다. 따라서 sizeof(tab)sizeof(Student) 또는 sizeof(*tab)으로 변경하십시오. 따라서 호출은 다음과 같아야합니다 :

qsort(tab, (size_t)n, sizeof(*tab), (int(*)(const void*, const void*))cmp); 
+0

아직 작동하지 않습니다 : (그러나 뭔가가 첫 번째 학생 이름에 발생하며 그 이름의 처음 세 글자가 누락되거나 때때로 중복됩니다.) – AndreiD

+0

@AndreiD : 한 가지 더 문제가 있습니다. 내 대답을 편집했습니다. –

+0

놀랍습니다. ! 문제 해결됨 :) – AndreiD