C/C++开发语言系列之21---C++函数指针的2个例子



今天闲来无事,做了两个C++测试用例

1.  定义一种普通函数 类型

2. 如何理解返回函数的函数


1.

#include <iostream.h>

typedef void funcType();	//定义一种普通函数 类型 ,正常开发中用函数指针类型

void test()
{
	cout<<"test"<<endl;
}

/*

funcType felixFunc()
{
  return &test;             //返回一个指定类型的函数
}
编译器报错:
function returns function 错误类型
A function cannot return a function. Return a pointer to a function instead.

上面为编译器手册说明,所以函数不能返回一个普通的函数,
必须是一个指向函数的指针,所以需要加一个*
*/
funcType* felixFunc()
{
  return &test;   //返回一个函数的地址,注意这里可以去掉&,编译器可以隐式的找到地址
}


int main()
{
	/*
	 由于返回一个指针*类型的函数,所以这里也要顶一个指针变量
	*/
	funcType *f = felixFunc();
	f();
	(*f)();
	//或者直接调用
	felixFunc()();


	return 0;
}


程序分析:

a) typedef void funcType( ); 定义一种普通函数 类型 ,正常开发中用函数指针类型,如

 typedef   void  (*funcType)( ); 

b)  不可以定义下面的函数,编译器的手册提示一个函数不能返回一个普通函数类型,必须是一个指向函数的指针类型,也就是为什么我们正常开发中使用函数指针类型,而不是普通的函数类型的原因

funcType    felixFunc()
{
  return   &test;
}


c)由于我们将funcType 用typedef进行了定义,所以是一种新的类型,这种类型的特点是: 函数返回值为void,且参数也为void。

既然是一种类型,就可以定义变量了,于是我们定义一个变量funcType   f;  

但是如何初始化这个变量呢?

首先我们知道,一般情况下函数不能作为 = 运算符的左值,也就是说  f = ...  .这样显然是不行的。解决办法就是我们可以将 f声明为一个指针就可以了

funcType *f;
f= felixFunc();

或者

funcType *f = felixFunc();


d )    如何通过函数指针变量调用函数呢,方法如下

f();
(*f)();
//或者直接调用
felixFunc()();

(*felixFunc)()();


用函数指针的方式就是


#include <iostream.h>

typedef void (*funcType)();	

void test()
{
	cout<<"test"<<endl;
}


funcType felixFunc()
{
  return test;  //或者return &test;
}


int main()
{

	funcType f = felixFunc();
	f();
	(*f)();
	//或者直接调用
	felixFunc()();
	(*felixFunc)()();

	return 0;
}



2.

上面在定义一个函数类型的时候使用了typedef关键字,正常开发中我们都是大量的使用typedef关键字,目的是方便开发和维护

typedef void (*funcType)(); 


如果这里不使用typedef,那么函数的返回值为一个函数的时候,如

funcType felixFunc()
{
  return test;  //或者return &test;
}

应该如何理解呢?也就是说该如何展开呢?


下面简单的讨论一下,请正常开发中不要这么使用,首先难理解,其次是你的代码给同事看,维护代码都是个问题,这里只做研究,实际开发中用typedef就够了


首先看一段代码

//返回值为void,参数为void的函数类型
typedef void (*new_handler)();
//声明一个函数,返回值为函数,且参数也为函数       
new_handler set_new_handler( new_handler );
用typedef开始来是不是很容易理解呢,我们实际开发中建议用这种方式



好了,看看展开后是个什么样子,做好心理准备
void ( *set_new_handler(void (*)() )  ) (); // 语法正确,但是不友好 
linux 中编程中就会经常遇到这种形式。


如何理解呢?我们分三步走
第一步:
首先写函数的返回值,为一个指向函数的指针
void (*)()


第二步:
写函数名称,难理解的是这里
void (*)()   set_new_handler(new_handler)  //人的思维,但是编译器认为是错误的
正确的是将set_new_handler(new_handler)放到括号里,且*号的后面
void (*set_new_handler(new_handler) )()


第三步:替换函数的参数

void (*set_new_handler(void (*)()) )()


这样是不是理解能好些


或许这样你会明白点:
#include <iostream>
using namespace std;
int p(int x,int y)
{
int n = x>y?x:y;
return n;
}
int (*getFuncPtr())(int,int)
{
return p;
}
int main(){
int (* funPtr)(int,int) = getFuncPtr();

cout<<funPtr(10,10)<<endl;
return 0;
}
/*
第二个函数getFuncPtr是这个函数的函数名称,里面的括号()是它本身的参数括号符来得。
而它前面的*表示返回的是一个指针,后面的()表示了这是一个函数指针,并且该函数指针
所指向的函数有两个int类型的参数,最前面的int表示该函数指针所指向的函数返回值为
int型的。
然后,在main函数中定义一个函数变量来接收getFuncPtr返回的函数指针值。

int (* funPtr)(int,int) = getFuncPtr();

int (* funPtr)(int,int)   表示定义一个函数变量 funPtr,如果用typedef 就很容易理解了,然后 getFuncPtr() 返回一个函数赋值给  funPtr


*/

猜你喜欢

转载自blog.csdn.net/maojudong/article/details/8194897