こんにちは、もがちゃんです。
今回は、C言語でソート処理を実装する時に使用するqsortの使い方を簡単なサンプルソースとともに説明します。
目次
qsortの構文
#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
qsortの説明
qsortは、baseで指定されたnmemb個のソート対象要素をソートします。
qsort関数は、先頭の要素をbaseが指すnmemb個のオブジェクトの配列を整列する。各オブジェクトの大きさは、sizeで指定する。
JISX3010 プログラム言語C
base
ソート対象要素の先頭ポインタを指定します。
nmemb
ソート対象要素の個数を指定します。
size
ソート対象要素1個分のバイトサイズを指定します。
compar
要素を比較する関数のポインタを指定します。
指定する関数のポインタは、以下の値を返す関数のポインタを指定します。
- 最初の実引数が2番目の実引数より小さい場合は、0未満の値を返します。
- 最初の実引数と2番目の実引数が同じ場合は、0を返します。
- 最初の実引数が2番目の実引数より大きい場合は、0より大きい値を返します。
qsortの使い方サンプル
qsortを使用して文字列をソートするサンプルプログラムを紹介します。
サンプルプログラムと実行結果
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printBase(const char *msg, char **base, int n);
int compare(const void *p1, const void *p2);
int main(void) {
/* ソート対象とする文字列ポインタの配列 */
char *base[] = {
"Z1234123",
"A1235123",
"a1234123",
"a1234",
"B1234",
"abcde",
"ab",
"12345",
"*@@@1",
"00000"
};
printBase("before qsort", base, 10);
qsort(base, 10, sizeof(char*), compare);
printBase("\nafter qsort", base, 10);
}
/* 比較関数:strcmpで比較 */
int compare(const void *p1, const void *p2) {
/* p1,p2 : 文字列の先頭ポインタが格納されているポインタ */
uintptr_t a1 = *(uintptr_t*)p1;
uintptr_t a2 = *(uintptr_t*)p2;
/* pp1,pp2 : 文字列の先頭ポインタ */
volatile char *pp1 = (char *)a1;
volatile char *pp2 = (char *)a2;
return strcmp((const char*)pp1, (const char*)pp2);
}
/* ソート確認用 */
void printBase(const char *msg, char **base, int n) {
fprintf(stdout, "%s\n", msg);
for(int i = 0; i < n; i++, base++) {
fprintf(stdout, "[%d][%s]\n", i, *base);
}
}
※uintptr_tは、ポインタを格納するために十分な領域が確保できる符号なし整数型で、inttypes.hで定義されています。
qsortの使い方まとめ
- qsortを使用する場合、各要素を比較するために使用する関数のポインタを指定する必要がある。
- ソート対象の要素は、base、nmemb、sizeで指定する。
- baseには、ソート対象となる要素の先頭を指すポインタを指定する。
- nmembには、ソート対象とする要素の個数を指定する。
- sizeには、1要素辺りのバイトサイズを指定する。
- qsortでソートを実行した後は、baseが指す領域は変更(ソート)されてしまうので、変更前の状態を残しておきたい場合は、事前にコピーをしておくか、baseにコピーした領域の先頭を指すポインタを指定する。