我认为我可能患有可怕的“偶然程序员”疾病,至少在涉及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)。
答案 0 :(得分:19)
函数名称的地址和普通函数名称都是相同的,因此&
对函数名称没有影响。
类似地,当使用函数指针时,多个解除引用不是问题:
#include <stdio.h>
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)
表示法;你可以写{ {1}}如果你喜欢“)。是的,这很奇怪。不,没有其他类型(或类别类型)表现出相同的行为,谢天谢地。
答案 1 :(得分:7)
关于函数指针的事情是它们是函数指针! :-)这就是你得到第三个样本的方法:
#include <stdio.h>
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 designators
节说明:
函数指示符是具有函数类型的表达式。除非它是sizeof运算符或一元&amp;运算符的操作数。运算符,类型为“函数返回类型”的函数指示符将转换为具有“指向函数返回类型的指针”类型的表达式。
答案 2 :(得分:3)
事实证明,在C / C ++中,funcname
和&funcname
都会产生funcname
的地址,并且可以分配给函数指针变量。这实际上只是为语言设计语法的一个奇怪之处。
答案 3 :(得分:3)
与C类似,C ++具有指向函数的指针:void (*)()
例如是一个指向函数的指针,该函数不接受任何参数并且不返回任何值。但是,C ++还引入了对函数void (&)()
的引用,并且两者之间存在隐式转换(尽管我不完全记得规则)。
因此:
funcname
是对函数的引用&funcname
是指向函数的指针请注意,获取重载函数的地址(或引用)需要static_cast
到确切类型(以解决重载)。