関数ポインタの逆参照: 謎を解く
C プログラミングでは、関数ポインタは関数のアドレスを格納する変数です。ただし、通常の変数とは異なり、関数ポインターの逆参照は独特の動作をします。
関数ポインターの逆参照が期待どおりの結果を生成しないのはなぜですか?鍵となるのは、関数値が右辺値コンテキスト (位置としてではなく値として使用される場合) でどのように動作するかを理解することにあります。 C では、右辺値コンテキスト内の関数値は、元の関数値へのポインターに自動的に変換されます。
このポインターを * で逆参照すると、元の関数値が取得されます。ただし、この値はすぐにポインターに再変換され、ポインター変換の無限ループが作成されます。質問で提供されているコードは、この動作を示しています。
#include <stdio.h> void hello() { printf("hello"); } int main(void) { (*****hello)(); }
このコードは、基本的に、一連の関数ポインター逆参照を通じて hello 関数を 5 回呼び出します。ただし、これらの逆参照は実際には関数を実行しません。これらは単に関数ポインタを取得し、その後ポインタに変換し直すだけです。最終結果は一連のポインター操作ですが、実際の関数呼び出しはありません。
これが起こる理由を理解するには、同様の実験を考えてみましょう。
int x; // Regular variable int *px = &x; // Pointer to the variable *px = 5; // Modifying the variable through the pointer
このコードでは、ポインター * を逆参照しています。 px を使用すると、変数 x の値を変更できます。ただし、関数ポインターの場合、逆参照は関数自体を変更するのではなく、そのアドレスを取得します。
この区別が存在するのは、C では関数が不変、つまり変更できないためです。これらはポインタとして呼び出すか渡すことしかできません。したがって、関数ポインタの動作を変更するために関数ポインタを逆参照する必要はありません。
要約すると、関数ポインタの逆参照は関数を実行するのではなく、そのアドレスを取得します。このアドレスはすぐにポインタに再変換され、ポインタ変換の無限ループが発生します。この動作は、C の右辺値コンテキストにおける関数値の固有の機能であり、アドレス参照に明示的にアンパサンド (&) を使用せずに関数ポインターを操作する際に便利です。
以上がC で関数ポインターを逆参照しても関数が実行されないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。