繁体   English   中英

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

[英]What is the difference between defining a function type and a function pointer type?

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

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"

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

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

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

  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; 

后者对于避免重复非常有用。 但请注意,函数类型不允许使用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);
}
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);

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

鉴于您可以使用函数指针( &funcfunc*func**func ,...最终作为函数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;
}

汇编

$ gcc -g -O3 -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
>     -Werror  pfn.c -o pfn
pfn.c: In function ‘a’:
pfn.c:13:5: error: function ‘fn2’ is initialized like a variable
     fn fn2 = callback;
     ^
pfn.c:13:8: error: nested function ‘fn2’ declared but never defined
     fn fn2 = callback;
        ^
$

看看最后一段这里

这有助于您更好地理解fucntion和函数指针的typedef。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM