Подтвердить что ты не робот

В C, в чем разница между `& function` и` function` при передаче в качестве аргументов?

Например:

#include <stdio.h>

typedef void (* proto_1)();
typedef void proto_2();

void my_function(int j){
    printf("hello from function. I got %d.\n",j);
}

void call_arg_1(proto_1 arg){
    arg(5);
}
void call_arg_2(proto_2 arg){
    arg(5);
}
void main(){
    call_arg_1(&my_function);
    call_arg_1(my_function);
    call_arg_2(&my_function);
    call_arg_2(my_function);
}

Запустив это, я получаю следующее:

> tcc -run try.c
hello from function. I got 5.
hello from function. I got 5.
hello from function. I got 5.
hello from function. I got 5.

Мои два вопроса:

  • В чем разница между прототипом функции, определенным с помощью (* proto) и одним, указанным без?
  • В чем разница между вызовом функции с ссылочным оператором (&) и без?
4b9b3361

Ответ 1

Нет никакой разницы. Для доказательства см. спецификация C99 (раздел 6.7.5.3.8).

"Объявление параметра в качестве возвращаемого типа функции должно быть отрегулировано на указатель '' to возвращаемый тип функции, как в 6.3.2.1. "

Ответ 2

нет разницы между &function и function при передаче в качестве аргумента

однако существует разница между вашими typedefs. Я не знаю официального объяснения, а что именно разница, но из того, что я помню

typedef void (*name1)(void);

и

typedef void(name2)(void);

разные:

name1 является указателем на функцию, которая не принимает никаких параметров и ничего не возвращает

name2 - это функция, которая не принимает никаких параметров и ничего не возвращает

вы можете протестировать его, скомпилировав:

typedef void (*pointer)(void);
typedef void (function)(void);

void foo(void){}

int main()
{
    pointer p;
    function f;

    p = foo; //compiles
    p();

    f = foo; //does not compile
    f();
}

снова, я не тот человек, который объясняет точную причину такого поведения, но я верю, что если вы посмотрите на стандарты, вы найдете объяснение где-то там.

Ответ 3

Нет никакой разницы между функцией и функцией - они оба являются адресами. Вы можете увидеть это, напечатав их оба:

function bar(); 

.... 
printf("addr bar is 0x%d\n", &bar);
printf("bar is 0x%d\n", bar);

Ответ 4

Разница только стилистическая. У вас такой же сценарий при использовании указателей функций:

void func (void);

...

void(*func_ptr)(void) = func;

func_ptr();    // call func
(*func_ptr)(); // call func

printf("%d\n", ptr); 
printf("%d\n", *ptr);

Некоторые говорят, что желательно использовать синтаксис (* func_ptr)(), чтобы было ясно, что вызов функции выполняется с помощью указателя функции. Другие считают, что стиль с * более ясен.

Как обычно, нет никаких научных исследований, доказывающих, что любая форма лучше, чем другая, поэтому просто выберите один стиль и придерживайтесь его.