我想我可能患有可怕的"意外程序员"疾病,至少在类型定义和函数指针方面是这样。所以我一直在尝试各种组合,根据我得到的所有输出来分析结果。
但当我不断尝试不同的组合,而不是分析结果时,我现在只是迷失在这个过程中。
我希望你们能帮我解决这个烂摊子。
第一个代码示例
typedef void (print)(void);
void do_something (void) { printf("Hello Worldn"); }
print *pr;
pr = &do_something;
pr(); // Hello World
第二个代码示例
typedef void (print)(void);
void do_something (void) { printf("Hello Worldn"); }
print *pr;
pr = do_something;
pr(); // Hello World
上面的两个代码示例是如何工作的,就好像"&"对函数名没有影响
第三个代码示例
typedef void (print)(void);
void do_something (void) { printf("Hello Worldn"); }
print pr;
pr = do_something; // compile error
pr = &do_something; // compile error
pr();
我希望上面的一项任务能在这里工作,但该死!我真的不懂函数指针(可能也不懂typedef)。
函数名的地址和普通函数名的含义相同,因此&
对函数名没有影响。
类似地,当使用函数指针时,多重去引用也不是问题:
#include <stdio.h>
typedef void print(void);
static void dosomething(void) { printf("Hello Worldn"); }
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
我不会说多颗星是好风格;事实并非如此。这是"奇怪的,(是的,你可以说)反常的"。一颗星就足够了(一颗星主要是给像我这样的人,他们在标准说"通过指针调用函数而不使用(*pointer_to_function)(arg1, arg2)
表示法是可以的;如果你喜欢,你可以写pointer_to_function(arg1, arg2)
"之前就学会了用C编程)。是的,这很奇怪。不,谢天谢地,没有其他类型(或一类类型)表现出同样的行为。
#include <stdio.h>
typedef void (*print)(void);
// ^
void do_something (void) { printf("Hello Worldn"); }
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 designators
节规定:
函数指示符是具有函数类型的表达式。除非它是sizeof运算符或一元&运算符,类型为"函数返回类型"的函数指示符将转换为类型为"指向函数返回类型的指针"的表达式。
事实证明,在C/C++中,funcname
和&funcname
都会产生funcname
的地址,并且可以分配给函数指针变量。实际上,这只是为语言设计语法的一个奇怪之处。
与C一样,C++也有指向函数的指针:例如,void (*)()
是指向不带参数也不返回值的函数的指针。然而,C++也引入了对函数void (&)()
的引用,并且两者之间存在隐式转换(尽管我记不清具体的规则)。
因此:
funcname
是对函数的引用&funcname
是指向函数的指针
请注意,获取重载函数的地址(或引用)需要static_cast
作为精确类型(以解决重载)。