2017-04-08 62 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(&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'已經是'學生*'s,並且您將它們投射到'學生*'s。但是,當你不得不施放函數指針類型時,這是一個大紅旗。你應該做一個匹配'qsort'的函數,不要給它別的東西,假裝它是它想要的。 – chris

+3

請注意,使用'qsort'對不是不可複製的類型是未定義的行爲。我知道你說你不想使用'std :: sort',但你真的應該這樣做。此外,您沒有定義複製構造函數,因此您將泄漏內存和/或獲取雙精度刪除,這也是未定義的行爲。總而言之,如果您打算使用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

仍然不能正常工作:(但第一個學生名稱發生了某些變化,其名稱的前3個字母缺失或有時被重複。 – AndreiD

+0

@AndreiD:還有一個問題,我編輯了我的答案。 –

+0

你真了不起! 問題解決了 :) – AndreiD