C言語の構造体配列をソートする
Q. 構造体の配列をソートしたいんやけど、どしたらええのん?
A. qsort使えばできるやで!
構造体配列をqsortでソートする
qsort()の引数は以下のような感じ。
qsort(配列, 配列数, 型のサイズ, ソートする関数);
qsortがちょっと敷居高く感じるのは、ソートする関数を自作しないといけない点。
でも、昇順、降順程度だったらif文で判定して正の値か負の値かを返せば良いだけなので、実は簡単。
以下に、出席番号とテストの点数が入った構造体配列を、成績の良かった順に並べ替えるサンプルコードを載せる。
コード内のコメントを見たらすぐわかると思う。
■サンプルプログラム(qsort_sample.c)
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int studentNumber; // 出席番号
int testScore; // 成績
} gradebook_t;
// qsortで判定するための関数を自作する
// 自作するといっても別に難しいことはしてない
// 引数のaとbを比較して昇順にしたいのであれば正の値を、降順にしたいのであれば負の値を返却すればいいだけ
// 今回はテストの点数が高い順に並べたい(降順)から、aのほうが大きいときに-1を返すようにしている
// あんま頭の中で難しく考えず、実際にやってみてif文の条件を変えたりすればいい
int compar(const void* a, const void* b) {
if (((gradebook_t*)a)->testScore > ((gradebook_t*)b)->testScore) {
return -1; // 降順なので負の値(-1)を。もし昇順にしたいなら正の値(1)を返せばよい
} else {
return 1; // 上とは逆の値を返す。
}
}
int main()
{
gradebook_t gbook[10] = {};
// データ作成
for (int i = 0; i < 10; i++) {
gbook[i].studentNumber = i+1;
gbook[i].testScore = rand() % 100;
}
// ソート前
for(int i = 0; i < 10; i++) {
printf("出席番号:%2d, 成績:%3d\n", gbook[i].studentNumber, gbook[i].testScore);
}
// 成績でソート
qsort(gbook, 10, sizeof(gradebook_t), compar);
// ソート後
printf("\n->\n\n");
for(int i = 0; i < 10; i++) {
printf("出席番号:%2d, 成績:%3d\n", gbook[i].studentNumber, gbook[i].testScore);
}
return 0;
}
■実行結果
$ gcc qsort_sample.c -o qsort_sample
$ ./qsort_sample
出席番号: 1, 成績: 83
出席番号: 2, 成績: 86
出席番号: 3, 成績: 77
出席番号: 4, 成績: 15
出席番号: 5, 成績: 93
出席番号: 6, 成績: 35
出席番号: 7, 成績: 86
出席番号: 8, 成績: 92
出席番号: 9, 成績: 49
出席番号:10, 成績: 21
->
出席番号: 5, 成績: 93
出席番号: 8, 成績: 92
出席番号: 7, 成績: 86
出席番号: 2, 成績: 86
出席番号: 1, 成績: 83
出席番号: 3, 成績: 77
出席番号: 9, 成績: 49
出席番号: 6, 成績: 35
出席番号:10, 成績: 21
出席番号: 4, 成績: 15
以上!