Эти 2 версии эквивалентны:
int max(int x, int y, int (*compare)(int, int))
int max(int x, int y, int compare(int, int))
Точно так же, как массивы, передаваемые в качестве параметров в функции "decay"в указатели на первый элемент, аналогичный «распад» происходит с функциями.Они распадаются на функциональные указатели.Стандарт гласит:
Объявление параметра как '' функции, возвращающего тип '' должно быть настроено на '' указатель на функцию, возвращающую тип ''
Итак, второе(неясная) версия выше переводится компилятором в первую версию.Но нет никакой причины объявлять функцию внутри списка параметров, поэтому вся эта проблема довольно экзотична.
Что касается того, почему compare(x,y)
работает так же хорошо, как (*compare)(x,y)
или в этом отношении (*****compare)(x,y)
, потому что всякий раз, когда вы используете либо имя функции, либо указатель на функцию, вы всегда получаете указатель на функцию.Если вы попытаетесь отменить ссылку на указатель на функцию, вы получите функцию.Который снова возвращается неявно в указатель на функцию.
См. Почему определения указателей на функции работают с любым количеством амперсандов '&' или звездочек '*'? *
Новичков и ветеранов, всех одинаково, можно смело забытьо приведенных выше неясных правилах, и просто сделайте это:
int max(int x, int y, int (*compare)(int, int))
{
return compare(x,y) ? x : y;
}
Или еще лучше, используйте typedef:
typedef int compare_t (int, int);
...
int max(int x, int y, compare_t* compare)
{
return compare(x,y) ? x : y;
}