我正在使用一个故意混淆的代码,其中包含一个我无法理解的奇怪的typedef.任何人都可以解释以下typedef意味着什么:
typedef void (*p_t)(char* a1, char* a2, int a3);
Run Code Online (Sandbox Code Playgroud)
后来主要使用如下:
int main(void) {
p_t p = &some_function;
p("foo", "bar", 42);
}
Run Code Online (Sandbox Code Playgroud)
e0k*_*e0k 10
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);
Run Code Online (Sandbox Code Playgroud)
现在,假设您希望某个指针p指向此函数,那么类似的赋值p = fn应该是有意义的.但那种类型会p是什么?它将是一个指向函数的指针,但由于函数具有不同的签名(使函数的"类型"不同),您还需要指定它指向的函数的签名.在您的情况下,您需要一个指向函数的指针,该函数接受三个参数:1.)指向a的指针char,2.)指向a的另一个指针char,以及3.)a int.此外,该函数返回一个void.所有这些都需要在类型中指定p.所以你p可能会被宣布(并随后被分配)为
void (*p)(char* a1, char* a2, int a3);
p = fn;
Run Code Online (Sandbox Code Playgroud)
可能看起来很奇怪的部分是*(声明p为某事物的指针),需要在括号中加上p标识符.看到一些类似的构造(*p)(...)应该是一个快速提示,问你自己是否正在查看指向函数的指针.如果你要反复使用这样一个指向函数的指针,而不是必须一次又一次地输出所有这些(如果你决定改变函数签名就存在风险不一致),那么制作一个是很方便的typedef.在你的情况下,这是
typedef void (*p_t)(char* a1, char* a2, int a3);
Run Code Online (Sandbox Code Playgroud)
请参阅"顺时针/螺旋规则".
在你的例子中,你有
p_t p = &some_function;
Run Code Online (Sandbox Code Playgroud)
这是声明一个p类型的变量p_t.如上所述,这是一个指向函数的指针,该函数接受三个参数并返回一个void.该行也p用值初始化&some_function.显然some_function是在某处定义的函数的标识符,并接受这三个参数并返回一个void.它初始化p为指向此函数,以便在下一行调用它:
p("foo", "bar", 42);
Run Code Online (Sandbox Code Playgroud)
我很惊讶这不是写的
(*p)("foo", "bar", 42);
Run Code Online (Sandbox Code Playgroud)
该指针引用p,这给函数some_function,然后调用的论据是功能"foo","bar"和42.这很方便,因为你可以(如果你想的话)p指出一些其他功能(具有相同的签名).因此,相关联的功能可以是动态的.
值得一提的是,&in p_t p = &some_function;是没有必要的.它没有伤害任何东西,但它不需要.关于函数指针的另一个奇怪之处在于,您可以根据需要多次引用和取消引用,它们的含义相同!(请参阅
为什么函数指针定义适用于任意数量的&符号'&'或星号'''?)
| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |