- ベストアンサー
bsearch関数の内容について
stdlib関数のbsearch関数で、次のことを教えてください。 void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { size_t pl = 0; /* 探索範囲先頭の添字 */ size_t pr = nmemb - 1;/* 探索範囲末尾の添字 */ char *x = (char *)base;/*なぜchar *にキャスト?*/ if (nmemb > 0) { while (1) { size_t pc = (pl + pr) / 2;/* 探索範囲中央の添字 */ int comp = compar((const void *)&x[pc * size], key); ~~~~~~~~~~~~~~~~~~~~~~~~~~~ /*なぜsizeを掛けるのか?*/ if (comp == 0) /* 探索成功 */ return (&x[pc * size]); else if (pl == pr) break; else if (comp < 0) pl = pc + 1;/* 探索範囲を後半に絞り込む */ else pr = pc - 1;/* 探索範囲を前半に絞り込む */ } } return (NULL);/* 探索失敗 */ }
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
1. char *にキャストしているのは void *ではあとで行っている 操作の &x[pc * size] ができないから。 Cにおけるアドレッシング可能な最小単位はchar なので char *にキャスト。 2. sizeを掛けているのは、&x[pc * size] という式で求めようとしているのが x を配列の先頭として、pc 番目の要素のアドレスを求めようとしているから。 → x[] は char の配列なので、pc 一つあたりのサイズは当然 1、 配列に格納されている要素の大きさが size バイトなので、 「pc番目の要素のアドレス」を得るためには 先頭アドレス(x) + その要素の添え字(pc) * 要素一つあたりの大きさ(size) となる。これを Cの式として表せば &x[pc * size] ということでいかが?
その他の回答 (5)
- keibou21
- ベストアンサー率31% (18/58)
>アドレスの演算はしたことがありません。 では、No5の参考URLで勉強してください。 アドレスの演算はC言語の肝となる部分ですので熟読されることを お勧めします。 そこで理解できない事が出てくれば遠慮なく質問されればよいと思います。
- keibou21
- ベストアンサー率31% (18/58)
#3です >すいません、全然分かりません。 私が提示したコードを実際に動作させてみましたか? そしてそれぞれのアドレスがどうなっているかデバッガなりコンソール出力で確かめてみましたか? また、「アドレスの演算を行ったことはありますか?」の回答がありませんが、どうなんでしょ? とりあえず、C言語の解説本やWebを参考にして復習されることをお勧めします。
- jacta
- ベストアンサー率26% (845/3158)
> char *x = (char *)base;/*なぜchar *にキャスト?*/ 単に冗長な書き方をしているだけです。キャスト無しでも問題ありません。 > /*なぜsizeを掛けるのか?*/ sizeというのは、(探索の対象となる)配列の中の1要素のバイト数です。bsearch関数の内部では、元の配列の型が分からないのでchar型の配列として扱っていますので、本当に扱いたい元の配列の要素をたどるにはsizeを掛ける必要があります。
- keibou21
- ベストアンサー率31% (18/58)
下記2つの質問であると認識して回答します。 /*なぜchar *にキャスト?*/ /*なぜsizeを掛けるのか?*/ C言語でアドレスの演算を行ったことはありますか? ---------------------------------------------------------- char work1[10]; char* a = work1; // work1の先頭アドレスをセット a = a+1; // この演算でaの値はどうなる? int work2[10]; int* b = work2; // work2の先頭アドレスをセット b = b+1; // じゃぁこれなら? ---------------------------------------------------------- 上記サンプルコードの処理が理解できるのであれば 自ずと回答は見つかるはずです。
補足
すいません、全然分かりません。 回答お願いします。
「次のことを教えてください」の「次のこと」は、 具体的にどこを指していますか? 1)下線部の1箇所ですか? 2)「なぜ~?」の2箇所ですか?
補足
分かりにくくてすいません。 2箇所です。
補足
アドレスの演算はしたことがありません。 #include <stdio.h> int main(void) { char work1[10]; char* a = work1; int work2[10]; int* b = work2; a = a + 1; b = b + 1; printf("a=%d", a); printf("b=%d", b); } を実行したところ、 a=-1073757615 b=-1073757676 となりました。たぶん目的とするプログラムになっていないような気がしますが。。