【问题标题】:Typedef function and is it useful? [duplicate]typedef 函数,它有用吗? [复制]
【发布时间】:2019-08-10 09:26:22
【问题描述】:

我正在深入研究语言,所以我可以理解代码中正在发生的事情,而不是打印一些东西然后观察看看会发生什么。

最近,为了更好地实现类函数表,我发现自己偶然发现了这个 C 语言标准:http://www.iso-9899.info/wiki/Typedef_Function_Type

我已经尝试过了,它似乎可以工作:

typedef void fnr(int x);

main()
{
    fnr t;
}

对于我寻找将函数打包到我的结构中的方法来说,这似乎是一个美好的一天,直到我意识到 fnr t; 并没有我预期的那么有用。它既不能被分配,也不能以我希望的正确方式使用(对于 C 用户来说可能是 lambda)。它甚至在反汇编中都不存在!

此语言功能有什么作用?除了简化函数指针,它还能用来做什么?

【问题讨论】:

  • 如果声明为fnr *t;,则可以赋值,或者在变量声明时不需要*,只需将typedef更改为typedef void (*fnr)(int);,这样你就可以使用fnr t;并赋值它通常。也就是说,我非常不清楚你的目标。 typedef 只允许您将复杂的事物别名为简单的名称,您似乎希望它做一些非常不同的事情。
  • "善用(不只是创建指针)" 使用函数 typedef 使指针指向函数类型 可读 是最重要的之一它们的用途,恕我直言。 fnr t; 是一个无用的字符串” fnr t; 扩展为 void t(int x);。你知道什么是函数声明以及它们的用途吗?使用 typedef 声明函数是否是一个好主意是另一个问题。
  • @HolyBlackCat 这不是函数声明,这是类型定义。如果你声明了同名的函数,它将不起作用
  • @IlyaPakhmutov 这是一个函数声明,see for yourself
  • @IlyaPakhmutov 在该示例中,fnr t; 行与 void t(int x); 完全相同,这是一个函数声明。

标签: c function function-pointers typedef


【解决方案1】:

您已将fnr 声明为函数类型。虽然不能分配函数类型,但指向函数类型的指针可以。例如:

typedef void fnr(int x);

void f(int x)
{
    printf("x=%d\n", x);
}

int main()
{
    fnr *t = f;
    t(1);
}

您也可以将 typedef 定义为函数指针:

typedef void (*fnr)(int x);
...
fnr t = f;

当函数指针被传递给函数或从函数返回时,对函数指针使用 typedef 是最有用的。举个例子,让我们看看signal 函数,它同时具备这两种功能:

  typedef void (*sighandler_t)(int);

  sighandler_t signal(int signum, sighandler_t handler);

这个函数的第二个参数是一个指向信号处理函数的指针,它还返回一个指向信号处理函数的指针。如果没有 typedef,它看起来像这样:

void (*signal(int signum, void (*handler)(int)))(int)

【讨论】:

  • 好吧,这似乎并不明显,我知道 fPointers 是什么,但问题是:这个函数的 typedef 是为了什么?我知道我可以从中创建指针,但 C 在其标准中甚至没有 bool,但这显然是无用的 typedef。但最重要的是,我不能给它分配任何东西。它所做的唯一一件事就是明确将 func 指针传递给回调函数。
  • @IlyaPakhmutov “C 甚至在其标准中都没有布尔” C 从 C11 开始就有布尔值。 “这个,显然是无用的typedef被提出”它有一些用途,如答案所示。在我看来,仅仅因为据称它们没有太多用途,就专门禁止定义函数类型(同时允许所有其他类型)是不明智的。
  • @IlyaPakhmutov C 有一个布尔类型,顺便说一句..._Bool。另请参阅 <stdbool.h> 标头。
  • @IlyaPakhmutov 它是 20 年前才添加的,但遗憾的是,很多 C 教育材料还没有赶上 C99,更不用说新版本了。 C 对新关键字使用保留标识符以避免破坏现有代码(许多旧的东西类型定义或定义 bool)并提供一个标题让您可以使用更传统的非保留名称:_Boolbool_Complexcomplex
  • @Shawn 在这一点上我发现自己一无所知,因为我几乎不会阅读(因为我),而向 prog 或程序员的老师提问是我获取知识的唯一途径。这就是为什么我想出深入学习 C 和 C++ 的想法。我想 git gud :)
【解决方案2】:

typedef 工具主要用作一种抽象机制 - 它用于为类型名称创建别名,以隐藏或简化实现细节。 stdio.h 中的 FILE 类型可能是 C 中的典型示例 - FILE 是存储流状态信息的其他类型(通常是 struct 类型)的 typedef 名称。我们不会直接处理 FILE 对象的内容 - 相反,我们创建一个指向 FILE 的指针,该指针由各种 CI/O 例程(fopenfclosefread、@987654331 @、fscanffprintf 等)。

编辑

至于 typedef-ing 函数类型...

您会经常看到它用于简化回调声明:

typedef void (*callback)( /* callback arguments */ );
...
void do_something( T arg1, T arg2, callback c );

callback 是“指向函数的指针”类型的别名,该函数采用一些回调参数并返回void

【讨论】:

  • 因为 FILE 的内容是占位符 ` typedef struct _iobuf { void* _Placeholder; } 文件;`
  • @IlyaPakhmutov:这是因为 FILE 别名因平台而广泛变化。在我的 SLES10 系统上是typedef struct _IO_FILE FILE;,其中_IO_FILEstruct _IO_FILE { int _flags; char* _IO_read_ptr; char * _IO_read_end; char* _IO_read_base; ...};,而在MaxOS 上是typedef struct __sFILE { unsigned char *_p; int _r; int _w; short _flags; ... } FILE;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
  • 2016-08-13
  • 2014-03-30
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
相关资源
最近更新 更多