声明函数指针

时间:2014-03-12 21:12:10

标签: c pointers

  1. 要使用typedef声明一个函数指针,它将类似于:

    typedef void (*FOO)(int i)

    但通常typedef的语法如下:

    typedef int BOOL

    那么为什么第一个不是:

    typedef void (*)(int) FOO

  2. 要返回一个函数指针(不带typedef),语法如下:

    void (*foo(char c))(int)

    这意味着foo接受一个char并返回一个指向函数的指针,该函数接受一个int并且不返回任何内容。语法太奇怪了!看起来foo接受一个int并且什么都不返回。括号似乎没有在正确的位置。如果要返回一个函数指针,为什么它不是这样的:

    (void (*)(int)) foo(char c)

    这非常简单。我真的很难理解这里的语法,更不用说使用它了。有人可以解释一下这里发生了什么吗?

3 个答案:

答案 0 :(得分:4)

整数只是:

int x;

上述名称由:

给出
typedef int x_type;

指向int的指针是:

int *p;

它的类型是:

typedef int *p_type;

一个名为foo的函数采用double``and returning an int`:

int foo(double);

定义foo的类型为:

typedef int foo_type(double);

现在指向上面的指针应该是*,但是()(函数调用)绑定比*(解除引用)更紧,所以parentesis:

typedef int (*ptr_to_foo_type)(double);

这可能写得更好:

typedef foo_type *ptr_to_foo_type;

正如一些人建议的那样,为了清晰起见。

这个想法是类型描述看起来(有点)像它的用途。给出前缀/后缀运算符的严重错误的想法,很多人都同意。但现在改变已经太晚了。

答案 1 :(得分:1)

声明语法基于表达式的类型,而不是对象。另一种说法是"声明模仿使用"。

让我们从简单的指针表达式开始;称之为iptriptr指向整数值。如果我们想要访问该值,我们需要使用一元iptr运算符取消引用 *,如下所示:

x = *iptr;

表达式 *iptr的类型为int,因此iptr的声明已写入

int *iptr;

如果你想为int指针创建一个typedef,你可以添加typedef来获取

typedef int *iptr;

iptr现在作为"指向int"的指针的同义词,所以你可以写

iptr ip;

ip声明为int的指针(通常,你真的不想在typedef中隐藏指针)。

现在让我们假设您有一个指向函数的指针,该函数需要两个int个参数并返回一个int值,称之为fp。要调用该函数,您可以取消引用指针并将必要的参数传递给结果函数,如下所示:

x = (*fp)(arg1, arg2);  // C allows you to omit the * in the call, so you could
                        // also write it as simply x = fp(arg1, arg2), but we're
                        // leaving it in so the following explanation makes sense

函数调用()运算符的优先级高于一元*; *fp()将被解释为*(fp()),这不是我们想要的。要在调用它指向的函数之前取消引用fp,我们必须使用*fp运算符进行explcitly分组。

表达式的类型 (*fp)(arg1, arg2)int,因此fp的声明变为

int (*fp)(int arg1, int arg2);

现在让我们看看你的第二个例子:foo是一个函数,它接受一个char参数并返回一个指向一个带有int参数并返回的函数的指针void。您可以将其称为

(*foo(c))(x);

同样,表达式 (*foo(c))(x)的类型是void,因此声明是

void (*foo(char c))(int x);

出于语法原因,typedef被视为存储类说明符,如externstatic,尽管它具有非常不同的含义。它并没有改变声明的结构;它只是改变了编译器解释声明的方式。将typedef添加到上面,如

typedef void (*foo(char c))(int x);

现在为类型"函数创建同义词foo,返回指向返回void"的函数的指针。它与诸如

之类的简单类型定义没有什么不同
typedef int *iptr;

的行为。

答案 2 :(得分:0)

1)typedef的语法是声明该类型的变量并将typedef放在它前面。

2)声明的语法回应了实际获取该类型值的语法。请参阅我最近关于寻址运算符(包括函数调用)优先级的其他答案,例如(*twod)[3] vs *(twod)[3] C Pointers ...我不想再重复一遍。