はじめましてm(_ _)m
最近プログラミングの勉強を始めて、「猫でもわかるC言語プログラミング」という本に従って勉強しているんですが、ちょっとわからないところが出てきたので教えて頂けるとありがたいです。
小題は「関数へのポインタ」で、以下のように打ち込みました。
#include <stdio.h>
int func(int);
int main()
{
int (*ptr1)(), (*ptr2)();
ptr1 = main;
ptr2 = func;
printf("main関数のアドレス = %p, ptr1 = %p\n", main, ptr1);
printf("func関数のアドレス = %p, ptr2 = %p\n", func, ptr2);
return 0;
}
int func(int x)
{
printf("x = %d\n", x);
return 0;
}
これをビルドしてみたところ、エラーが出てうまくいきませんでした。
1>------ ビルド開始: プロジェクト: funcptr02, 構成: Debug Win32 ------
1> funcptr02.cpp
1>c:\users\shigeki\documents\visual studio 2010\projects\funcptr02\funcptr02\funcptr02.cpp(12): error C2440: '=' : 'int (__cdecl *)(int)' から 'int (__cdecl *)(void)' に変換できません。
1> この変換には reinterpret_cast, C スタイル キャストまたは関数スタイルのキャストが必要です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
という文が表示されます。
ポインタに関しても知識が乏しいので、何が原因でこうなったのか分かりません。
どなたかお力を貸してくださいm(_ _)m
環境は、Windows7で、コンパイラはVisual C++ 2010を使っています
関数へのポインタ
Re: 関数へのポインタ
ポインターに関する知識が乏しいと自覚されている間は関数ポインターに手を出さない方が無難では?
という話はさておき、こんなコードを書けばお手元のコンパイラーでコンパイル~実行できるのではないかと
勝手に見込んでおります。
なお、質問者さんが提示されたコードは、当方のgccコンパイラーでは何もエラーを吐くことなくコンパイル~実行できました。
ptr1とptr2の型を、『「引数を取らない、戻り値がint型の関数」へのポインター』としています。
main関数もfunc関数も、「引数を取らない、戻り値がint型の関数」です。
という話はさておき、こんなコードを書けばお手元のコンパイラーでコンパイル~実行できるのではないかと
勝手に見込んでおります。
なお、質問者さんが提示されたコードは、当方のgccコンパイラーでは何もエラーを吐くことなくコンパイル~実行できました。
#include <stdio.h>
int func(void);
int main(void)
{
int (*ptr1)(void), (*ptr2)(void);
ptr1 = main;
ptr2 = func;
printf("main関数のアドレス = %p, ptr1 = %p\n", main, ptr1);
printf("func関数のアドレス = %p, ptr2 = %p\n", func, ptr2);
return 0;
}
int func(void)
{
return 0;
}
main関数もfunc関数も、「引数を取らない、戻り値がint型の関数」です。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: 関数へのポインタ
ちなみに、
私はVisual Studioを使ったことがないので、勝手な推測に過ぎないのですけれど。
このエラーが出たのは、depo さんが書きました: 1> funcptr02.cpp
1>c:\users\shigeki\documents\visual studio 2010\projects\funcptr02\funcptr02\funcptr02.cpp(12): error C2440: '=' : 'int (__cdecl *)(int)' から 'int (__cdecl *)(void)' に変換できません。
ここで、ptr2について「引数の並びを無視する(あるいはvoidとみなす?)」と書いているのと
実際には引数がある点とが食い違っていることをVisual Studioに指摘されたのだと思います。
私はVisual Studioを使ったことがないので、勝手な推測に過ぎないのですけれど。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: 関数へのポインタ
Cなので,拡張子は.cppではなく.cで書きましょう。depo さんが書きました:最近プログラミングの勉強を始めて、「猫でもわかるC言語プログラミング」という本に従って勉強しているんですが、ちょっとわからないところが出てきたので教えて頂けるとありがたいです。
ちょうど,C++とCの非互換の部分でひっかかっています。
ちゃんとcodeタグで囲みましょう。詳しくは,投稿フォームの上にあるフォーラムルールの項目を参照。depo さんが書きました:小題は「関数へのポインタ」で、以下のように打ち込みました。
funcは引数にint型をとってint型を返す関数なので,funcへのポインタの型はint (*)(int)です。
故に,と書く必要があります。
エラーメッセージをよく見るとわかるのですが,depoさんはC++としてコンパイルされています。box さんが書きました:なお、質問者さんが提示されたコードは、当方のgccコンパイラーでは何もエラーを吐くことなくコンパイル~実行できました。
gccでもC++としてコンパイルすればエラーになるのではないでしょうか。
Re: 関数へのポインタ
全くもっておっしゃるとおりです。YuO さんが書きました:エラーメッセージをよく見るとわかるのですが,depoさんはC++としてコンパイルされています。
gccでもC++としてコンパイルすればエラーになるのではないでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
-
depo
Re: 関数へのポインタ
boxさん、YuOさん
ご指摘ありがとうございましたm(__)m
拡張子を.cにしてみたらちゃんと読み込んでくれました。
あと、コードを囲んでなくてすいませんでした。
次回以降注意します。
ご指摘ありがとうございましたm(__)m
拡張子を.cにしてみたらちゃんと読み込んでくれました。
あと、コードを囲んでなくてすいませんでした。
次回以降注意します。