C言語において、関数ポインタの型をtypedefで作ると、
typedef int (*MyFunc)(int*,int*);
と宣言でき、関数ポインタの変数は、
int FuncA(int* a, int* b)
{
~
}
void main_loop()
{
MyFunc pf = FuncA;
~
(*pf)(pa,pb);
}
というように使うと思います。
ここで疑問なのですが、この実際に呼び出される関数、FuncAの定義に、typedef(ここではMyFunc)を使えないものでしょうか?
同じことを2回やっているようで、無駄に思えてしまいます。
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
おそらく参考書を読みながら質問しているのかと思いますが、参考書では関数のポインタを手短に説明するために質問にあるようなコードが提示されているんだろうと思います。
もう少し発展させて・・・
MyFunc pf;
ではなく、単純なリスト構造にするために
MyFunc pf[100];
とかだったら、(配列の終わり判定を含めて)100個までの処理を並べることができますよね。
あとは添え字をインクリメントしていけば、バッチ言語処理のようなことが出来そうな気がしてくれば、C言語のプログラミングを勉強した甲斐があったというものでしょう。
もっと詳しく知りたいのならば、
「実用Cプログラミング生 粋のCプログラマへ」H.シュルト著
http://www.fukkan.com/vote.php3?no=19161
とか
「エキスパートCプログラミング - 知られざるCの深層 -」Peter van der Linden著
などといった、K&Rを卒業した中級以上のスキルを対象にする本を眺めてみることです。
No.3
- 回答日時:
多分, できないと思います.
該当する例は見付ていないのですが,
The identifier declared in a function definition (which is the name of the function) shall have a function type, as specified by the declarator portion of the function definition.
とあって, ここに対する脚注として
The intent is that the type category in a function definition cannot be inherited from a typedef.
と書かれており, その例として以下が規格に挙げられています:
typedef int F(void);
F f, g; // f and g both have type compatible with F
F f { /* ... */ } // WRONG: syntax/constraint error
F g() { /* ... */ } // WRONG: declares that g returns a function
脚注部分で「the type category in a function definition cannot be inherited from a typedef」と書かれているので,
typedef int (*PF)(void);
でも
PF *f { /* ... */ }
はアウトだと思います.
No.4
- 回答日時:
関数ポインタに代入する関数が、1つで決まってるなら無駄といえば無駄ですね。
この場合なら
int FuncA(int* a, int* b){~}
void main_loop(){
FuncA(pa,pb);
}
で十分です。
関数ポインタが必要になるような例は。
typedef int (*MyFunc)(int*,int*);
int FuncA(int* a, int* b){ ~ }
int FuncB(int* a, int* b){ ~ }
void main_loop(){
MyFunc pf;
if (flag) {
pf = FuncA; // flagが真であればFuncAを呼び出す
} else {
pf = FuncB; // flagが偽であればFuncBを呼び
}
(*pf)(pa,pb);
}
こうゆう使い方なら納得できるとかと思います。
No.5
- 回答日時:
C では、式の中の関数名だけが関数を指すポインタに読み替えられます。
# これは、コンパイラが勝手に読み替えます。
関数定義やプロトタイプ宣言といった、式の中にない関数名はポインタに読み替えられることはありません。
ですので、ご質問の中にある
> typedef int (*MyFunc)(int*,int*);
と
> int FuncA(int* a, int* b)
> {
> ~
> }
は、別の型ということになります。
FuncA( pa, pb ); // FuncA はポインタに読み替えられている。
と関数を式の中に記述した場合にのみ、コンパイラがこの FuncA をポインタとして読み替えるんです。
式の中という意味では、以下の場合も同様です。
MyFunc pf = FuncA; // FuncA はポインタに読み替えられている。
実際、pf に FuncA を代入する場合、以下のようにしても正常に動作します。
MyFunc pf = &FuncA; // アドレス演算子 & をつけてみる。
ついでに、(*pf)() コールの箇所も、以下のようにすることができます。
pf(pa,pb); // 間接参照演算子 * をとってみた。
つまり、関数を指すポインタに「限って」いえば、間接参照演算子はあってもなくても良い存在です。
というわけで、こんなことをしてもコンパイルエラーにも実行エラーにもなりません。
(**********pf)(pa,pb); // どうせ * は何もしないし。。。
このように、関数のポインタ周りの仕様はかなり混乱しています。
配列とポインタが違うものであるように、関数と関数ポインタも別物です。
どちらも、C のコンパイラが自分の都合でポインタに読み替えているだけです。
こんな感じでいかがでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# C言語 ポインタ 配列 2 2022/06/02 17:29
- C言語・C++・C# ポインタの型変換、どうやるんでしたっけ? 2 2022/03/28 11:00
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
セグメントエラー
-
戻り値で構造体を返すことは可...
-
init関数の意味
-
fopne で失敗する原因
-
ハンドルはポインタか
-
Run-Time Check Failure #3とい...
-
C言語のポインタに直接アドレス...
-
C言語の関数と配列に関する質問
-
アプリを32bitから64bit移行
-
VBはCを混乱させる?
-
プログラミングのfarについて
-
連結リスト 要素の入れ替え
-
C言語でのconstを返す関数
-
コンストラクタでnewを失敗した...
-
入れ子の構造体について
-
[excel vba] マウスポインタの...
-
VB6でのgethostbyaddrの使用方...
-
エラーの意味
-
デバイスハンドルとは?
-
ExcelVBAでのkernel32(64bit)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
C言語の関数と配列に関する質問
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
LPSTR型の初期化について
-
セグメントエラー
-
アプリを32bitから64bit移行
-
コンストラクタでnewを失敗した...
-
ExcelVBAでのkernel32(64bit)
-
Cで作成したDLL関数をVBから呼...
-
ハンドルはポインタか
-
DLL<->VB間での受け渡し(文字...
-
C言語でのconstを返す関数
-
ポインタについて
-
参照型で受け取った引数をポイ...
-
TCHAR文字列内の検索について
-
デバイスハンドルとは?
-
基本アルゴリズムの『返す』の...
おすすめ情報