我是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练习它,它给了我错误:
非法初始化程序(只能初始化变量)
但是我认为编译器可以识别出两者是一样的,为什么必须有一对括号?
答案 0 :(得分:9)
在原始代码中
int (*minus)(int,int)=subtraction;
将minus
声明为函数指针,它接受参数int, int
并返回int
。
在你的第二个代码中
int *minus(int,int)=subtraction;
将minus
声明为函数,它接受参数int, int
并返回指针int *
。
您可以使用函数名称(自动转换为函数指针)来初始化函数指针,但不能初始化函数。
答案 1 :(得分:3)
这是operator precedence的问题。函数调用operator()的优先级高于取消引用运算符*。因此,您必须使用括号来指定正确的评估顺序。
int *minus(int, int)
表示:首先调用名为minus的函数,然后取消引用返回值(在本例中为int *)。
int (*minus)(int, int)
表示:首先取消引用“减号”,它返回一个函数,然后调用该函数。
答案 2 :(得分:2)
您已使用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;
}