You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

结构体中void (func)(int)与void (*func)(int)的差异及报错原因

为什么函数参数中的void (func)(int)合法,结构体字段中却报错?

在C语言中,函数参数声明时,void (func)(int)与void (*func)(int)写法等价,以下代码可正常编译运行:

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 (func1)(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);

原因解析

这是C语言语法规则针对不同场景的不同处理逻辑导致的:

  • 函数参数场景:C标准明确规定,当在函数参数列表中声明一个函数类型的参数时,编译器会自动将其隐式转换为指向该函数的指针类型。也就是说void (func)(int)会被编译器等价处理为void (*func)(int),因此两种写法效果完全一致,都表示一个指向"接收int参数、无返回值"函数的指针参数。
  • 结构体成员场景:C语言不允许结构体直接包含函数类型的成员,结构体只能存储数据对象(比如整数、指针等),而函数本身不属于可直接存储的数据对象。void (func1)(int)在结构体中就是直接声明了一个函数类型的成员,这违反了语法规则,因此编译器报错。而void (*func2)(int)是声明一个函数指针类型的成员,指针属于可存储的数据对象,所以是合法的。

内容的提问来源于stack exchange,提问作者Eric Gumba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:50:42