C 言語でのソート関数
この記事では、標準ライブラリのソート関数を C 言語で使用する方法をいくつか説明します。
関数 qsort
を使って C 言語で整数の配列をソートする
関数 qsort
は、異なるデータ要素の配列に対する多少汎用的なソート操作を実装しています。つまり、qsort
は第 4 引数として関数へのポインタを受け取り、与えられた要素の配列に対する比較関数を渡す。今回は、qsort
を用いて整数配列を比較するために intCompare
関数を実装しました。なお、intCompare
は qsort
プロトタイプで指定された型 - int (*compar)(const void *, const void *)
を持つ必要があります。その結果、まず p1
/p2
の引数を int
ポインタにキャストしてから、それらを参照して値そのものにアクセスします。比較関数の戻り値は、最初のパラメータが他のパラメータよりも小さい場合は 0 よりも小さい整数、最初のパラメータが 2 番目のパラメータよりも大きい場合は 0 よりも大きく、2つのパラメータが等しい場合は 0 でなければなりません。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int intCompare(const void *p1, const void *p2) {
int int_a = *((int *)p1);
int int_b = *((int *)p2);
if (int_a == int_b)
return 0;
else if (int_a < int_b)
return -1;
else
return 1;
}
void printIntegers(int arr[], size_t size) {
for (size_t i = 0; i < size; i++) printf("%4d | ", arr[i]);
printf("\n");
}
int main(int argc, char *argv[]) {
int arr2[] = {53, 32, 12, 52, 87, 43, 93, 23};
printIntegers(arr2, 8);
qsort(arr2, 8, sizeof(int), intCompare);
printIntegers(arr2, 8);
exit(EXIT_SUCCESS);
}
出力:
53 | 32 | 12 | 52 | 87 | 43 | 93 | 23 |
12 | 23 | 32 | 43 | 52 | 53 | 87 | 93 |
関数 qsort
を用いて C 言語で文字列の配列を並べ替える
qsort
は文字列配列を昇順に並べ替えることができ、比較関数として strcmp
を用います。この例では、char
ポインタの配列を宣言して初期化し、その要素を qsort
関数を呼び出すだけでソートします。比較関数は両方のパラメータを void
ポインタ型として受け取るので、キャストと参照解除は必要な部分であることに注目してください。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int stringCompare(const void *p1, const void *p2) {
return strcmp(*(char *const *)p1, *(char *const *)p2);
}
void printStrings(char *arr[], size_t size) {
for (size_t i = 0; i < size; i++) printf("%10s | ", arr[i]);
printf("\n");
}
int main(int argc, char *argv[]) {
char *arr[] = {"jello", "hello", "mello", "zello", "aello"};
printStrings(arr, 5);
qsort(arr, 5, sizeof(char *), stringCompare);
printStrings(arr, 5);
exit(EXIT_SUCCESS);
}
出力:
jello | hello | mello | zello | aello |
aello | hello | jello | mello | zello |
あるいは、先ほどのサンプルコードを再実装して、ユーザがプログラムの引数として文字列配列を与え、ソートされた配列を出力として出力することもできます。今回は、qsort
を呼び出す前に、ソートするのに十分な引数が渡されているかどうかを確認することが重要です。なお、stringCompare
関数は strcmp
コールの値を直接返すことに注意してください。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int stringCompare(const void *p1, const void *p2) {
return strcmp(*(char *const *)p1, *(char *const *)p2);
}
void printStrings(char *arr[], size_t size) {
for (size_t i = 0; i < size; i++) printf("%10s | ", arr[i]);
printf("\n");
}
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Usage: ./program string_0 string_1 string_2...\n");
exit(EXIT_FAILURE);
}
printStrings(argv + 1, argc - 1);
qsort(argv + 1, argc - 1, sizeof(char *), stringCompare);
printStrings(argv + 1, argc - 1);
exit(EXIT_SUCCESS);
}