bsearch関数2回目

このQ&Aのポイント
  • bsearch関数2回目についての質問です。
  • 前回の回答を参考に、柴田望洋著の新・明解C言語によるアルゴリズムとデータ構造のp105を学習しました。
  • int_cmp関数の定義についての疑問と、VisualStudio2013でのデバッグ解析に関する問題について教えていただきたいです。
回答を見る
  • ベストアンサー

bsearch関数2回目

前回回答いただいた皆さんありがとうございました。 自分なりに勉強したところ、柴田望洋著 新・明解C言語によるアルゴリズムとデータ構造 のp105に解説を発見し、kmeeさんの回答からキャストの定義を学び、理解できました。 第5引数の比較関数なのですが、定義で int *int_cmp(const int *a, const int *b) とint_cmpの前に*は要らないのでしょうか。。ただ第5引数にint_cmpと書けばint_cmp関数の先頭アドレスが参照されることになってるんでしょうか。 それと MillenniuM さんの宿題のような比較関数 int int_cmp(const void* x, const void* y) { return *(int*) x - *(int*) y; } の*(int*)x - *(int*)y; の部分をVisualStudio2013でデバッグ解析しようとすると msvcr120d.i386.pdbが見つからない~というようなことを言われてその部分の動作を解析できません。。(コンパイルはできます) このvsでコンパイルできない理由と意味をどなたかご教授頂けないでしょうか

質問者が選んだベストアンサー

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1621/5656)
回答No.2

>msvcr120d.i386.pdbが見つからない~というようなことを言われてその部分の動作を解析できません。。(コンパイルはできます) >このvsでコンパイルできない理由と意味をどなたかご教授頂けないでしょうか 自分で書かれてて違和感ありませんでした? 「コンパイルできます」といってるのに「コンパイルできない(理由)」って何? bsearch呼び出す前からステップ実行しててbsearchの処理の中に入ってってるだけじゃないかなぁ。 bsearchのソースデバッグのための情報はないでしょうから。 int_cmpにブレイクポイント設定して一気に実行させればいいだけかと。

tranceporter
質問者

お礼

第5引数ではなくbsearch関数が別になってるからですね。 今見るとこの回答がベストアンサーです。ありがとうございました。

tranceporter
質問者

補足

すいません日本語間違えました。でも日本人です。。 >bsearchのソースのデバッグのための情報はないでしょうから。 この「デバッグのための情報」というのはなんなのでしょう 以前別のプログラムをvs2005でステップインしようとしてもデバッグ情報がありませんみたいな ことを言われて逆アセンブルになっちゃったのですが、、この辺のコンパイラの挙動の勉強って どういう書籍、サイトをみればよいでしょうか。。

その他の回答 (6)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

関数名を書くと, 一部の例外を除き自動的に「当該関数へのポインタ」に変換されます. 配列名を書いたときに (これも一部の例外を除き) 自動的に「先頭要素へのポインタ」に変換されるのと同じ. だから, ただ単に int_cmp と書けば (「例外」でなければ) その関数へのポインタとなりますが, この「関数へのポインタ」は #1 にもあるように &int_cmp と書いても同じように得ることができます.

tranceporter
質問者

お礼

第5引数がダメなんじゃなくてbsearch関数のソースがないって言ってるんですね もう少し勉強します。。

  • wormhole
  • ベストアンサー率28% (1621/5656)
回答No.6

>以前別のプログラムをvs2005でステップインしようとしてもデバッグ情報がありませんみたいな >ことを言われて逆アセンブルになっちゃったのですが、、この辺のコンパイラの挙動の勉強って >どういう書籍、サイトをみればよいでしょうか。。 簡単にいえば、デバッグ対象のプログラムをコンパイルする際にソースからコンパイルしていない部分に関してはステップ実行時には逆アセンブルになります。 元のソースがないわけですしソースとの対応もわからないんですから。 もっと極端にいうなら、あなたがソースコードを用意してコンパイルした部分だけがソースレベルでステップ実行などできる部分です。 >あ、それで\VC\srcの中のdllファイルを指定すればデバッグ可能になるのですね >この辺は2013になっても自動では認識してもらえないということですか。 なりません。 そこにはソースがあるだけです。 コンパイル対象に含めればできるとは思いますけどbsearchなどの標準関数を何のためにデバッグするんですか?

tranceporter
質問者

お礼

詳しい説明ありがとうございます デバッグは語弊ですすみません あくまで途中の値とかどうなってるか挙動を解析して 理解したいのです またよろしくお願いします

回答No.5

> それとも今からCは流行らないのかな・・・ デバッグ云々とCの流行り廃りとは何の関係もありません。

回答No.4

