所以我被告知这两个几乎一模一样
void function1 (void(func)(int), int arg){
func(arg);
}
void function2 (void(*func)(int), int arg){
func(arg);
}
当我执行它时,它不会抛出错误。
void print_plus_1(int p)
{
printf("p=%d\n", p+1);
}
void print_plus_2(int p)
{
printf("p=%d\n", p+2);
}
int main(void)
{
function1(print_plus_1, 1);
function2(print_plus_2, 1);
}
但是当我在一个结构体内部初始化相同的void(unc)(int)vs void(* unc)(int)模式时
struct foo
{
void (func1)(int);
void (*func2)(int);
};
void print_plus_1(int p)
{
printf("p=%d\n", p+1);
}
void print_plus_2(int p)
{
printf("p=%d\n", p+2);
}
int main(void)
{
struct foo f;
f.func1 = print_plus_1;
f.func2 = print_plus_2;
return 0;
}
它抛出编译器错误?
error: field 'func1' declared as a function
void (func1)(int);
为什么void(func)(void)作为回调函数编写时有效,而作为结构体中的字段编写时无效?
1条答案
按热度按时间fcg9iug31#
名义上,
void (func)(int)
声明了一个函数,它接受int
并且不返回任何东西,而void (*func)(int)
声明了一个指向这样一个函数的指针。在标准基C中,函数不是对象。它们不能赋值给变量,不能作为参数传递,也不能存储在结构成员中。
然而,C 2018 6.7.6.3第8期称:
参数声明为“返回 * 类型 * 的函数”时,应调整为“返回 * 类型 * 的函数指针",如6.3.2.1所示。
这意味着,当你将一个参数声明为函数时,它会自动更改为将该参数声明为指向函数的指针。在C标准中没有任何内容要求在声明结构成员时进行此调整。这就是为什么名义上(而不是实际上)可以将函数参数声明为函数,但不能将结构成员声明为函数的原因。