C で関数ポインタを逆参照する行為は、予期しない結果を生み出すように見えるかもしれません。たとえば、以下のコード スニペットは、関数ポインターに対して過剰な数の逆参照を実行しているように見えますが、出力は変更されません。
#include<stdio.h> void hello() { printf("hello"); } int main(void) { (*****hello)(); }
この動作を理解するには、次のようにします。これは、C における関数ポインターのセマンティクスを明確にするために非常に重要です。関数名は関数へのポインターを暗示する場合がありますが、実際には関数コードのアドレスを表します。したがって、関数ポインタの逆参照は関数を直接実行するのではなく、関数指定子を返します。これはすぐに関数ポインタに変換されます。
コード例では、hello の逆参照が繰り返されても、機能を繰り返します。代わりに、逆参照するたびに新しい関数指定子が作成され、それが関数ポインタに変換されて戻されます。最後の式 (*****hello) は単純に hello の関数ポインタとして評価され、() を介して呼び出すと期待どおりに関数が実行されます。
もう 1 つの特殊な式C の関数ポインターの特徴は、特定のコンテキストにおける関数値とポインターの間の暗黙的な変換です。関数値が右辺値コンテキスト (場所ではなく値として使用されるコンテキスト) に出現すると、関数値は自動的に関数ポインターに変換されます。この動作はネストされた関数の値にも拡張され、各逆参照は元の関数を指す関数ポインタを返します。
関数ポインタの逆参照の動作は、最初は不可解に思えるかもしれませんが、実際には次のようなことが考えられます。特定のシナリオでは有益です。関数ポインターを渡すときに & を明示的に使用しないようにすると、コードがより簡潔で読みやすくなります。さらに、関数ポインターと関数名の両方を介した関数呼び出し間の対称性により、2 つの形式間のシームレスな移行が可能になります。
以上がC で関数ポインターの逆参照を繰り返しても複数の関数呼び出しが発生しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。