名前空間
変種
操作

bsearch, bsearch_s

提供: cppreference.com
< c‎ | algorithm
ヘッダ <stdlib.h> で定義
void* bsearch( const void *key, const void *ptr, size_t count, size_t size,
               int (*comp)(const void*, const void*) );
(1)
void* bsearch_s( const void *key, const void *ptr, rsize_t count, rsize_t size,

                 int (*comp)(const void *, const void *, void *),

                 void *context );
(2) (C11およびそれ以降)
1) ptr の指す配列から key の指す要素と等しい要素を探します。 配列はそれぞれ size バイトの要素を count 個持ち、 key の指すオブジェクトに関して分割されていなければなりません。 つまり、キーオブジェクトより小さなすべての要素はキーオブジェクトと等しいすべての要素より前に現れなければならず、それらはキーオブジェクトより大きなすべての要素より前に現れなければなりません。 完全にソートされた配列はこれらの要件を満たします。 要素は comp の指す関数を使用して比較されます。 配列がキーに関して comp が使用するのと同じ基準に従ってあらかじめ昇順に分割されていない場合、動作は未定義です。
2) (1) と同じですが、追加のコンテキスト引数 contextcomp に渡され、以下のエラーが実行時に検出され、現在設定されている制約ハンドラ関数を呼びます。
  • count または sizeRSIZE_MAX より大きい。
  • keyptr または comp がヌルポインタ (count がゼロでなければ)。
すべての境界チェック付き関数と同様に、 bsearch_s__STDC_LIB_EXT1__ が処理系によって定義されていて、 <stdlib.h> をインクルードする前にユーザが __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義した場合にのみ、利用可能であることが保証されます。

検索する要素と等しいと comp が示す要素が配列に複数含まれている場合、関数が結果としていずれの要素を返すかは未規定です。

目次

[編集] 引数

key - 検索する要素を指すポインタ
ptr - 調べる配列を指すポインタ
count - 配列の要素数
size - 配列の各要素のバイト単位のサイズ
comp - 第1引数が第2引数より小さい場合は負の整数値、第1引数が第2引数より大きい場合は正の整数値、第1引数が第2引数と等しい場合はゼロを返す比較関数。 key が第1引数として、配列の要素が第2引数として渡されます。

比較関数のシグネチャは以下と同等であるべきです。

 int cmp(const void *a, const void *b);

関数は渡されたオブジェクトを変更してはならず、同じオブジェクトに対してはその配列内の位置にかかわらず一貫した結果を返さなければなりません。

context - comp に第3引数として渡される追加の情報 (照合シーケンスなど)

[編集] 戻り値

1) *key と等しい配列内の要素を指すポインタ、またはそのような要素が見つからなかった場合はヌルポインタ。
2) (1) と同じですが、実行時制約違反の場合もヌルポインタが返されます。

[編集] ノート

その名前にもかかわらず、 C も POSIX 標準もこの関数がバイナリサーチを用いて実装されることも、いかなる計算量の保証も、要求していません。

他の境界チェック関数と異なり、 bsearch_s はサイズゼロの配列を実行時制約違反として扱わず、代わりに要素が見つからなかったことを示します (サイズゼロの配列を受理する他の関数は qsort_s です)。

bsearch_s 以前、 bsearch のユーザは比較関数に追加のコンテキストを渡すためにしばしばグローバル変数を使用していました。

[編集]

#include <stdlib.h>
#include <stdio.h>
 
struct data {
    int nr;
    char const *value;
} dat[] = {
    {1, "Foo"}, {2, "Bar"}, {3, "Hello"}, {4, "World"}
};
 
int data_cmp(void const *lhs, void const *rhs) 
{
    struct data const *const l = lhs;
    struct data const *const r = rhs;
 
    if (l->nr < r->nr) return -1;
    else if (l->nr > r->nr) return 1;
    else return 0;
 
    // return (l->nr > r->nr) - (l->nr < r->nr); // possible shortcut
    // return l->nr - r->nr; // erroneous shortcut (fails if INT_MIN is present)
}
 
int main(void) 
{
    struct data key = { .nr = 3 };
    struct data const *res = bsearch(&key, dat, sizeof dat / sizeof dat[0],
                                     sizeof dat[0], data_cmp);
    if (res) {
        printf("No %d: %s\n", res->nr, res->value);
    } else {
        printf("No %d not found\n", key.nr);
    }
}

出力:

No 3: Hello

[編集] 参考文献

  • C11 standard (ISO/IEC 9899:2011):
  • 7.22.5.1 The bsearch function (p: 355)
  • K.3.6.3.1 The bsearch_s function (p: 608-609)
  • C99 standard (ISO/IEC 9899:1999):
  • 7.20.5.1 The bsearch function (p: 318-319)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 4.10.5.1 The bsearch function

[編集] 関連項目

不特定の型の要素の範囲をソートします
(関数) [edit]