Различия в указателях функций C - PullRequest
1 голос
/ 20 марта 2019

У меня есть следующий код C:

#include <stdio.h>

int max(int x, int y, int (*compare)(int, int))
{
  return (*compare)(x,y) ? x : y;
}

int greater_than(int x, int y)
{
  if(x > y) return 1;
  else return 0;
}

int main(void) {
 printf("%d",max(6,7,greater_than));
}

Это просто для проверки указателей функций.Но код все еще работает так же, даже если я не использую int (*compare)(int,int), но int compare(int,int).Это также работает, если я не разыменую указатель функции или если использую int compare(int,int), но все еще разыменую.Это также не имеет значения, если я пройду greater_than или &greater_than.Почему это?

Что касается Новы

Ответы [ 2 ]

4 голосов
/ 20 марта 2019

Эти 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;
}
0 голосов
/ 20 марта 2019

Великолепный ответ, данный Лундиным ранее. Реп слишком низкий, чтобы комментировать, поэтому я добавлю это здесь как дополнительный Я видел ссылку на подобный пост здесь на stackoverflow, мне понравился учебник.

Происхождение ссылки на учебник: Как передать функцию в качестве параметра в C?

Учебник указателя функции, упомянутый выше: http://www.newty.de/fpt/index.html

Надеюсь, я не самонадеян, мне понравилось, может быть, это будет приятным и для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...