Любое хорошее использование для вложенной функции в C?

Я где-то читал, что вложенные функции допустимы в 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 ответа

Решение

Вложенные функции обеспечивают инкапсуляцию через лексическую область видимости.

В вашем примере G() может быть вызван только F() и другими функциями, определенными в F(),

Вложенные функции могут обращаться к локальным функциям внешней функции. Как и в случае замыканий, вы можете взять указатель на вложенную функцию и передать этот указатель другим функциям, и вложенная функция будет иметь доступ к локальным элементам текущего вызова (плохие вещи случаются, если этот вызов уже возвращен). Поскольку система времени выполнения C не предназначена для этого, указатель на функцию, как правило, является просто указателем на первую инструкцию функции, а указатели на вложенные функции могут быть сделаны только путем написания некоторого кода в стеке и передачи указателя на него. Это плохая идея с точки зрения безопасности.

Если вы хотите использовать вложенные функции, используйте язык с системой времени выполнения с соответствующей поддержкой для них. Чтобы добиться аналогичного результата в C, поместите "локальные функции внешней функции" в контекстную структуру и передайте это вручную.

Как правило, вложенная функция обычно является вспомогательной функцией, которая используется только внутри одной другой функции. Это вроде как static функция (с областью действия файла), но еще более локализованная (только область действия функции).

Вложенные функции не являются стандартными C, поэтому нет особых причин использовать их на этом языке.

В других языках программирования (например, 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)

Это декоратор карри, который берет функцию и делает ее карри.

Другие вопросы по тегам