Ответ 1
Нет никакой разницы. Для доказательства см. спецификация C99 (раздел 6.7.5.3.8).
"Объявление параметра в качестве возвращаемого типа функции должно быть отрегулировано на указатель '' to возвращаемый тип функции, как в 6.3.2.1. "
Например:
#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)
и одним, указанным без?&
) и без?Нет никакой разницы. Для доказательства см. спецификация C99 (раздел 6.7.5.3.8).
"Объявление параметра в качестве возвращаемого типа функции должно быть отрегулировано на указатель '' to возвращаемый тип функции, как в 6.3.2.1. "
нет разницы между &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();
}
снова, я не тот человек, который объясняет точную причину такого поведения, но я верю, что если вы посмотрите на стандарты, вы найдете объяснение где-то там.
Нет никакой разницы между функцией и функцией - они оба являются адресами. Вы можете увидеть это, напечатав их оба:
function bar();
....
printf("addr bar is 0x%d\n", &bar);
printf("bar is 0x%d\n", bar);
Разница только стилистическая. У вас такой же сценарий при использовании указателей функций:
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)(), чтобы было ясно, что вызов функции выполняется с помощью указателя функции. Другие считают, что стиль с * более ясен.
Как обычно, нет никаких научных исследований, доказывающих, что любая форма лучше, чем другая, поэтому просто выберите один стиль и придерживайтесь его.