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