【问题标题】:Understanding C typedef了解 C 类型定义
【发布时间】:2013-04-10 01:33:52
【问题描述】:

我试图理解这段来自Tcl documentation的代码

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

据我所知,typedef 的目的是为现有类型分配替代名称,那么为什么需要 typedef int 到 function?这个怎么用?

【问题讨论】:

  • 用于在TCL_CHANNELTYPE中声明function pointers
  • 你怎么看这个(typedef int (*hello)(void);)?

标签: c++ c types tcl


【解决方案1】:

我知道 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。但我猜 C 中唯一可能的用例确实是创建指针变量(因此通常的方法是首先对指针类型进行 typedef)。但还是很高兴知道。
  • @ChristianRau:你也可以使用函数 typedef 来声明一个函数,虽然你在定义它时仍然需要正常的函数声明语法;而在 C++ 中,函数类型通常用作模板参数(例如 std::function<void()>)。
  • 是的,最终 C++ 更多地使用了 types,无论是重载、模板还是...... function-type 语法是 C++11 的新版本,引入时考虑了 std::result_ofstd::function 之类的东西。今天仍然有一些关于旧的 C 的知识;)
  • 在内部,Tcl 使用函数 typedef 有两个目的:在“类描述结构”中提供插件点(如果它是用 C++ 编写的,它会使用类,并且有些地方它不使用类) t 有一个中间结构,因为它只有一个成员)并强制限制将在这些结构中使用的函数具有正确的声明。考虑到 Tcl 代码库的大小,像这样小心谨慎是很有意义的(并且在出现问题时会给出最好的错误消息)。
【解决方案2】:

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

【讨论】:

  • 嗯,很奇怪......它出现在函数名称出现在非 typedef 声明中的完全相同的位置。
【解决方案3】:

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

typedef function_name( int, int);

function_name function1;
function_name *function2;

在这里,在您的情况下, typedef 语句用于声明“ Tcl_DriverOutputProc ”函数。并且在“struct Tcl_ChannelType”中使用“Tcl_DriverOutputProc”来声明“*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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 2011-05-28
    • 2021-11-19
    相关资源
    最近更新 更多