typedef如何用于函数指针

我想我可能患有可怕的“偶然程序员”疾病,至少在涉及typedef和函数指针时。 所以我一直在试验各种涉及这些的组合,根据我得到的所有输出来分析结果。

但是,当我继续尝试不同的组合,而不是分析结果,我现在只是在过程中丢失。

我希望你们能帮助我搞清楚这个烂摊子。

第一个代码示例

typedef void (print)(void); void do_something (void) { printf("Hello World\n"); } print *pr; pr = &do_something; pr(); // Hello World 

第二个代码示例

 typedef void (print)(void); void do_something (void) { printf("Hello World\n"); } print *pr; pr = do_something; pr(); // Hello World 

上面的代码示例如何工作,好像’&’对函数名称没有影响

第三个代码示例

 typedef void (print)(void); void do_something (void) { printf("Hello World\n"); } print pr; pr = do_something; // compile error pr = &do_something; // compile error pr(); 

我希望上面的任务之一可以在这里工作但该死的! 我真的不懂函数指针(也可能是typedef)。

函数名称的地址和普通函数名称都是相同的,因此&对函数名称没有影响。

同样,使用函数指针时,多个解除引用不是问题:

 #include  typedef void print(void); static void dosomething(void) { printf("Hello World\n"); } int main(void) { print *f1 = dosomething; print *f2 = &dosomething; f2(); (f1)(); (*f1)(); (**f2)(); (***f1)(); (****f2)(); (*****f1)(); } 

在以下情况下完全编译:

 gcc -O3 -g -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \ -Wold-style-definition -std=c99 xx.c -o xx 

我不会说多颗星是好的风格; 事实并非如此。 它是’奇怪的,(是的,你可能会说)反常’。 一个就足够了(一个明星主要是像我这样的人,在标准之前学会用C编程说“可以通过指针调用函数而不使用(*pointer_to_function)(arg1, arg2)表示法;你如果你喜欢“) pointer_to_function(arg1, arg2)可以写出pointer_to_function(arg1, arg2) )。 是的,这很奇怪。 不,没有其他类型(或类别类型)表现出相同的行为,谢天谢地。

关于函数指针的事情是它们是函数指针! :-)这就是你的第三个样本的工作方式:

 #include  typedef void (*print)(void); // ^ void do_something (void) { printf("Hello World\n"); } int main (void) { print pr; pr = do_something; // &do_something would also work. pr(); return 0; } 

无论您使用的是funcName还是&funcName ,都无关紧要(至少在C中)。 第6.3.2.1 Lvalues, arrays and function designators6.3.2.1 Lvalues, arrays and function designators指出:

函数指示符是具有函数类型的表达式。 除非它是sizeof运算符或一元&运算符的操作数,否则将具有“函数返回类型”类型的函数指示符转换为具有“指向函数返回类型的指针”类型的表达式。

事实certificate,在C / C ++中, funcname&funcname都将产生&funcname的地址,并且可以分配给函数指针变量。 这实际上只是为语言设计语法的一个奇怪之处。

与C类似,C ++具有指向函数的指针: void (*)()例如是一个指向函数的指针,该函数不带参数且不返回任何值。 但是,C ++还引入了函数void (&)()引用,并且两者之间存在隐式转换(尽管我不完全记得规则)。

因此:

  • funcname是对函数的引用
  • &funcname是函数的指针

请注意,将地址(或引用)过载的函数需要static_cast到确切的类型(以解决重载)。