>> bsearchのソースのデバッグのための情報はないでしょうから。 > この「デバッグのための情報」というのはなんなのでしょう 生成された機械語と元ソースとの対応表みたいなもん。 それがないと一行ずつ実行とかブレークポイントとか変数ウォッチとか、できない。 gccなんかだと、実行モジュールに埋め込むんだけど、VCは別ファイルなのです。

tranceporter
質問者

お礼

第5引数じゃなくてbsearch関数のソースがないって言ってるんですね。 もう少し勉強します。。

tranceporter
質問者

補足

ということは つまりbsearch関数のソースはあるけど 第5引数はあんたが書いて用意したものだから そこは知らないよ と言われた、のでしょうか それでブレークポイントを付けてステップインすると エラーが出る

回答No.3

> bsearch呼び出す前からステップ実行しててbsearchの処理の中に入ってってるだけじゃないかなぁ。 あ、そゆことか。 bsearchのソースだったら <VisualStudio-install-dir>\VC\crt\src にあるはず。

tranceporter
質問者

お礼

あ、それで\VC\srcの中のdllファイルを指定すればデバッグ可能になるのですね この辺は2013になっても自動では認識してもらえないということですか。 それとも今からCは流行らないのかな・・・

回答No.1

> 定義で int *int_cmp(const int *a, const int *b) > とint_cmpの前に*は要らないのでしょうか。。 そんなことしたら int* を返す関数になっちゃうじゃないですか。 > ただ第5引数にint_cmpと書けばint_cmp関数の先頭アドレスが参照されることになってるんでしょうか。 です。厳密には &int_cmp ですけど、どっちでもOK。 > msvcr120d.i386.pdbが見つからない~ ごめんなさい、そんな現象に出くわしたことがないのでわからんです。

tranceporter
質問者

お礼

ありがとうございます。断定して頂けるのが助かります。 厳密には&int_cmpなんですね この辺のあいまいさはCの醍醐味とも言えるかもしれませんね

