Я изучал обработку сигналов в Unix и наткнулся на это
void (*signal(int sig, void (*func)(int)))(int);
Я не понимаю этот прототип и то, как он возвращает указатель на функцию.
Я также прочитал этот ответ: Как работают указатели функций в C? но мне непонятно.
Предполагается, что он возвращает указатель на функцию, но я не понимаю, где он указывает тип возвращаемого значения в качестве другого указателя на функцию. указатель на функцию. Правильно ли это?
Есть ли для этого более простой пример?
Также: объяснение cdecl — person rs911 schedule 12.08.2013
@millimoose Спасибо, это действительно полезно. — person rs911 schedule 12.08.2013
Кроме того, возвращаемый тип становится указателем на функцию путем добавления списка параметров после сигнатуры функции. (который уже содержит несвязанный список параметров.) Сравните void (*foo(int))
< /a> (то же самое, что void *foo(int)
, но не void (*foo)(int)
) и void (*foo(int))(long)
. Другими словами: возвращаемый тип функции — это то, что находится вне сигнатуры, а не только слева от нее. — person rs911 schedule 12.08.2013
Итак, давайте посмотрим, как объявляется указатель на функцию.
В объявлении, которое вы разместили, есть два типа указателей на функции. Первый — это параметр, который передается в функцию, соответствующую прототипу
signal
:Давайте переименуем этот тип указателя функции в
handler
и дадим ему собственное объявление.Теперь мы можем разбить остальную часть декларации. «Внутренняя» часть — это фактическое объявление функции:
И «снаружи» описывает указатель функции, который он возвращает:
Это тот же тип указателя на функцию, что и наш тип
handler
, так что с этимtypedef
мы могли бы повторно объявить функциюsignal
следующим образом:(Гораздо красивее.)
… что также является
handler
— или я ошибаюсь? — person rs911; 12.08.2013Да действительно. Позвольте мне изменить мой пост, чтобы сделать это немного яснее. — person rs911; 12.08.2013
объявляет signal как возвращающий указатель на функцию, которая принимает int в качестве аргумента и возвращает void. Материал дает аргументы для сигнала, которые в этом случае
То есть первый аргумент функции signal — это int, а второй аргумент — это указатель на функцию, принимающий int в качестве аргумента и возвращающий void.
Редактировать: Таким образом, если вы сделали какой-то звонок, например,
тогда bar будет указателем на функцию, принимающую int и ничего не возвращающую, поэтому ее можно вызвать следующим образом:
Вам не нужно
*
разыменовывать, если вы вызываете указатель на функцию. Просто сделайтеbar(0)
и все в порядке. — person rs911; 12.08.2013Верно, но я считаю, что это помогает запоминать, что происходит в больших проектах. — person rs911; 12.08.2013
Мы можем использовать
typedef
для упрощения определения указателя функции, что может помочь вам понять длинное и сложное определение.приведенный выше код должен вывести:
A is 12
;Надежда помогает!