関数へのポインタ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
depo

関数へのポインタ

#1

投稿記事 by depo » 14年前

はじめまして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を使っています

box
記事: 2002
登録日時: 15年前

Re: 関数へのポインタ

#2

投稿記事 by box » 14年前

ポインターに関する知識が乏しいと自覚されている間は関数ポインターに手を出さない方が無難では?
という話はさておき、こんなコードを書けばお手元のコンパイラーでコンパイル~実行できるのではないかと
勝手に見込んでおります。
なお、質問者さんが提示されたコードは、当方の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;
}
ptr1とptr2の型を、『「引数を取らない、戻り値がint型の関数」へのポインター』としています。
main関数もfunc関数も、「引数を取らない、戻り値がint型の関数」です。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 15年前

Re: 関数へのポインタ

#3

投稿記事 by box » 14年前

ちなみに、
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)' に変換できません。
このエラーが出たのは、
depo さんが書きました:

コード:

	int (*ptr1)(), (*ptr2)();
ここで、ptr2について「引数の並びを無視する(あるいはvoidとみなす?)」と書いているのと
depo さんが書きました:

コード:

int func(int x)
実際には引数がある点とが食い違っていることをVisual Studioに指摘されたのだと思います。
私はVisual Studioを使ったことがないので、勝手な推測に過ぎないのですけれど。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

YuO
記事: 947
登録日時: 15年前
住所: 東京都世田谷区

Re: 関数へのポインタ

#4

投稿記事 by YuO » 14年前

depo さんが書きました:最近プログラミングの勉強を始めて、「猫でもわかるC言語プログラミング」という本に従って勉強しているんですが、ちょっとわからないところが出てきたので教えて頂けるとありがたいです。
Cなので,拡張子は.cppではなく.cで書きましょう。
ちょうど,C++とCの非互換の部分でひっかかっています。
depo さんが書きました:小題は「関数へのポインタ」で、以下のように打ち込みました。
ちゃんとcodeタグで囲みましょう。詳しくは,投稿フォームの上にあるフォーラムルールの項目を参照。
depo さんが書きました:

コード:

int func(int);
depo さんが書きました:

コード:

	int (*ptr1)(), (*ptr2)();

	ptr1 = main;
	ptr2 = func;
funcは引数にint型をとってint型を返す関数なので,funcへのポインタの型はint (*)(int)です。
故に,

コード:

int (*ptr1)(), (*ptr2)(int);
と書く必要があります。
box さんが書きました:なお、質問者さんが提示されたコードは、当方のgccコンパイラーでは何もエラーを吐くことなくコンパイル~実行できました。
エラーメッセージをよく見るとわかるのですが,depoさんはC++としてコンパイルされています。
gccでもC++としてコンパイルすればエラーになるのではないでしょうか。

box
記事: 2002
登録日時: 15年前

Re: 関数へのポインタ

#5

投稿記事 by box » 14年前

YuO さんが書きました:エラーメッセージをよく見るとわかるのですが,depoさんはC++としてコンパイルされています。
gccでもC++としてコンパイルすればエラーになるのではないでしょうか。
全くもっておっしゃるとおりです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

depo

Re: 関数へのポインタ

#6

投稿記事 by depo » 14年前

boxさん、YuOさん

ご指摘ありがとうございましたm(__)m
拡張子を.cにしてみたらちゃんと読み込んでくれました。



あと、コードを囲んでなくてすいませんでした。

次回以降注意します。

閉鎖

“C言語何でも質問掲示板” へ戻る