関連するQ&A

  • bsearch関数の呼び出しで

    C言語の深いところまで理解しようとしてます。今まで使わないだろうと思っていた関数へのポインタ なのですが、 2分探索のところで bsearch関数というのが出てきました。 この関数は第5引数に比較関数を引数にするのですが p = bsearch(&ky, x, nx, sizeof(int), (int (*)(const void *,const void *))int_cmp ); という形でサンプルソースには載っています。 この (int (*)(const void *,const void *))int_cmp の部分なのですが、まず戻り値をキャストするなら int (*)ではなく(int *)ではないでしょうか。 それとint_cmpは比較関数なのですが、引数が左側に来る、というところが納得できません。 ちなみにソースファイルをcppのままだとコンパイルできませんでした.cに拡張子を直したらコンパイルできました。 説明が足りないところがあったら指摘してください。お願いします。

  • qsortの関数について

    qsortの関数について 下記のようにある本に関数の呼ぶ時、関数名(int_cmp)が引数(const void *, const void *)の後に書かれて理由を教えて頂きたい。よろしくお願いします。 質問のプログラム int int_cmp(const int *a ,const int *b) { ------ } int main { qsort(x, nx , y, (int (*)(const void *, const vois *))int_cmp);

  • qsortの関数ポイントについて

    qsortの関数ポイントについて int int_cmp(const int *a, const int *b) { ------ } main { qsort(x,nx,sizeof(int),(int (*) (const void *, const void * )) int_cmp); 上記の(1)関数のポイント,(int (*) (const void *, const void * )) int_cmpを  普通の(2)関数ポイント(* int_cmp) (const void *, const void * )で呼べない  理由 、また、(1)(2)は、同じ意味でしょうか、教えて頂きたい。

  • こんなコンパイルエラーがでます。

    OS:WinNT4.0 環境:VC++6.0 MFC コンパイル時に次のエラーが出て来ました。 error C2664: 'qsort' : 4 番目の引数を 'int (const void *,const void *)' から 'int (__cdecl *)(const void *,const void *)' に変換できません。 (新しい機能 ; ヘルプを参照)スコープ内でこの名前を持つ関数でターゲット型に一致するものはありません。 qsort関数の引数関数を'int xxxxxxx(const void *,const void *)に宣言したところこのエラーが出てきました。 何がなんだかさっぱりわかりません。 ぜひお願いします。

  • なんでchar型なんでしょうか??

    なぜここ(☆☆)で char型なのかが よく・・いやさっぱりわかりません。 他の型ではだめなんでしょーか? この関数自体は挿入ソートだとわ思われるんで なんとなくこの☆☆(から以下三行あたりまで) のところの動作の意味はわかるんですが なぜchar型でなくてはならないのかが。 知っている方いたら どうか教えてください。 typedef User* PUser; typedef int (*CFT)(const void*, const void*); void ssort(void* base, unsigned int n,        unsigned int sz, CFT cmp) {    for (int i = 0; i < n - 1; i++) for (int j = n - 1; i < j; j--) {          char* pj = (char*)base + j * sz; //←ここ☆☆          char* pj1 = pj - sz;  //とここ☆☆           if (cmp(pj, pj1) < 0) { for (int k = 0; k < sz; k++) { char temp = pj[k]; pj[k] = pj1[k]; pj1[k] = temp; }     }    } /* ssort関数の引数の関数ポインタで 利用される比較関数 */ int cmp1(const void* p, const void* q) { return strcmp(PUser(p)->name, PUser(q)->name); } int cmp2(const void* p, const void* q) { return PUser(p)->dept - PUser(q)->dept; }

  • 引数に二重配列のある関数について

    void calc(int *a,int b,int c){ a[0]=b+c; a[1]=b-c; } void main(void){ int x[2]; int y=2,z=5; calc(x,y,z); printf("x[0]=%d,x[1]=%d\n",x[0],x[1]); } 上のように引数が普通の配列の関数ならできるのですが, 引数が下のような多重配列になるとエラーが出てしまいできません。 void keisan(int **a,int b,int c){ a[0][0]=b+c; a[0][1]=b-c; a[1][0]=b*c; a[1][1]=b/c; } void main(void){ int x[2][2]; keisan(x,6,2); printf("x[0][0]=%d,x[0][1]=%d\n",x[0][0],x[0][1]); printf("x[1][0]=%d,x[1][1]=%d\n",x[1][0],x[1][1]); } 引数に多重配列を使った場合の関数の作り方について教えてください. お願いいたします.

  • ユーザー関数が定義されません

    ユーザ関数について勉強しようとしてテキストの例文を打ってコンパイルしたのですが、ユーザー関数「sub1」が照合できず、ユーザー関数が使えません。 悪いところがあれば教えてください。 コンパイラはVC++です。 例文 #include <stdio.h> void main() { int a=8,b=-6; sub1(a,b); } int sub1(x,y) { int x,y; printf("x= %d y= %d",x,y); }

  • 関数の引数をvoid*でキャストする

    最近見かけたCのプログラムで、関数の引数の型は void* なのですが、その関数を使うときに 引数をvoid*でキャストしていました。 例えば、 func ( (void*) p ); こういうことです。 私の知っている知識では、 void* と 任意の型のポインタは キャストなしに相互に代入可能です。 関数の引数でも、キャストは要らないものだと思っていました。 そうすると、引数を void* でキャストするのは無意味だと思うのですが、・・・ 違うのでしょうか。処理系によるとか。 逆に、関数の引数の型がchar*などで、渡すものが void* のときはどうなのでしょうか。 下のプログラムは、関数byte_orderの引数の型はvoid*ですが、int型へのポインタ( &a )を設定しています。私の環境では、コンパイルエラーも警告もないし、動作も正常です。 #include <stdio.h> #include <string.h> void byte_order(void *vp) { char char_array[4]; strncpy(char_array, vp, 4); printf("出力します:%x %x %x %x\n", char_array[0], char_array[1], char_array[2], char_array[3]); } int main(void) { int a = 0x12345678; byte_order(&a); return 0; } このプログラムは単なる一例であって、質問はバイトオーダに関するものではありません。 また、C言語の質問であって、C++ではありません。

  • C言語での関数の引数の受け渡しについて

    C言語での関数の引数の受け渡しについて教えてもらいたいのです。 char *p=Goo;  というポインタpがmain関数で定義され、このポインタpをある関数 void func(・・・) に渡すことは出来ますか? つまりポインタを実引数として扱うことはできるのかという事ですが・・・ int p=10; とかだったら、 void func(int test) の関数には、main関数で func(p) で仮引数testにわたせると思うんですが・・・ もし出来るようでしたら、関数の渡し方と定義の記述を教えてください。 どうか宜しくお願いします。

  • qsortについて

    qsort()で構造体をソートする時に、qsortの第3,4引数時の、「size t_t size, int (*cmp)(const void *a, const void *b)」の使い方が分かりません。 何故これを使ってソートが出来るのでしょうか?そもそも、構造体を送った時に、自作関数内での書き方にも疑問があります。 int main(void){ MAX dt[5]={・・・・}; //構造体変数宣言 ・・・・・ qsort(dt,5,sizeof(MAX),sum); //(*1) .... return 0; } int sum(const void *a, const void *b){ MAX *p1 = (MAX *)a; //(*2) MAX *p2 = (MAX *)b; //(*2) ・・・・ return ~; } ---------------------------------------------------- *1: 第3引数のsizeof(MAX)って何ですか? *2: 例えばint型が渡されてreturnする場合は、「return *(int *)a - *(int *)b 」でいいのに、   何故構造体の場合はこう書かないといけないのですか?

専門家に質問してみよう