typedef如何用于函数指针

时间:2012-02-20 07:22:17

标签: c++ c syntax function-pointers 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)。

4 个答案:

答案 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到确切类型(以解决重载)。