【C言語入門】qsortの使い方

こんにちは、もがちゃんです。

今回は、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にコピーした領域の先頭を指すポインタを指定する。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA