理解C语言中的typedef

12

我正在尝试理解这段代码,它来自Tcl文档

typedef int Tcl_DriverOutputProc(
        ClientData instanceData,
        const char *buf,
        int toWrite,
        int *errorCodePtr);

据我所知,typedef 的目的是将现有类型指定为替代名称,那么为什么需要将 int 定义为函数呢?这可以用来做什么?

它用于在TCL_CHANNELTYPE中声明函数指针。 - alexrider
你认为这个(typedef int (*hello)(void);)怎么样? - MYMNeo
3个回答

17

我知道typedef的目的是为现有类型分配替代名称。

确切地说。函数有类型,而这将函数类型命名为Tcl_DriverOutputProc。函数类型本身就像缺少名称的函数一样编写:

int(ClientData, const char *, int, int *)

就像函数声明一样,您可以选择包含参数名称或将它们省略。

这可以如何使用?

您可以使用函数指针来在运行时指定行为,例如:

typedef void function();
void hello()   {printf("Hello\n");}
void goodbye() {printf("Goodbye\n");}

int main() {
    function * pf = hello;
    pf(); // prints "Hello"
    pf = goodbye;
    pg(); // prints "Goodbye"
}
在这种情况下,它允许您编写一个函数来处理TCL输出的某些方面,并告诉TCL使用该函数。

哇,我不知道在C中可以为实际函数类型(与常见的指向函数的typedef相反)创建typedef。但我猜在C中唯一可能的用例确实是创建指针变量(因此通常的方法是首先typedef指针类型)。但仍然很好知道。 - Christian Rau
2
@ChristianRau:你也可以使用函数typedef来声明一个函数,尽管在定义时仍需要使用正常的函数声明语法;在C++中,函数类型经常用作模板参数(例如std::function<void()>)。 - Mike Seymour
是的,最终C ++在所有方面都更多地使用类型,无论是重载、模板等。我曾经认为这种函数类型语法是C ++11的新东西,是为了引入std::result_ofstd::function等内容而设计的。今天仍然有一些关于老式C需要学习的东西 ;) - Christian Rau
在内部,Tcl 对于两个目的都使用函数 typedefs:在“类描述结构体”中提供插入点(如果它是用 C++ 编写的,则使用类,并且有些地方没有中间结构,因为那只有一个成员),并强制执行将在这些结构体中使用的函数具有正确声明的限制。鉴于 Tcl 代码库的规模,像这样仔细处理非常有意义(并且在出现错误时提供最佳错误消息)。 - Donal Fellows
@MikeSeymour 我想应该是 pf(); 而不是 pg();。但是因为这是一个非常老的回答,我不会进行编辑...也许我错过了什么。 - Support Ukraine

3

typedef也可以用来声明一个函数,例如"function_name",这个"function_name"可以被用来声明另一个具有相似类型和参数的函数。

typedef function_name( int, int);

function_name function1;
function_name *function2;

在您的情况下,typedef语句用于声明"Tcl_DriverOutputProc"函数。并且"Tcl_DriverOutputProc"被用于"struct Tcl_ChannelType"中声明"*outputProc"。

"struct Tcl_ChannelType"位于Tcl文档的最后。

typedef struct Tcl_ChannelType {
    const char *typeName;
     Tcl_ChannelTypeVersion version;
    Tcl_  DriverCloseProc *closeProc;
    Tcl_DriverInputProc *inputProc;
    Tcl_DriverOutputProc *outputProc;   // <-- DriverOutputproc is used here.
    Tcl_DriverSeekProc *seekProc;
    Tcl_DriverSetOptionProc *setOptionProc;
    Tcl_DriverGetOptionProc *getOptionProc;
    Tcl_DriverWatchProc *watchProc;
    Tcl_DriverGetHandleProc *getHandleProc;
    Tcl_DriverClose2Proc *close2Proc;
    Tcl_DriverBlockModeProc *blockModeProc;
    Tcl_DriverFlushProc *flushProc;
    Tcl_DriverHandlerProc *handlerProc;
    Tcl_DriverTruncateProc *truncateProc;
}Tcl_ChannelType;

0

函数类型的typedef语法很奇怪——你正在创建的类型名称出现在中间。正如Mike Seymour所说,这将名称Tcl_DriverOutputProc分配给函数类型int(ClientData,const char *,int,int *)


2
好奇怪...它出现在与非typedef声明中函数名出现的完全相同的位置。 - Angew is no longer proud of SO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接