関数ポインターがあるとします。
void (*func0)(void);
これも次のように定義されています。
void func0(void) { printf( "0\n" ); }
しかし、ある時点で何らかの方法で関数ポインターにアクセスしようとすると、MS VS デバッガーが、コードにステップインしたときに func0 が実際に 0x0000 を指していることを示した場合、それはどういう意味ですか? また、最適な修正方法を教えてください。ありがとう。
ヌル ポインターを逆参照することは、未定義の動作です。修正は、ポインターが適切な関数を参照していることを確認するだけです。
あなたの場合、次のようなものが必要です:
void MyFunction(void)
{
printf( "0\n" );
}
その後、次のように割り当てることができますfunc0
。
func0 = &MyFunction;
関数ポインター変数と実際の関数に別の名前を使用していることに注意してください。
これで、関数ポインターを介して関数を呼び出すことができます。
func0();
関数ポインタの命名と定義を混同していると思います。あなたが書いた場合、私はそれを指摘します
void func0(void) { printf( "0\n" ); }
void (*func0)(void);
実際には、まったく関係のない同じ名前のオブジェクトが 2 つありますfunc0
。1 つ目func0
は関数で、2 つ目func0
は関数へのポインタ型の変数です。
変数 をグローバルに(関数の外で)宣言したと仮定すると、func0
自動的にゼロ初期化されるため、コンパイラはあなたの行を読み取ります
void (*func0)(void);
なので
void (*func0)(void) = NULL;
したがって、変数func0
は値で初期化され、NULL
ほとんどのシステムでNULL
は実際には0
.
デバッガーは、変数 func0
の値0x0000
が であると伝えています0
。したがって、これは大きな驚きではありません。
「修正」に関するあなたの質問に-まあ、あなたはあなたの function を指す関数ポインタが必要だと思うfunc0
ので、次のことができます:
void func0(void) { printf( "0\n" ); }
void (*pFunc)(void) = func0;
またはさらに良い(ほとんどのコンパイラでは必要ありませんが)次のように書くことができます
void (*pFunc)(void) = &func0;
そのため、変数を初期化してpFunc
(名前を変更することを強くお勧めします!)、 を指すようにしfunc0
ます。もう少し正確に:&...
関数のアドレスを取得func0
し、この値を variable に割り当てますpFunc
。
これで、関数ポインターを「呼び出す」ことができます (関数ポインターが指す関数を呼び出すことを意味します)。
pFunc(); //will call function func0