C/C++学习笔记17:函数指针

来源:互联网 发布:ubuntu开机自启动服务 编辑:程序博客网 时间:2024/05/21 07:47

指针问题是C/C++中经常性运用的问题,也是非常重要的一个知识点。在前面的章节中经常提到了指针问题,比如指针与引用的区别http://blog.csdn.net/gzbaishabi/article/details/38559581,指针在传递内存中的运用:http://blog.csdn.net/gzbaishabi/article/details/38563613。接下来主要是说一下指针v与函数之间的关系我们从一个一个经典的面试题开始:

请分别写出函数指针、函数返回指针、const指针、指向const的指针、指向const的const指针。

题解:

函数指针: void (*f)()

函数返回指针:void *f()

const指针:const int *纠正:int  *const p

指向const的指针:int *const(面试宝典中给出的结果)纠正:const int *

指向const的const指针:const int* const 

针对上述提出各种指针类型我们接下来一个个的理解:


1:函数指针

1.1 什么是函数指针?

一个函数在编译时被分配一个入口地址,这个函数的入口地址就称之为函数的指针。

1.2 函数指针怎么用呢?

可以用一个指针变量指向函数,然后通过对该指针变量调用函数。

函数原型:数据类型 (*指针变量名)(函数参数列表)

具体用法:

#include <stdio.h>void main(){        int max(int t,int i);     <span style="color:#cc33cc;">   int (*p) (int,int);  </span><em><strong><span style="font-family:Microsoft YaHei;color:#009900;">//用来定义p是指向函数的指针变量,此处就是声明了一个p函数了</span></strong></em>        int a,b,c;        p=max;      <span style="font-family:Microsoft YaHei;color:#009900;"><strong><em>//将max函数的入口地址赋给指针变量p,此处p和max都是指向了函数的开头。</em></strong></span>
<span style="font-family:Microsoft YaHei;color:#009900;"><strong><em>                               //调用(*p)就是调用max函数</em></strong></span>
<span style="white-space:pre"></span><span style="background-color: rgb(255, 255, 255);"><span style="color:#009900;">   <span style="font-family:Microsoft YaHei;"><em><strong>//注意:p是指向函数的指针变量,它只能指向函数的入口处而不可能指向函数中间的某一条指令</strong></em></span></span></span>
<span style="font-family:Microsoft YaHei;color:#009900;"><em><strong style="background-color: rgb(255, 255, 255);">                             //因此不能用*(p+1)来表示函数的下一条指令</strong></em></span>
        scanf("%d,%d,&a,&b");       <span style="background-color: rgb(255, 255, 255);"><span style="color:#cc33cc;"> c=(*p)(a,b);</span></span>        printf("a=%d,b=%d,max=%d\n",a,b,c);}<span style="color: rgb(51, 255, 51);"></span>

特别说明:函数名代表着该函数的入口地址。 


1.3 指向函数的指针可不可以做参数呢?

分析:指向函数的指针是可以做为参数,函数的指针也可以作为参数,以实现函数地址的传递,这样就可以在被调用的函数中使用实参参数。

原理:有一个函数sub,它有两个形参(x1和x2),定义其为指向函数的指针变量:

void sub(int (*x1)(int),int (*x2)(int,int))

在调用sub时,实参为两个函数名f1和f2,给形参传递的是函数f1和f2的地址,这样在函数sub中就可以调用f1和f2:

<span style="color:#33cc00;">int a,b,i,j;a=(*x1)(i);b=(*x2)(i,j);</span>
<span style="font-family:Microsoft YaHei;color:#cc0000;">上面所说的是不是就是类似于函数的嵌套调用,a=(*x1)(i);这其实就是调用f1函数,(*x)这个函数指针又是函数sub的参数。所以就完成了指向函数的指针做参数的用法。</span>

2:返回函数指针(返回指针值的函数)

返回函数指针其实就是一个函数的返回至是指针类型的数据。

函数原型:int *a(int x,int y);a是函数名,调用它以后得到一个指向整型数据的指针(地址)。

具体用法:

<span style="color:#009900;">float *search(float(*pointer)[4],int n);</span>

3:const 指针

const 指针:本身的值不能修改。

原型:int *const p

用法:

<span style="color:#33cc00;">int errNumb = 0;int *const curErr = &errNumb;//curErr是一个指向int型数据的const指针,const指针的值不能够修改</span>
<span style="font-family:Microsoft YaHei;">const指针的值不能够修改 意味着指针curErr不能指向其他的对象。如果企图给const指针赋值,会导致编译错误。</span>
与const量一样,const指针在定义时也必须要初始化。


4:指向const对象的指针

通常我们用指针来修改其所指对象的值,但是如果指针指向了const对象,则不允许指针来改变其所指的const值。在C++语言中强制要求指向const对象的指针也必须具有const特性(指向const对象想const指针)。

具体用法:

const double *cptr
这里的cptr是一个指向double类型const对象的指针,const限定了cptr指向的对象类型而不是cptr本身。意思就是说cptr本身不是const。在定义是不需要对他进行初始化,如果需要的话允许cptr重新赋值,使得其指向另外一个const对象,但是不能通过指针修改其指向的值(即*cptr=42是错误的)。

注意三点:1)不能把一个const对象的地址赋给一个普通的、非const对象的地址。这样会导致编译错误

<span style="color:#33cc00;">const double pi =3.14;const void *ptr = &pi //error,不能把一个const对象的地址赋给一个非const对象的地址const double *cptr = &pi //ok</span>

2)不能用void *指针保存const对象的指针,而必须用const void *类型保存const对象的地址

<span style="color:#33cc00;">const int universe = 42;const void* ptr = &universe; //ok,必须能用const void*类型保存const对象的地址void *ptr = &universe; //error,不能用void* 指针保存const对象的指针</span>


3)允许把非const对象的地址赋一个const对象的地址

<span style="color:#33cc00;">double dval = 3.14;cptr = &dval;</span>

应用:很多时候把指向const对象的指针作为函数的形参,将形参定义为指向const的指针,以此确保传递函数的实际对象在函数中不因为形参而被修改。

5:指向const对象的const指针

既不能修改指针所指向对象的值,也不能修改该指针的指向(指针所存放的地址值)

原型:const double *const

用法:

<span style="color:#33ff33;">const double pi = 3.1415;const double *const pi_ptr = π</span>
(本章关于各部分的介绍主要来源于C程序设计(第三版)和《C++ primer 中文版》李师贤等译》的总结,能力有限,如有错误,欢迎指正)

 

0 0
原创粉丝点击