Thinkers'Studio
JavaとC言語の自習ツール
qsort で構造体配列をソートする例

構造体配列のソートで力を発揮する qsort

 今回は、qsort を使って構造体の配列をソートするプログラム例です。
 qsort は配列要素の並べ替えを行う標準関数です(参考:int配列をソートするTips)。
 構造体メンバの値によって、配列全体を簡単に並べ替えることができるので、とても便利です。

qsort を使ったプログラム例 】
 チョコレートの商品リストの構造体配列 lst を価格順にソートします。
#include <stdio.h>
#include <stdlib.h>
#define NAMELEN 20

typedef struct {
    int hb;             //品番
    char name[NAMELEN]; //商品名
    int price;          //価格
} choco_t;

// --------------- 比較用の関数 cmp -------------------
int cmp( const void *p, const void *q ) {
    return ((choco_t*)p)->price - ((choco_t*)q)->price;
}

// ----------------------------------------------------
main()
{
    choco_t lst[] =
    { { 5200, "アーモンド", 1000 }, { 3010, "ラムレーズン", 840 }
    , { 2020, "ビター", 525 }, { 3020, "クランチ", 720 }
    , { 2030, "ホワイト", 500 }, { 2010, "ミルク", 450 }
    , { 5050, "マカダミア", 1200 } };
    int i;

    int n = sizeof lst / sizeof( choco_t );
    qsort( lst, n, sizeof(choco_t), cmp );
    printf( "価格順にソート\n" );
    for( i = 0; i < n; i++ )
       printf( "%4d円 (%d)%s\n"
       , lst[i].price, lst[i].hb, lst[i].name );
}
実行結果
価格順にソート
  450円 (2010)ミルク
  500円 (2030)ホワイト
  525円 (2020)ビター
  720円 (3020)クランチ
  840円 (3010)ラムレーズン
 1000円 (5200)アーモンド
 1200円 (5050)マカダミア

qsort の呼び出し

    qsort( lst, n, sizeof(choco_t), cmp );

 先頭から4つの引数は、並べ替え対象に関する指定  --> 配列lst(要素数はn、1要素の大きさは sizeof(choco_t))
 最後の引数は、比較に使う関数の指定  --> cmp を使ってメンバの値を比較する

cmp 関数の内容

 void へのポインタ p と q を比較対象の choco_tへのポインタにキャストして比べます。
 上のように、引数1 > 引数2 のときに正の値が返るようにすると、昇順ソートとなります。

 構造体のサイズが大きく要素数も大量にある配列の場合、上記のソートでは時間がかかる場合があります。そんなときの対応は、また別の Tips で。

(今週のクイズです)
 価格が同じときは、hb の順にソートするよう cmp 関数を変更するにはどうすればよいでしょう?
 (答えは、次回のC言語の Tips で ・・・)

[ 関連記事 ] ポインタや構造体の他の Tips は、Tips 一覧 で見ることができます。
[ ご案内 ] ポインタや構造体の要点を学習できるコース:要点講座 [配列とポインタ編]/[構造体編]

前回のクイズは自習でした