博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[C++基础]035_指针函数与函数指针<详细讲解>
阅读量:5958 次
发布时间:2019-06-19

本文共 3172 字,大约阅读时间需要 10 分钟。

1. 前言

   关于指针函数和函数指针,特别是函数指针,相信很多C/C++ers跟我曾经一样,对它抱有敬畏,认为它是很高深的东西,其实不然。要理解它花不了多少功夫,或许我一句话就能说清楚二者的区别,但是这样也只是在脑子里形成一个概念而已。大学时代,作为一名学生时,我可以一天看完毛概,考八九十分;但是我用了一个星期去看谭浩强的C++教材(尽管现在很多人鄙视这本教材),上机时却仍无从下手,我可以侃侃而谈,熟悉一切概念,但是就是编不出程序。这就是程序员的世界,凡事只有动手才能领悟真谛。不过这也应证了一句千古名句,也是我最喜欢的一句诗“纸上得来终觉浅,绝知此事要躬行”。

   本文所有代码编译及运行环境:windows 7 professionnal, Visual Studio2010 professional.

2. 概述

   按照行文的总-分-总的结构,这里仍然先概括的介绍一下指针函数和函数指针的概念,然后再用程序来详细的介绍二者。下面就是指针函数和函数指针的概念。

  【指针函数】:返回指针的函数。重点是它是一个函数,只是返回值由普通的值或对象变成了指针,也就是说这个函数返回的是一块内存的地址。

  【函数指针】:指向函数的指针。重点是它是一个指针,只是它指向的内容由普通的变量或对象变成了函数,也就是说它可以指向函数的入口地址。

3. 指针函数

   在介绍指针函数之前,我们先来看一个普通的函数。

1 #include 
2 using namespace std; 3 4 class MyType{ 5 public: 6 MyType(int value):m_value(value){ 7 cout<<"Construct."<

   涂色部分就是我们需要注意的地方,函数"getInstanceOfMyType()"内部创建了一个MyType的对象,接着输出了该对象的地址,最后返回了该对象。main函数里面,通过调用该函数,获得了函数的返回值,接着打印了返回对象的地址,再输出获得对象的m_value属性的值。输出结果如下:

Construct.0045F688Desconstruct.0045F78810请按任意键继续. . .

   可以看到,在"getInstanceOfMyType()"函数里,对象创建之后又被销毁了。从输出可以看出,返回的对象地址与函数里创建的对象地址是不一样的,但是属性m_value的值是一样的,这说明通过该普通函数获取的是函数内部创建对象的一个副本,这就是普通函数在返回对象时的处理。

   在看到普通函数的处理之后,我们再来看一个指针函数的处理,下面是一段指针函数的代码,注意,这段代码与上一段很相似,要注意区分。

1 #include 
2 using namespace std; 3 4 class MyType{ 5 public: 6 MyType(int value):m_value(value){ 7 cout<<"Construct."<
m_value<

   上面代码着色的部分需要我们注意,特别是函数"getInstanceOfMyType()",它在这里已经是一个指针函数了,那么,这段程序的输出是什么呢?如下:

Construct.00754AA800754AA810请按任意键继续. . .

   可以看出,在函数"getInstanceOfMyType()"中的对象一直没有被调用析构函数,函数内和函数外的对象的地址是完全一样的,当然,对象里存储的内容m_value的值也是一样的。你可能会问,不是说函数调用完,就销毁局部变量吗?是的,它销毁了,但是它只销毁了"MyType *mt"这个指针,它指向的内存却不会被销毁。所以,在外面我们仍然可以继续访问这个对象。这种情况下,我们一般是需要在函数调用外面加上我们自己的delete操作的,上面的程序没有添加这样的操作,严格上来讲是一个错误的程序。

   使用指针函数时,直接返回函数内部对象的地址,这样就无需重新制造对象的副本,对效率的提升有帮助。但是需要注意的是,一定要记得在函数外部将函数内部申请的内存释放掉,否则就有内存溢出的风险。

4. 函数指针

   下面说道我们今天主要的话题了——函数指针。函数指针是一个很有用的技术,它使得我们可以通过指针就能执行某一个函数代码。对于技术高超的人来说,它是一把【绝世好剑】,能够解决很多问题。下面,我们就函数指针来探究一番。

   首先,来看一段最简单的函数指针的代码,注意声明和调用的方式。

1 #include 
2 using namespace std; 3 4 int printFunc(int value){ 5 cout<<"this is a print function. the value is:"<
<

   上述代码着色部分就是函数指针的声明-定义-执行的过程,可以看出来,我只要将函数入口地址给函数指针就可以执行函数了。这里有个知识点,就是关于函数的调用方式,一般我们调用函数的方式是这样的:函数名(参数列表),但是其实函数的调用方式也可以这样来写:(*函数名)(参数列表)。即可以如下来调用函数,只是很少这样用:

1 (*printFunc)(8);

   除此之外,我们还可以这样写:(&函数名)(参数列表)。即如下调用函数,这也几乎没人这样用:

1 (&printFunc)(8);

   对于函数指针,它有两个前提:①.就是指向的函数返回值要与声明的函数指针一致。②.指向的函数的参数类型及个数要与声明的函数指针一致。否则,是无法编译通过的。

5. 函数指针类型

   上面一节在使用函数指针的时候,直接声明了一个函数指针。其实函数指针也可以借助typedef声明为一个类型,这样我们就可以像定义int型变量一样来定义一个函数指针了。定义函数指针类型代码如下:

1 #include 
2 using namespace std; 3 4 int printFunc(int value){ 5 cout<<"this is a print function. the value is:"<
<

6. 一个函数指针的妙用示例

1 #include 
2 using namespace std; 3 4 typedef void (*PFunction)(int x); // 函数指针类型,注意返回值和参数列表 5 6 void printA(int value){ 7 cout<<"A - "<
<
>choice;22 ptrFunc[choice](choice);23 24 system("pause");25 return 0;26 }

   具体的这里就不解说了,代码很短,也很容易看懂。

7. 结语

   本文就指针函数和函数指针做了一个简单的入门讲解,希望读者在阅读完本文以后,对指针函数和函数指针有一个深入的认识。当然,写作本文的目的也是为了强化笔者的C++基础功底。

转载于:https://www.cnblogs.com/alephsoul-alephsoul/archive/2012/10/19/2730337.html

你可能感兴趣的文章
[网络流24题-9]试题库问题
查看>>
jquery选择器详解
查看>>
C# 保留2位小数
查看>>
hdu6086(AC 自动机)
查看>>
使用xshell远程连接Linux
查看>>
杭电ACM1007
查看>>
faster-RCNN台标检测
查看>>
Unix环境高级编程 centos中配置apue编译环境
查看>>
运算符
查看>>
数据结构之各排序算法
查看>>
网页分帧操作<frameset>,<iframe>标签
查看>>
Vue生产环境部署
查看>>
酒店之王
查看>>
html5判断用户摇晃了手机(转)
查看>>
VS下Qt4.8.4安装
查看>>
Linux df命令
查看>>
redhat6.5 配置使用centos的yum源
查看>>
取得内表的数据数
查看>>
在一个程序中调用另一个程序并且传输数据到选择屏幕执行这个程序
查看>>
“=” “:=” 区别
查看>>