Я попробовал оба — C
а также C++
и оба работают нормально.
Я немного знаком с указателями на функции, и вот простой код, который меня удивил:
#include <assert.h>
void sort( int* arr, const int N );
int main ()
{
int arr1[] = { 1, 5, 2, 6, 2 };
int arr2[] = { 1, 5, 2, 6, 2 };
void (*sort_ptr)( int*, const int) = sort;
sort_ptr( arr1, 5 );
(*sort_ptr)( arr2, 5 );
assert( arr1[0] == 1 && arr1[1] == 2 && arr1[2] == 2 &&
arr1[3] == 5 && arr1[4] == 6 );
assert( arr2[0] == 1 && arr2[1] == 2 && arr2[2] == 2 &&
arr2[3] == 5 && arr2[4] == 6 );
return 0;
}
void sort( int* arr, const int N )
{
// sorting the array, it's not relevant to the question
}
Итак, в чем разница между
sort_ptr( arr1, 5 );
а также
(*sort_ptr)( arr2, 5 );
Оба, кажется, работают (без ошибок, без предупреждений, отсортированных массивов), и я немного запутался. Какой из них правильный, или они оба верны?
sort_ptr( arr1, 5 );
а также
(*sort_ptr)( arr2, 5 );
Оба верны. На самом деле, вы можете поставить столько звездочек, сколько захотите, и все они будут правильными:
(*****sort_ptr)( arr2, 5 );
Имя функции распадается на указатель на функцию. Таким образом, разыменование это будет производить тот же указатель.
Что касается компилятора, sort_ptr
а также (*sort_ptr)
идентичны Если sort_ptr
на самом деле это указатель, однако, явно разыменование делает его более понятным для читателя. В общем; есть один случай, когда полезен тот факт, что вы можете вызывать функцию непосредственно по указателю на функцию: в шаблонах указатель на функцию является функциональным объектом, который ведет себя точно так же, как класс с operator()()
,