今回は、qsort を使ってソートするプログラム例です。
qsort はいろいろな配列をいろいろな条件でソートすることができますが、下記では int 配列を昇順にソートします。
void qsort( void *base, size_t n, size_t size, int (*comp)(const void *, const void *) )ひとつの要素の大きさが size である n個の要素をソートします。要素の先頭は base に指定します。 comp には比較用の関数へのポインタを指定します。 qsort は実行時に、比較したい2つの要素を指すポインタを関数 comp に渡して大小を調べます。
void へのポインタ2つを引数に取るもので、戻り値は両要素の大小の判定結果を示します。 第1引数 > 第2引数のとき正の値を戻すようにすると、昇順のソートになります。
【 qsort を使ったプログラム例 】
#include <stdio.h>
#include <stdlib.h>
// -- 比較用の関数 cmp --
int cmp( const void *p, const void *q ) {
return *(int*)p - *(int*)q;
}
// ---------------------------------------
main()
{
int ages[] = { 21, 18, 53, 43, 14, 24, 38 };
int n, i;
n = sizeof( ages )/sizeof( int );
qsort( ages, n, sizeof(int), cmp );
for( i = 0; i < n; i++ )
printf( "ages[%d] = %d\n", i, ages[i] );
}
実行結果
ages[0] = 14 ages[1] = 18 ages[2] = 21 ages[3] = 24 ages[4] = 38 ages[5] = 43 ages[6] = 53
cmp では、比較するものが int型の配列要素だと分かっているので、void へのポインタ p と q を int へのポインタにキャストして比べています。
return *(int*)p - *(int*)q と書くだけで、昇順ソートの比較結果を返すことができます。たとえば 21 と 18 の比較なら正の値 3 が、18 と 53 の比較なら -35 の負の値が返ります。それを見て、必要なら qsort が並べ替えます。
qsort がその本領を発揮するのは構造体のソートです。
それはまた別の Tips で。
int cmp( const void *p, const void *q ) {
return *(double*)p - *(double*)q; //NG!
}
これは正しくありません。なぜでしょう?
また、どのような比較をすればよいでしょう?
[ 関連記事 ] 構造体配列をqsort, ポインタ配列をqsort
[ ご案内 ] ポインタの要点を学習できるコース:要点講座 [配列とポインタ編]
char *dayname[] ・・・ 定数文字列が取られ、その領域へのポインタの配列。 char dayname[][8] ・・・ char配列の配列。[]内に指定したサイズで取られます。上は、文字列+'\0'分のピッタリサイズで取られます。定数扱いなので文字列の内容を変えられません。下は、サイズを超えなければ書き換え可能です。