2

関数ポインターがあるとします。

void (*func0)(void);

これも次のように定義されています。

void func0(void) { printf( "0\n" ); }

しかし、ある時点で何らかの方法で関数ポインターにアクセスしようとすると、MS VS デバッガーが、コードにステップインしたときに func0 が実際に 0x0000 を指していることを示した場合、それはどういう意味ですか? また、最適な修正方法を教えてください。ありがとう。

4

2 に答える 2

8

ヌル ポインターを逆参照することは、未定義の動作です。修正は、ポインターが適切な関数を参照していることを確認するだけです。

あなたの場合、次のようなものが必要です:

void MyFunction(void)
{
    printf( "0\n" ); 
}

その後、次のように割り当てることができますfunc0

func0 = &MyFunction;

関数ポインター変数と実際の関数に別の名前を使用していることに注意してください。

これで、関数ポインターを介して関数を呼び出すことができます。

func0();
于 2012-04-04T15:28:12.837 に答える
6

関数ポインタの命名定義を混同していると思います。あなたが書いた場合、私はそれを指摘します

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
于 2012-04-07T18:07:27.040 に答える