Нужен ли указателю функции паретез в c? - PullRequest
1 голос
/ 05 августа 2020

Из этого вопроса Как работают указатели функций в C? , пробовал здесь:

#include <stdio.h>

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

int add2(int(*fp)(int,int)){
    return fp(2,3);
}

int (*factory(int n))(int,int){
    printf("got params:%i\n",n);
    return add;
}

int main(){
    int *p(int,int) = factory(5); // it has to be (*p)
    printf("%i\n",p(1,2));
}

Там упоминалось

стандарт говорит, что имя функции преобразуется в адрес функции

Так что оно должно работать без паретез в любом случае, когда оно преобразовано в адрес.

Но это дает ошибку:

function ‘p’ is initialized like a variable

Но это должна быть функция указатель , а не просто функция. Так как там с синтаксисом?

Ответы [ 5 ]

3 голосов
/ 05 августа 2020

Проблема в том, что

int *p(int,int)

объявляет p как функцию (int, int), возвращающую указатель на int .

Вам нужно

int (*p)(int,int)

, который объявляет p как указатель на функцию (int, int), возвращающую int

2 голосов
/ 05 августа 2020

Компилятор выдает ошибку в вашем коде - поэтому код недействителен .

int *p(int, int); - объявляет функцию, возвращающую указатель

int (*p)(int, int); - определяет указатель к функции.

Вы можете использовать typedefs, чтобы использовать "обычный синтаксис указателя:

typedef int functype(int, int);

functype *p; // defines the function pointer `p`

Кстати, ваш пример будет легче читать, если мы будем использовать typedef s

typedef int func(int, int);

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

int add2(func *funcptr){
    return funcptr(2,3);
}

func *factory(int n){
    printf("got params:%i\n",n);
    return add;
}

int main(){
    func *funcptr = factory(5); 
    printf("%i\n",funcptr(1,2));
}

https://godbolt.org/z/zj4Yax

0 голосов
/ 05 августа 2020
int *p(int,int) = factory(5); 

Это не работает, потому что int *p(int,int) здесь означает объявление функции, которое принимает два int и возвращает указатель на int. Это похоже на то, когда вы пишете int* p(int,int);. Это не указатель на функцию.

Вам нужна скобка:

int (*p)(int,int) = factory(5); // this declare `p` as a function pointer, then assign it to `factory` function.
0 голосов
/ 05 августа 2020

Имя функции действительно преобразуется в адрес функции, поэтому вам не нужно (но можно иметь) & в return add;.

Однако int (*p)(int,int) = factory(5); абсолютно соответствует нужна первая пара круглых скобок, потому что в противном случае (int *p(int,int)) вы объявляете p как функцию, принимающую два int и возвращающую указатель на int, а не как указатель на функцию, принимающую два int s и возвращая int.

0 голосов
/ 05 августа 2020

Вот ваше решение:

#include <stdio.h> 
// A normal function with an int parameter 
// and void return type 
void p(int a) 
{ 
    printf("Value of a is %d\n", a); 
} 
  
int main() 
{ 
    // fun_ptr is a pointer to function p()  
    void (*fun_ptr)(int) = &p; 
  
    /* The above line is equivalent of following two 
       void (*fun_ptr)(int); 
       fun_ptr = &p;  
    */
  
    // Invoking p() using fun_ptr 
    (*fun_ptr)(10); 
  
    return 0; 
} 
...