定义函数类型和函数指针类型有什么区别?

时间:2014-03-10 05:23:34

标签: c

据我所知,我可以定义一个函数类型:

typedef void (fn)(void);

我还可以定义一个函数指针类型:

typedef void (*pfn)(void);

有2个功能。第一个函数的参数类型是一个函数,另一个是函数指针:

void a(fn fn1)
{
    fn1();
}

void b(pfn fn1)
{
    fn1();
}  

我实现了一个函数回调:

void callback(void)
{
    printf("hello\n");
}

并将其作为参数传递给a和b:

int main(void) {
    a(callback);
    b(callback);
    return 0;
}

a和b都运行良好,并打印"hello"

所以我想知道定义函数类型和函数指针类型有什么区别?或者实际上,它们是一样的?

4 个答案:

答案 0 :(得分:2)

函数类型被视为参数列表中相应的函数指针类型。

(非指针)函数类型基本上有两个实际应用:

  1. 如果发现它太巴洛克式,请避免使用函数指针语法。

    int apply(int (*f)(int), int x) {
      return f(x);
    }
    
    int apply(int f(int), int x) {
      return f(x);
    }
    
  2. 声明相同类型的多个功能。

    int add(int, int);
    int subtract(int, int);
    int multiply(int, int);
    int divide(int, int);
    
    typedef int arithmetic(int, int);
    arithmetic add, subtract, multiply, divide;
    
  3. 后者对于避免重复非常有用。但请注意,函数类型不允许您使用const来防止指针被重新分配。所以编译得很好:

    #include <stdio.h>
    
    int pred(int const i) { return i - 1; }
    int succ(int const i) { return i + 1; }
    
    int apply(int f(int), int const x) {
      // Oops, didn’t really mean to reassign ‘f’ here.
      f = pred;
      return f(x);
    }
    
    int main() {
        printf("%i\n", apply(succ, 1));
        return 0;
    }
    

    您可以通过指针const

    来避免这种潜在的错误来源
    int apply(int (* const f)(int), int const x) {
      // error: assignment of read-only parameter ‘f’
      f = pred;
      return f(x);
    }
    

答案 1 :(得分:2)

fn fn2 = callback;

在标准C中是非法的。

void a(fn fn1)

的行为与void a(fn *fn1)完全相同。它是仅在函数形式参数列表中允许的特殊语法,类似于void b(int x[])实际上与void b(int *x)完全相同的行为。如果你执行sizeof fn1,你将获得函数指针的大小。

顺便说一句,你在fn的定义中有多余的括号,这更简单:

typedef void fn(void);

指针版本需要使用括号来关联*

答案 2 :(得分:1)

鉴于滥用,您可以使用函数指针(&funcfunc*func**func,...所有最终都作为函数的相同值{{ 1}}),两者之间几乎没有实际差异。您可以使用func来指示指向函数的指针,这不是一个简单的转换。

但是,这里使用类型为fn *的非参数变量并尝试(未成功)使用类型为pfn的非参数变量,对您的代码进行了温和调整。这不会编译,因此在文件范围(全局)或本地范围内使用时存在差异,而不是在参数列表中使用。

fn

pfn.c

汇编

typedef void (fn)(void);
typedef void (*pfn)(void);

static void callback(void)
{
    printf("hello\n");
}

static void a(fn fn1)
{
    fn fn2 = callback;
    fn *fn3 = callback;
    fn1();
    fn2();
    (*fn2)();
    fn3();
    (*fn3)();
}

static void b(pfn fn1)
{
    pfn fn2 = callback;
    fn1();
    fn2();
}  

int main(void)
{
    a(callback);
    b(callback);
    return 0;
}

答案 3 :(得分:0)

查看最后一段Here

可以帮助您更好地理解fucntion和函数指针的typedef。