【C言語】qsort()関数のコンパレータ関数の書き方と使い方を徹底解説
C言語では、標準ライブラリとして提供されている qsort() 関数を使うことで、クイックソートのアルゴリズムによる配列の並べ替えを簡単に行うことができます。この関数を利用する際には、要素同士の大小関係を判定するための「コンパレータ(比較)関数」を自分で定義して渡す必要があります。
コンパレータ関数とは
コンパレータ関数は、ソート対象となる2つの要素を受け取り、それらの相対的な順序を返す役割を持つ関数です。引数はいずれもポインタ型で、const void* にキャストして受け取るのが特徴です。
基本的な構文は以下の通りです。
int comparator(const void* p1, const void* p2);
戻り値の意味
コンパレータ関数の戻り値は、次の3つのケースに分けられます。
- 0より小さい場合: p1が指す要素が、p2が指す要素よりも前に配置されます。
- 0の場合: 2つの要素は同じ順序(同等)とみなされます。
- 0より大きい場合: p1が指す要素が、p2が指す要素よりも後に配置されます。
サンプルコード:構造体配列を価格順にソートする
ここでは、「書籍名・ページ数・価格」を持つ構造体の配列を、価格の昇順に並べ替える例を紹介します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char title[50];
int pages;
float price;
} book;
/* 価格を比較するコンパレータ関数 */
int compareBook(const void* p1, const void* p2) {
book* b1 = (book*)p1;
book* b2 = (book*)p2;
if (b1->price < b2->price) {
return -1; /* b1 を前に置く */
}
if (b1->price > b2->price) {
return 1; /* b1 を後ろに置く */
}
return 0; /* 同じ価格 */
}
int main(void) {
int i;
book book_arr[5];
strcpy(book_arr[0].title, "C Programming");
book_arr[0].pages = 260;
book_arr[0].price = 450;
strcpy(book_arr[1].title, "DBMS Guide");
book_arr[1].pages = 850;
book_arr[1].price = 775;
strcpy(book_arr[2].title, "Learn C++");
book_arr[2].pages = 350;
book_arr[2].price = 520;
strcpy(book_arr[3].title, "Data Structures");
book_arr[3].pages = 380;
book_arr[3].price = 430;
strcpy(book_arr[4].title, "Learn Python");
book_arr[4].pages = 500;
book_arr[4].price = 300;
/* 配列の先頭アドレス・要素数・要素サイズ・コンパレータを渡す */
qsort((void*)book_arr, 5, sizeof(book_arr[0]), compareBook);
for (i = 0; i < 5; i++) {
printf("%s\t\t%d\t\t%f\n",
book_arr[i].title,
book_arr[i].pages,
book_arr[i].price);
}
return 0;
}実行結果
Learn Python 500 300.000000 Data Structures 380 430.000000 C Programming 260 450.000000 Learn C++ 350 520.000000 DBMS Guide 850 775.000000
ポイントまとめ
qsort()の第4引数には、int (*)(const void*, const void*)というシグネチャを持つ関数へのポインタを渡します。- コンパレータ内では、
void*ポインタを実際のデータ型(ここではbook*)にキャストしてからメンバにアクセスします。 - 昇順にしたい場合は「小さいときに負の値」、降順にしたい場合は「大きいときに負の値」を返すように戻り値を逆にすればOKです。
このようにコンパレータ関数のロジックを変えるだけで、任意の基準(価格・ページ数・文字列など)での柔軟なソートが実現できます。
-
PHPのpi()関数とは?使い方と定義済み定数との対応を実例付きで解説
pi()関数の定義と使い方PHPのpi()関数は、数学定数π(円周率)の値を返す関数です。戻り値はfloat型の「3.14159265359」であり、PHPにあらかじめ定義されている定数M_PIとまったく同じ値になります。構文pi ( void ) : floatパラメータこの関数は引数を受け取りません。引数なしでそのまま呼び出すことができます。戻り値pi()関数は数学定数πの値を返し、定義済みの数学定数M_PIと等価です。数式の中では、M_PIの代わりにpi()関数を使うこともできます。対応するPHPバージョンこの関数はPHP 4.x、PHP 5.x、PHP 7.xのすべてのバージョンで利用
-
Python Pandas入門 – DataFrameのtail()関数で末尾の行を抽出する方法
products.csvファイルを読み込み、price(価格)列の値が30,000〜50,000の範囲に含まれる行を抽出したうえで、その中から最後の3行の「id」列と「product」列を表示するPythonコードを紹介します。なお、DataFrame.tail(n)はDataFrameの末尾n行を取得できる便利なメソッドで、解法2ではこのtail()関数を活用します。 期待される出力結果 price列の値が30,000〜50,000の範囲にある行のうち、id列とproduct列の最後の3行は次のようになります。 id product 79 80 Truck 81 82 Bike 9