C 言語でのソート関数

胡金庫 2023年10月12日
  1. 関数 qsort を使って C 言語で整数の配列をソートする
  2. 関数 qsort を用いて C 言語で文字列の配列を並べ替える
C 言語でのソート関数

この記事では、標準ライブラリのソート関数を C 言語で使用する方法をいくつか説明します。

関数 qsort を使って C 言語で整数の配列をソートする

関数 qsort は、異なるデータ要素の配列に対する多少汎用的なソート操作を実装しています。つまり、qsort は第 4 引数として関数へのポインタを受け取り、与えられた要素の配列に対する比較関数を渡す。今回は、qsort を用いて整数配列を比較するために intCompare 関数を実装しました。なお、intCompareqsort プロトタイプで指定された型 - 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);
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook