Вызов функции через указатель на функцию-разыменование указателя или нет? Какая разница?
Я пытался как - 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 );
оба, кажется, работают (без ошибок, без предупреждений, отсортированных массивов), и я немного запутался. Какой правильный или они оба верны?
2 ответов
sort_ptr( arr1, 5 );
и
(*sort_ptr)( arr2, 5 );
оба правы. На самом деле, вы можете поставить столько звездочек, сколько хотите, и все они правильные:
(*****sort_ptr)( arr2, 5 );
имя функции распадается на указатель на функцию. Таким образом, разыменование его повторно приведет к созданию одного и того же указателя.
что касается компилятора,sort_ptr
и (*sort_ptr)
идентичны. Если sort_ptr
действительно является указателем, однако, явно разыменовав его, делает вещи намного яснее для читателя. В общем; есть один случай, когда тот факт, что вы можете вызвать функцию непосредственно на указателе на функцию, полезен: в шаблонах, где он делает указатель на функцию функциональным объектом, который ведет себя точно так же, как класс с operator()()
.