C & C++ FAQ
|
|
標準ライブラリqsort関数は、以下の形式をもっています。
#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
各引数に何を渡すかを、少しわかりやすくまとめるとると、以下のようになります。
- base
- ソートする配列の先頭要素へのポインタ。
- nmemb
- ソートする配列の要素数。
- size
- ソートする配列の要素の大きさ(バイト数)。int型の配列をソートするのであればsizeof(int)。
- compar
- いわゆる“比較関数”へのポインタです。比較関数は、プログラム側で用意します。この関数は、以下のように定義します。
- 比較の対象となる二つの要素へのポインタを受け取る(以下、それらをxおよびyとする)。
- int型の値を返す。
- xの指す要素が、yの指す要素より、小さい(ソート後により先頭側に位置する)のであれば、負の値を返す(値は何でもよい)。
- xの指す要素が、yの指す要素と同じであれば、0を返す。
- xの指す要素が、yの指す要素より、大きい(ソート後により末尾側に位置する)のであれば、正の値を返す(値は何でもよい)。
qsort関数を用いて、int型の配列を昇順にソートするプログラム例を以下に示す。
ソート前
1 3 2 9 8 6
ソート後
1 2 3 6 8 9 |
/*
qsort関数を用いて配列をソート
*/
#include <stdio.h>
#include <stdlib.h>
/*--- int型オブジェクトの比較関数 ---*/
int int_cmp(const int *a, const int *b)
{
if (*a < *b)
return (-1);
else if (*a > *b)
return (1);
return (0);
}
int main(void)
{
int i;
int x[] = {1, 3, 2, 9, 8, 6};
int nx = sizeof(x) / sizeof(x[0]); /* 配列xの要素数 */
puts("ソート前");
for (i = 0; i < nx; i++)
printf("%d ", x[i]);
qsort(x, nx, sizeof(int), (int(*)(const void*, const void*))int_cmp);
puts("\nソート後");
for (i = 0; i < nx; i++)
printf("%d ", x[i]);
return (0);
}
もしも、配列を値の降順でソートしたいのであればreturn (*y - *x)と変更しましょう。
次に、構造体をソートする例を以下に示します。ここでは、名前の昇順、身長の昇順、体重の降順の例を示しています。
ソート前
Shibata 170cm 52kg
Takaoka 180cm 70kg
Nangoh 172cm 63kg
名前昇順ソート後
Nangoh 172cm 63kg
Shibata 170cm 52kg
Takaoka 180cm 70kg
身長昇順ソート後
Shibata 170cm 52kg
Nangoh 172cm 63kg
Takaoka 180cm 70kg
体重降順ソート後
Takaoka 180cm 70kg
Nangoh 172cm 63kg
Shibata 170cm 52kg
|
/*
qsort関数を用いて配列をソート
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[10]; /* 名前 */
int height; /* 身長 */
int weight; /* 体重 */
} person;
/*--- person型オブジェクトの比較関数(名前昇順) ---*/
int npcmp(const person *x, const person *y)
{
return (strcmp(x->name, y->name));
}
/*--- person型オブジェクトの比較関数(身長昇順) ---*/
int hpcmp(const person *x, const person *y)
{
return (x->height < y->height ? -1 :
x->height < y->height ? 1 : 0);
}
/*--- person型オブジェクトの比較関数(体重降順) ---*/
int wdcmp(const person *x, const person *y)
{
return (x->height < y->height ? 1 :
x->height < y->height ? -1 : 0);/* 降順 */
}
/*--- 一人分のデータを表示 ---*/
void print_person(person x)
{
printf("%-10.10s %dcm %dkg\n", x.name, x.height, x.weight);
}
int main(void)
{
int i;
person x[]= {{"Shibata", 170, 52},
{"Takaoka", 180, 70},
{"Nangoh", 172, 63},
};
int nx = sizeof(x) / sizeof(x[0]); /* 配列xの要素数 */
puts("ソート前");
for (i = 0; i < nx; i++)
print_person(x[i]);
/* 名前昇順にソート */
qsort(x, nx, sizeof(person), (int(*)(const void*, const void*))npcmp);
puts("\n名前昇順ソート後");
for (i = 0; i < nx; i++)
print_person(x[i]);
/* 身長昇順にソート */
qsort(x, nx, sizeof(person), (int(*)(const void*, const void*))hpcmp);
puts("\n身長昇順ソート後");
for (i = 0; i < nx; i++)
print_person(x[i]);
/* 体重降順にソート */
qsort(x, nx, sizeof(person), (int(*)(const void*, const void*))wdcmp);
puts("\n体重降順ソート後");
for (i = 0; i < nx; i++)
print_person(x[i]);
return (0);
}
■ 根拠 ■
標準C
| §7.10.5.2
| The qsort function
|
標準C99
| §7.20.5.2
| The qsort function
|
標準C++
| §25.4
| C library algorithms
|
■ 参照 ■