Нет, объявление / прототип функции C не может иметь более одного идентификатора. См. Справочную страницу и пример кода для signal
на cplusplus.com здесь: http://www.cplusplus.com/reference/csignal/signal/.
В этом объявлении:
void (*signal(int sig, void (*func)(int)))(int);
мы объявляем функция с именем signal
, которая возвращает указатель на функцию, которая возвращает void
и принимает int
- ie: указатель на такую функцию:
void func(int);
Входными данными для функции signal
являются 1-й, int
и 2-й, указатель на функцию, которая возвращает void
и принимает int
- опять же, a указатель на функцию, подобную func
выше. Теперь, в C, при объявлении функции, которая возвращает указатель на функцию и принимает указатель на функцию, она выглядит как goobly-ga-gook (искаженный и сбивающий с толку), поэтому у всех нас возникает путаница первоначально (и снова и снова часто), глядя на объявления функций, такие как signal
. Пара гораздо более понятных способов определения функции, такой как signal
в C, чтобы сделать все это кристально чистым, похожи на это, вместо этого оба они идентичны похожим на goobly-gook:
// 1. typedef a function--call it `func_t` for "func type"
typedef void func_t(int);
// 2. Use the typedef above to define `signal`
func_t* signal(int sig, func_t* fp); // Ah, now this makes sense!
ИЛИ
// 1. typedef a *pointer to* a function--call it `func_p` for "pointer to a func type"
typedef void (*func_p)(int);
// 2. Use the typedef above to define `signal`
func_p signal(int sig, func_p fp); // Ah, now this makes sense too!
И помните, что вы называете каждый тип входного параметра в функции объявление не имеет значения в C и даже не нужно совпадать между заголовком и исходным файлом.
Пример:
my_module.h:
// Any of these 3 prototypes are equivalent, valid, and identical
// (although using sensible names which match between the header &
// source files is most clear and helpful to the reader!):
func_p signal(int sig, func_p fp);
func_p signal(int signal, func_p whatsupdude);
func_p signal(int, func_p);
my_module. c:
func_p signal(int sig, func_p fp)
{
// define the function here
}
Теперь, как я сначала все это выяснил?
Ответ: Я посмотрел пример кода из cplusplus.com . Это помогло TON прояснить все это, поскольку вы можете видеть, как возвращаемое значение из signal
присваивается prev_handler
, который является указателем на функцию, и вы можете видеть, как my_handler
, который определяется как функция, переданная в качестве второго параметра в signal
! Для пиков, я, вероятно, должен также упомянуть, что эти 2 строки идентичны, и обе они совершенно корректны:
prev_handler = signal (SIGINT, my_handler);
prev_handler = signal (SIGINT, &my_handler);
Это потому, что если вы передаете функцию в качестве параметра, то компилятор знает, что он просто берет свой адрес в любом случае.
Пример кода Cplusplus:
/* signal example */
#include <stdio.h> /* printf */
#include <signal.h> /* signal, raise, sig_atomic_t */
sig_atomic_t signaled = 0;
void my_handler (int param)
{
signaled = 1;
}
int main ()
{
void (*prev_handler)(int);
prev_handler = signal (SIGINT, my_handler);
/* ... */
raise(SIGINT);
/* ... */
printf ("signaled is %d.\n",signaled);
return 0;
}
Ссылки:
- Напоминание о том, как вводить определения функций и указатели функций, поскольку это сбивает с толку почти всех и требует время от времени повторной проверки: http://www.iso-9899.info/wiki/Typedef_Function_Type