Указатели функций, замыкания и лямбда - PullRequest
83 голосов
/ 16 октября 2008

Я только сейчас узнаю о функциональных указателях и, когда я читал главу K & R по этому вопросу, первое, что поразило меня, было: «Эй, это как закрытие». Я знал, что это предположение в корне неверно, и после поиска в Интернете я не нашел никакого анализа этого сравнения.

Так почему же указатели на функции в стиле C принципиально отличаются от замыканий или лямбд? Насколько я могу судить, это связано с тем, что указатель на функцию по-прежнему указывает на определенную (именованную) функцию, в отличие от практики анонимного определения функции.

Почему передача функции в функцию, которая считается более мощной, во втором случае, где она безымянна, чем в первом, где передается обычная повседневная функция?

Пожалуйста, скажите мне, как и почему я ошибаюсь, сравнивая их так близко.

Спасибо.

Ответы [ 12 ]

1 голос
/ 16 октября 2008

Основное различие возникает из-за отсутствия лексического определения в C.

Указатель функции - это просто указатель на блок кода. Любая переменная не из стека, на которую она ссылается, является глобальной, статической или аналогичной.

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

Несколько замыканий могут совместно использовать некоторые переменные, и поэтому могут быть интерфейсом объекта (в смысле ООП). чтобы сделать это в C, вы должны связать структуру с таблицей указателей на функции (это то, что делает C ++, с классом vtable).

короче говоря, замыкание - это указатель на функцию ПЛЮС некоторого состояния. это конструкция более высокого уровня

0 голосов
/ 16 октября 2008

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

...