typedef如何用于函数指针

Raj*_*aja 10 c c++ syntax typedef function-pointers

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

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

我希望你们能帮助我弄清楚这个烂摊子.

第一个代码示例

typedef void (print)(void);
void do_something (void) { printf("Hello World\n"); }

print *pr;
pr = &do_something;
pr(); // Hello World
Run Code Online (Sandbox Code Playgroud)

第二个代码示例

typedef void (print)(void);
void do_something (void) { printf("Hello World\n"); }

print *pr;
pr = do_something;
pr(); // Hello World
Run Code Online (Sandbox Code Playgroud)

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

第三个代码示例

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();
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*ler 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)();
}
Run Code Online (Sandbox Code Playgroud)

在以下情况下完全编译:

gcc -O3 -g -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -std=c99 xx.c -o xx
Run Code Online (Sandbox Code Playgroud)

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

  • +1,要说清楚,函数和函数指针是不一样的,但前者在大多数情况下往往会自动衰减到后者(尽管不是全部).在表达式"**f2"中,函数指针被取消引用,结果函数立即衰减回指针,然后再次取消引用. (4认同)
  • 数组具有类似但不相同的"自动衰减"行为.对于`int x [10];`,`x`和`&x`的地址是相同的.但他们的类型不同,你不能使用这里显示的漂亮的星空塔. (2认同)

pax*_*blo 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;
}
Run Code Online (Sandbox Code Playgroud)

在是否使用条款funcName或者&funcName,它不会(至少在C)关系.部分6.3.2.1 Lvalues, arrays and function designators说明:

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