この方法は、以下のように2つの関数呼び出しがあるがあります。
無効楽しい(無効) { // 何かを行う } int型メイン(ボイド) { ... 楽しいです(); ... リターン 0 ; }
無効楽しい(無効) { // 何かを行う } int型メイン(ボイド) { ... 無効(* P)(ボイド); P = 楽しいです。 P()。 リターン 0 ; }
上記二つの方法は、特に、タスク切り替えのオペレーティングシステムでは、コールバック関数を使用する方法で最も、第二の機能を呼び出すことができます。だから我々は第二のアプローチの下での分析に注力しなければなりません。
関数ポインタpを宣言するための第二の方法は、なぜ無効(* P)(ボイド)書くのか?直接* pを書き込みませんなぜ、関数名は、関数のエントリアドレスであることを言っていない、ポインタへのアドレスにそれを指示していない理由、実際には、手間を省く真実と思うが、Cにするために理解することは簡単で便利ですこの言語は、このような文字に割り当てられたINT、コンパイラはエラーを報告しますように変数の型のもの、タイプの機能もあるのと同じ方法を持って、関数の型は、それ以来、私たちはどのように変数の型を知っていますかました。さて、次のプログラムを書き、プログラムにエラーがあることに注意し、異常が書かれた意図的だった、目的はコンパイラがGCCで使用し、コンパイラエラーをさせることです。
#include " stdio.hの" 無効楽しい(無効) { のprintf(" Hello Worldの" ); } INTメイン(ボイド) { ボイド *のP。 P = 楽しいです。 リターン 0 ; }
ここでは、コンパイラの出力は次のようになります。
。G ++ exeファイル-x C ++ -c C:\ Users \ユーザーAdministrator.SC-201903191934 \デスクトップ\ unknown1.c -o C:\ Users \ユーザーAdministrator.SC-201903191934 \デスクトップ\ unknown1.o -Wall -fpermissive -Wnoサイン-compare -g
C:\ Users \ユーザーAdministrator.SC-201903191934 \デスクトップ\のunknown1.c:機能で`int型のmain() ':
C:\ Users \ユーザーAdministrator.SC-201903191934 \デスクトップ\のunknown1.c:12:警告: '無効* `へ'`無効(*)()から無効な変換
コンパイルエラーが無効*型の型に無効(*)を()話すことはありませ意味します。そう、その後、どのようにタイプ(*)のポインタを申請する場合は、警告がタイプ楽しい*()()を入力し、ポインタ型を宣言する機能を説明したp、矛盾の2種類*で、それは(彼のミスにつながりました)それは?関数へのアドレスポインタを作るために、ちょうど(*)()タイプを宣言することができるように、C言語の関数ポインタ、すなわち(*)()を入力し、この型を得ました。
次のように:
#include " stdio.hの" 無効楽しい(無効) { のprintf(" Hello World"の); } INTメイン(ボイド){ ボイド(* P)(ボイド)。// 函数指针 P = 楽しいです。リターン0 ; }
このように、それは、ポインタpに楽しいアドレスを機能し、pはそれほど関数ポインタである、あなたにもそのpは関数名であると言うかもしれないが、あなたが述べた古い関数から見ることができる機能、内部のものはありません。
だから我々は、このいわゆる関数pを実行したい、とだけの行に同じ機能を使用する必要があり、P();
今のコードを見て:
無効 *楽しい(無効) { のprintf("Hello Worldの" ); リターンNULL; }
代わりに値を返す関数の楽しい機能は、ここでは、その戻り値はポインタのvoid型である*、その後、どのように我々は、ポインタは関数を参照宣言していますか?
分析は、()関数の型は、(*)*する必要があり、ファサードから見ることができます。だから今、私たちは、同じタイプ、つまり、void *型(* P)(空)へのポインタを宣言する必要があるためだけではp =楽しいです;それは目的を達成することができます。
#include " stdio.hの" 無効 *楽しい(無効) { のprintf(" Hello Worldの" ); リターンNULL; } INTメイン(ボイド) { ボイド *(* P)(ボイド)。 P = 楽しいです。 リターン 0 ; }
概要:1.関数名が入力されているので、C言語では、タイプ一致の原則を厳守しなければなりません。
2.関数名(*)()型のタイプは、戻り値の場合、戻り型は、例えば、上部に上昇させることができます
INT *ファン(INT、INT);タイプ**(*)(INT、INT)、対応する関数ポインタINT **(* P)(INT、INT)の関数として。