如果没有为第3行中的typedef命名,以下代码如何工作?编译器如何将pf视为新数据类型?
#include <stdio.h>
int fun(int, int);
typedef int (*pf) (int, int);
int proc(pf, int, int);
int main(){
printf("%d\n", proc(fun, 6, 6));
return 0;
}
int fun(int a, int b){
return (a==b);
}
int proc(pf p, int a, int b){
return ((*p)(a, b));
}
答案 0 :(得分:7)
确实给它一个名字:
typedef int (*pf) (int, int);
^^
这是typedef的名字。它读作: pf是一个指向函数的指针,它接受两个int并返回一个int 。
有关函数指针typedef如何工作的更多详细信息,请参阅:
答案 1 :(得分:2)
pf
充当函数的别名,该函数将两个int
s作为参数并返回int
。
这是一个函数指针。
答案 2 :(得分:2)
从语法上讲,typedef
被视为存储类说明符,如extern
或static
。它实际上并没有指定存储类;它只是为了方便而定义的方式。因此,您可以将typedef
替换为static
,并获得具有不同含义但语法相似且定义相同标识符的声明。
你有:
typedef int (*pf) (int, int);
typedef
替换static
给出:
static int (*pf) (int, int);
声明一个名为pf
的函数指针。声明的typedef
版本也声明了标识符pf
,但是作为类型名称,而不是指针对象。
请记住,typedef
不会创建新类型,只会创建现有类型的新名称。 pf
声明不是将typedef
声明为对象,而是使pf
成为类型名称int (*)(int, int)
的别名。
由于存储类说明符是可选的,您还可以通过删除单词typedef
来理解复杂的typedef
声明:
int (*pf) (int, int);
将pf
声明为int (*) (int, int)
类型的对象。
您还可以使用cdecl
程序来解释这样的复杂声明。它不理解typedef
(从版本2.5开始),但您可以删除typedef
关键字:
$ cdecl
Type `help' or `?' for help
cdecl> explain typedef int (*pf) (int, int);
syntax error
cdecl> explain int (*pf) (int, int);
declare pf as pointer to function (int, int) returning int
cdecl>
如果您的系统上没有安装cdecl
程序,那么http://cdecl.org/处有一个在线版
答案 3 :(得分:1)
pf
因为typedef是一个类型定义;它定义了一个函数的签名(作为参数提供什么以及它将返回什么)。
对于使用proc
作为变量的函数p
;它在地址p
执行此函数时定义'契约';此合约只能在编译时检查,因为基本上在运行时p
变量只是一个地址。
答案 4 :(得分:0)
typedef声明有一个名字 - 'pf'。它代表一个函数指针(而不是指向数据,它指向内存中的可执行代码)。
声明函数指针时,typedef不遵循(通常)模式 - “typedef oldTypeName newAliasName”。相反,别名(即上例中的pf)出现在返回类型(左侧)和参数类型(右侧)之间。