4

我是C++的新手,最近在学习函数指针,对函数指针的用法有点困惑;

我练习了以下代码:

#include <iostream>
#include <sstream>
using namespace std;

int subtraction(int a,int b){
    return a-b;
}

int main(int argc, const char * argv[])
{

    int (*minus)(int,int)=subtraction;
    cout<<minus(5,4);

    return 0;
}

它运作良好;所以,我尝试了一些变化:

#include <iostream>
#include <sstream>
using namespace std;

int subtraction(int a,int b){
    return a-b;
}

int main(int argc, const char * argv[])
{

    int *minus(int,int)=subtraction;//only here different!
    cout<<minus(5,4);

    return 0;
}

我在 Mac 上的 Xcode 中练习它,它给了我错误:

非法初始化器(只能初始化变量)

但我认为编译器可以识别两者是相同的,为什么必须有一对括号?

4

3 回答 3

9

在您的原始代码中

int (*minus)(int,int)=subtraction;

声明minus为接受参数并返回的函数指针int, intint

在您的第二个代码中

int *minus(int,int)=subtraction;

声明minus为接受参数并返回指针的函数int, intint *

您可以使用函数名(自动转换为函数指针)来初始化函数指针,但不能初始化函数。

于 2013-09-23T06:26:23.070 回答
3

您已标记C++并使用您的代码,iostream因此我可以放心地假设您正在寻找 C++ 解决方案。

在这种情况下,最好使用类模板std::function而不是容易出错的函数指针语法。

#include <iostream>
#include <sstream>
#include <functional>


int subtraction(int a,int b){
    return a-b;
}

int main(int argc, const char * argv[])
{
    std::function<int(int,int)> minus = subtraction;
    //int (*minus)(int,int)=subtraction;
    std::cout<<minus(5,4);

    return 0;
}

或者,如果您仍想继续使用指向函数的指针,建议使用 typedef

#include <iostream>
int subtraction(int a,int b){
    return a-b;
}
typedef int (*MINUS)(int,int);
int main(int argc, const char * argv[])
{
    MINUS minus = subtraction;
    //int (*minus)(int,int)=subtraction;
    std::cout<<minus(5,4);

    return 0;
}

最后,另一个广泛使用的选项是使用函子。

#include <iostream>
struct MINUS
{
    int operator()(int a,int b){
        return a-b;
    }
};
int main(int argc, const char * argv[])
{
    //int (*minus)(int,int)=subtraction;
    MINUS minus;
    std::cout<<minus(5,4);

    return 0;
}
于 2013-09-23T06:50:00.267 回答
3

这是运算符优先级的问题。函数调用运算符 () 的优先级高于取消引用运算符 *。因此,您必须使用括号来指定正确的评估顺序。

int *minus(int, int)

意思是:首先调用一个名为 minus 的函数,然后取消引用返回值(在本例中为 int*)。

int (*minus)(int, int)

意思是:首先取消引用“减号”,它返回一个函数,然后调用该函数。

于 2013-09-23T06:43:13.437 回答