函数指针与函数名

    技术2022-05-11  27

    迷惑很久的问题了,今天正好又遇到这个问题,就抽了个时间研究总结了一下把它记录下来。

    和同学讨论一个typedef的问题,实验过程中偶然发现VS2005的行为:

    int fun(){    cout << "fun()" <<endl;    return 43;}int (*callback())(){//对         return fun; //returns function pointer}int (callback())(){//不对,报错:function returns function           return fun; //returns function}

    C99中的一个例子:

    typedef int F(void);            // type F is "function with no parameters                                            // returning int"F f, g;                                  // fand g both have type compatible with FF f { /* ... */ }                     // WRONG: syntax/constraint errorF g() { /* ... */ }                  // WRONG: declares that g returns a functionint f(void) { /* ... */ }         // RIGHT: f has type compatible with Fint g() { /* ... */ }               // RIGHT: g has type compatible with F

    F *e(void) { /* ... */ }        // e returns a pointer to a functionF *((e))(void) { /* ... */ }  // same: parentheses irrelevantint (*fp)(void);                  // fp points to a function that has type FF*Fp;                                //Fp points to a function that has type F

    typedef int F(void);和typedef int (*F)(void);含义是不同的。

    还可以这样int (*G)(void);这是声明了一个函数变量G,它不是个类型只是个对象。

    因此可以对它赋值但不能用它定义变量。

    int  f(int);

    int  (*pf)(int) = &f;

    初始化表达式中的&操作符是可选的,因为函数名在被使用前总是由编译器把它转换为函数指针,&操作符只是显式地说明了编译器将隐式执行的任务。

    在函数指针被声明并且被初始化之后,我们就可以使用一种方式调用函数:

    int  ans;

    ans = f(25);

    ans = (*pf)(25);

    ans = pf(25);

    第一条语句简单地使用名字调用函数f,但他的执行过程可能和你想像的不太一样。函数名f首先被转换为一个函数指针,该指针制定函数在内存中的位置。然后,函数调用操作符调用该函数,执行开始与这个地址的代码。

    第二条语句对pf执行间接访问操作,它把函数指针转换为一个函数名。这个转换并不是真正需要的,因为编译器在执行函数调用操作符之前又会把它转换回去,不过,这条语句的效果和第一条完全一样。

    第三条语句和前两条的效果一样。间接访问操作并非必须,因为编译器需要的是一个函数指针。这个例子显示了函数指针通常是如何使用的。 


    最新回复(0)