当前位置:   article > 正文

c++函数指针相关知识点详细总结!!!_函数指针考点

函数指针考点

函数指针初识

  • 函数指针指向的是函数而非对象。
  • 和其他指针一样,函数指针指向某种特定类型。
  • 函数的类型由它的返回类型和形参类型共同决定。
  • 例如:
//比较两个string对象的长度
bool lengthCompare(const string& s1,const string& s2);
  • 1
  • 2
  • 该函数的类型是
  • bool(const string&,const string&).
  • 要想声明一个可以指向该函数的指针,只需要用指针替换函数名即可:
	//pf指向一个函数,该函数的两个参数是const string的引用,返回值是bool类型
	bool (*pf)(const string & , const string &);//未初始化
  • 1
  • 2

注意:pf两端的括号比不可少,如果不写,则pf是一个返回类型为bool指针的函数

函数指针的使用

  • 当我们把函数名作为一个值使用时,该函数自动转换为指针。
	pf = lengthCompare;//pf指向名为lengthCompare的函数
	pf=&lengthCompare; //等价赋值语句:取地址符是可逆的
  • 1
  • 2
  • 此外,我们还能直接使用指向函数的指针调用该函数,无须提前解引用指针:
	bool b1 = pf("hello", "goodbye");//调用lengthCompare函数
	bool b2 = (*pf)("hello", "goodbye");//一个等价的调用
	bool b3 = lengthCompare("hello", "goodbye");//另一个等价调用
  • 1
  • 2
  • 3
  • 在指向不同函数类型的指针间不存在转换规则
  • 我们可以将函数指针赋值为nullptr或者值为0的整形常量表达式,表示当前函数指针没有指向任何一个函数
bool lengthCompare(const string& s1, const string& s2)
{
	cout <<s1<<" "<<s2<< endl;
	return true;
}
string::size_type sumLength(const string&, const string&)
{
	return 0;
}
bool cstringCompare(const char*, const char*)
{
	return true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
	pf = 0;//正确:pf不指向任何函数
	pf = sumLength;//错误:返回类型不匹配
	pf = cstringCompare;//错误:形参类型不匹配
	pf = lengthCompare;//正确:函数和指针类型精确匹配
  • 1
  • 2
  • 3
  • 4

重载函数指针

  • 当我们使用重载函数时,上下文必须精确地界定到底应该选用哪个函数。
void ff(int*)
{
	cout << "ff(int*)" << endl;
 }
void ff(unsigned int)
{
	cout << "ff unsigned int" << endl;
}
void test()
{
	void (*pf1)(unsigned int) = ff;//pf1指向ff(unsigned)
	pf1(1);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述

  • 编译器通过指针类型决定选用哪个函数,指针类型必须与重载函数中某一个精确匹配。
	void (*pf2)(int) = ff;//错误:没有任何一个ff与该形参列表匹配
	int (*pt3)(int*) = ff;//错误:没有任何一个ff与pt3的返回类型匹配
  • 1
  • 2

函数指针形参

  • 虽然不能定义函数类型的形参,但是形参可以是指向函数的指针。此时形参看起来是函数类型,实际上却是当做指针使用。
//比较两个string对象的长度
bool lengthCompare(const string& s1, const string& s2)
{
	if(s1.size()>s2.size())
	return true;
	return false;
}
//第三个参数是函数类型,它会自动转换成指向函数的指针
bool useBigger(const string& s1, const string& s2, bool bf(const string& s1, const string& s2))
{
	return bf(s1, s2);
}
void test()
{
	string s1 = "abc";
	string s2 = "abcdfe";
	if (useBigger(s1, s2, lengthCompare))
	{
		cout << "s1大于s2" << endl;
	}
	else
		cout << "s1小于s2" << endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
//等价的声明:显示地将形参定义成指向函数的指针
bool useBigger(const string& s1, const string& s2, bool (*bf)(const string& s1, const string& s2))
{
	return bf(s1, s2);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 我们可以直接把函数作为实参使用,此时它会自动转换为指针
//自动将函数lengthCompare转换成指向该函数的指针
useBigger(s1, s2, lengthCompare);
//或者也可以用取地址符
useBigger(s1, s2, &lengthCompare);
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

  • 类型别名和decltype能让我们简化使用了函数指针的代码:
     //func和func2是函数类型
	typedef bool func(const string&, const string&);
	typedef decltype(lengthCompare) func2;//等价的类型
	//funcp和funcp2是指向函数的指针
	typedef bool(*funcp)(const string&, const string&);
	typedef decltype(lengthCompare)* funcp2;//等价的类型
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 我们使用typefdef定义自己的类型,func和func2是函数类型,而funcp和funcp2是指针类型,需要注意的是decltype返回函数类型,此时不会将函数类型自动转换为指针类型因为decltype的结果是函数类型,所以只有在结果前面加上*才能得到指针。
  • 可以使用如下形式重新声明useBigger:
	//useBigger的等价声明,其中使用了类型别名
	void useBigger(const string & s1, const string & s2, func);
	void useBigger(const string & s1, const string & s2, func2);
	void useBigger(const string & s1, const string & s2, funcp);
	void useBigger(const string & s1, const string & s2, funcp2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 前两句等价声明中,编译器自动把func表示的函数转换为指针

返回值指向函数的指针

  • 和数组类似,虽然不能返回一个函数,但是能返回指向函数类型的指针,
  • 然而,我们必须把返回类型写成指针形式,编译器不会自动地将函数返回类型当初对应的指针类型处理
  • 与前面一样,要想声明一个返回函数指针的函数,最简单的办法是使用类型别名:
using F = int(int*, int*);//F是函数类型,不是指针
using FF = int(*)(int*, int*);//FF是指针类型
  • 1
  • 2

注意:返回值不会自动地转换为指针,我们必须显示将返回类型指定为指针

	FF f1(int);//正确:FF是指向函数的指针,f1返回指向函数的指针
	F f2(int);//错误:F是函数类型,f1不能返回一个函数
	F* f3(int);//正确:显示地指定返回类型是指向函数的指针
  • 1
  • 2
  • 3
  • 当然,我们也可以用下面形式直接声明f1:
	int (*f1(int))(int*, int*);
  • 1
  • 按照由内向外的顺序阅读这条声明语句:我们看到f1有形参列表,所以f1是个函数;

  • f1前有*,所以f1返回一个指针;

  • 进一步观察发现,指针的类型本身也包含形参列表,因此指针指向函数,该函数返回的类型是int.

  • 举例说明:

int addSum(int* a, int* b)
{
	cout << "a+b= " << *a + *b << endl;
	return 1;
}
int (*f1(int val))(int*, int*)
{
	 addSum(&val, &val);
	 return addSum;
}
void test()
{
	auto ret = f1(10);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在这里插入图片描述

将auto和decltype用于函数指针类型

  • 如果我们明确知道返回的函数是哪一个,就能使用decltype简化书写函数指针返回类型的过程。
string::size_type a(const string& s1, const string& s2)
{
	return s1.size() + s1.size();
}
string::size_type b(const string& s1)
{
	return s1.size() + s1.size();
}
decltype(a) * getFunc(const string& s)
{
	cout << "a(s,s)= " << a(s, s) << endl;
	b(s);
	return a;
}
void test()
{
	auto ret = getFunc("abc");
	cout << ret("abcd","casd") << endl;
	//直接打印函数名,或解引用的效果一样,得到的都是函数的地址
	cout << ret<< endl;
	cout << *ret<< endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这里插入图片描述

在这里插入图片描述
点个赞,再走吧,个位亲

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/726480
推荐阅读
相关标签
  

闽ICP备14008679号