Любое хорошее использование для вложенной функции в C? - PullRequest
2 голосов
/ 28 ноября 2010

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

3 голосов
/ 28 ноября 2010

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

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

2 голосов
/ 28 ноября 2010

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

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

1 голос
/ 28 ноября 2010

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

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

0 голосов
/ 28 ноября 2010

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

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

...