<分区>
我正在使用一个有意混淆的代码,其中包含一个我无法理解的奇怪类型定义。谁能解释以下 typedef 的含义:
typedef void (*p_t)(char* a1, char* a2, int a3);
后来主要使用如下:
int main(void) {
p_t p = &some_function;
p("foo", "bar", 42);
}
<分区>
我正在使用一个有意混淆的代码,其中包含一个我无法理解的奇怪类型定义。谁能解释以下 typedef 的含义:
typedef void (*p_t)(char* a1, char* a2, int a3);
后来主要使用如下:
int main(void) {
p_t p = &some_function;
p("foo", "bar", 42);
}
最佳答案
typedef void (*p_t)(char* a1, char* a2, int a3);
是指向接受参数 typedef
并返回 char* a1, char* a2, int a3
(不返回)的函数的指针的 void
。
考虑一个函数声明(不涉及任何 typedef
),例如:
void fn(char* a1, char* a2, int a3);
现在,假设您希望某个指针 p
指向此函数,那么像 p = fn
这样的赋值应该是有意义的。但是 p
的类型是什么?它将是一个指向函数的指针,但由于函数具有不同的签名(使函数的“类型”不同),您还需要指定它指向的函数的签名。在您的情况下,您需要一个指向接受三个参数的函数的指针:1.) 指向 char
的指针,2.) 另一个指向 char
的指针,以及 3.) int
的指针。此外,该函数返回 void
。所有这些都需要在 p
的类型中指定。所以你的 p
可能被声明(并随后分配)为
void (*p)(char* a1, char* a2, int a3);
p = fn;
可能看起来很奇怪的部分是 *
(将 p
声明为指向某物的指针),它需要与 p
标识符放在括号中。看到像 (*p)(...)
这样的构造应该是一个快速提示,让您问自己是否正在查看指向函数的指针。如果您打算一遍又一遍地使用这样一个指向函数的指针,而不是必须一次又一次地键入所有内容(如果您决定更改函数签名,则可能会出现不一致的风险),制作 typedef
会很方便。在你的情况下,这是
typedef void (*p_t)(char* a1, char* a2, int a3);
在你的例子中,你有
p_t p = &some_function;
这是声明一个类型为 p
的变量 p_t
。如上所述,这是一个指向接受三个参数并返回 void
的函数的指针。此行还使用值 p
初始化 &some_function
。显然 some_function
是在某处定义并接受这三个参数并返回 void
的函数的标识符。它初始化 p
以指向此函数,以便在下一行调用它:
p("foo", "bar", 42);
我很惊讶这不是写成
(*p)("foo", "bar", 42);
这取消引用 p
,它给出函数 some_function
,然后使用参数 "foo"
、 "bar"
和 42
调用该函数。这很方便,因为您可以(如果需要)使 p
指向其他一些函数(具有相同的签名)。因此,关联函数可以是动态的。
值得一提的是,&
中的p_t p = &some_function;
并不是必须的。它不会伤害任何东西,但它不是必需的。函数指针的另一个奇怪之处在于,您可以根据需要多次引用和取消引用,它们的意思是一样的! (看
Why do function pointer definitions work with any number of ampersands '&' or asterisks '*'?)
关于c - void typedef 在 C 中如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49969739/