コンテンツにスキップ

Top

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

以上!