Какой правильный стиль использовать указатель на функцию? - PullRequest
0 голосов
/ 22 сентября 2018

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

Вот мой код:

#include <stdio.h>
#include <stdlib.h>

typedef int(*pfun)(int a, int b);

int add(int a, int b)
{
    return a + b;
}

int f1()
{
    pfun fun = add;
    return fun(3, 4);
}

int f2()
{
    pfun fun = &add;     //Why did't compiler report an error?
    return fun(3, 4);   //Why it could work? The value in fun should be a pointer of function pointer.
}

int f3()
{
    pfun fun = &add;
    return (*fun)(3, 4);    //Why did't compiler report an error?

}

int main()
{
    printf("%d,%d,%d\n", f1(),f2(),f3());
    system("pause");
    return 0;
}

Вывод 7,7,7 без ошибки компиляциив VS2017.

Ответы [ 2 ]

0 голосов
/ 22 сентября 2018

В f2 Ваш комментарий неверный.&add не может быть указателем на указатель;на какой объект указателя он будет указывать?Аналогично, данный char array[N];, &array не является указателем на указатель.Он имеет тип указателя на массив.И идентификаторы типа функции и массива в большинстве контекстов оцениваются как указатели (указатель на функцию или указатель на первый элемент соответственно), но это не означает, что они сами имеют тип указателя.

In f3, *fun - это выражение для функции, которая всегда неявно преобразуется в указатель на функцию.Просто нет такого понятия, как выражение с типом функции.Следовательно, ****************fun также оценивает то же самое, что и fun (указатель на add).

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

Для каждого языка ни одна из этих форм не является более "правильной", чем любая другая, но я думаю, что большинство программистов на Си находят использование *Операторы 1017 * и * в лучшем случае избыточны (если не вводят в заблуждение) с функциями и считают f1 наилучшим.

0 голосов
/ 22 сентября 2018

Нет разницы между add и &add.Оба выражения представляют адрес функции.

Что касается

fun(3, 4);
// vs.
(*fun)(3, 4);

, то не имеет значения, не указана ли неявная ссылка на указатель на функцию или вы делаете это явно.

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