機能を使用したいqsort()
。
qsort(base, num_of_elements, element_size, my_compare);
比較関数my_compare
は 2 つの引数 (それぞれ a ) を取りconst void *
、引数の相対的な順序を示す数値を返します。負の数は、最初の引数が 2 番目の引数の前にあることを意味します。正の数は、最初の引数が 2 番目の引数の後にあることを意味します。引数が等しいと比較された場合、ゼロが返されます。
文字列比較では大文字と小文字が区別されないため、独自の比較関数を作成するか、C ライブラリに含まれていないシステムから提供された関数を見つける必要があります。POSIX はstrcasecmp()
この目的のために_stricmp()
用意されています (Google によると、これは Windows で利用可能です)。
int my_compare (const void *a, const void *b) {
return strcasecmp(a, b);
}
通常、比較関数の定義は、 を使用する上で最も難しい部分ですqsort()
。その関数に渡されるポインターのコンテキストを理解する必要があります。の配列TYPE
が に渡されると、比較関数の各引数へqsort()
のポインタが渡されます。const TYPE
あなたの場合、MAX_CHAR_LEN
char
s の配列の配列を渡します。したがって、比較関数の各引数は、MAX_CHAR_LEN
char
s の const 配列へのポインターです。これは、技術的には、my_compare
関数を次のように記述する必要があることを意味します。
int my_compare (const void *a, const void *b) {
typedef char TYPE[MAX_CHAR_LEN];
const TYPE *aa = (const TYPE *)a;
const TYPE *bb = (const TYPE *)b;
return strcasecmp(*aa, *bb);
}
C が定数配列の概念を実際にサポートしていないことを除いて、引数のキャストは通常は必要ありません。そのようなものを定数の配列に変換するため、キャストはそれを反映する必要があります。
ただし、配列のアドレスは、その最初の要素のアドレスと同じです。つまり、上記のコードの場合、次のアサーションが true になります。
assert(aa == (const void *)*aa);
assert(bb == (const void *)*bb);
したがって、配列へのポインターの逆参照は、同じ配列の減衰したアドレス値と等しいmy_compare()
ため、2 次元配列には の最初の実装で十分です。