2

ネストされた関数が C で許可されていることをどこかで読みました (少なくとも GNU コンパイラでは許可されています)。次のコードを検討してください。

/* nestedfunc.c */
#include <stdlib.h> /* for atoi(3) */
#include <stdio.h>

int F (int q)
{
  int G (int r)
  {
    return (q + r);
  }
  return (G (5));
}

int main (int argc, const char* argv[])
{
  int q = 0;
  if (argc > 1)
  {
    q = atoi (argv[1]);
  }

  printf ("%d\n", F (q));
  return 0;
}

コンパイルと実行:

gcc -o nestedfunc -O2 -s -Wall nestedfunc.c
me@mybox:~/college/c++/other stuff$ ./nestedfunc 8
13
me@mybox:~/college/c++/other stuff$

また、他のいくつかのプログラミング言語がこれらをサポートしていることも読みました。私の質問はこれです: ネストされた関数にはどのような有用な目的がありますか? 前もって感謝します。

4

4 に答える 4

3

ネストされた関数は、外部関数のローカルにアクセスできます。クロージャのように、ネストされた関数へのポインタを取り、このポインタを他の関数に渡すことができます。ネストされた関数は、現在の呼び出しのローカルにアクセスできます(この呼び出しがすでに戻っている場合は悪いことが起こります)。Cランタイムシステムはこのために設計されていないため、関数ポインターは通常、関数の最初の命令へのポインターにすぎず、ネストされた関数へのポインターは、スタックにコードを記述してそれにポインターを渡すことによってのみ実行できます。これはセキュリティの観点からは悪い考えです。

ネストされた関数を使用する場合は、それらを適切にサポートするランタイムシステムを備えた言語を使用してください。Cで同様の結果を得るには、「外部関数のローカル」をコンテキスト構造に入れ、これを手動で渡します。

于 2010-11-27T21:34:51.250 に答える
2

ネストされた関数は、レキシカル スコープによるカプセル化を提供します。

あなたの例では、内で定義された他の関数G()によってのみ呼び出すことができます。F()F()

于 2010-11-27T21:16:55.300 に答える
1

一般に、ネストされた関数は通常ヘルパー関数であり、他の 1 つの関数内でのみ使用されます。関数 (ファイル スコープ付き)のようなものstaticですが、さらにローカライズされています (関数スコープのみ)。

ネストされた関数は標準 C ではないため、その言語で使用する理由はほとんどありません。

于 2010-11-27T21:19:02.107 に答える
0

他のプログラミング言語 (Python や Ruby など) では、関数はファースト クラス オブジェクトです。強力な抽象概念であるクロージャーがあります。Pythonでは、これを行うことができます:

def curry(func):
    from inspect import getfullargspec
    args = getfullargspec(func)
    num_args = len(args[0])

    def new_func(list_args, *args):
        l = len(list_args) + len(args)
        nl = list_args + list(args)
        if l > num_args:
             raise TypeError("Too many arguments to function")
        elif l == num_args:
             return func(*nl)
        else:
             return lambda *new_args: new_func(nl, *new_args)

    return lambda *args: new_func([], *args)

それが関数をとってカレーにするカレーデコレータです。

于 2010-11-27T21:21:43.073 に答える