指针函数与函数指针

来源:互联网 发布:github网站源码 编辑:程序博客网 时间:2024/06/16 22:31

 

1. 指针函数

指针函数是指带指针的函数,即本质是一个函数,函数返回类型是某一类型的指针。

类型标识符    *函数名(参数表) —— int *f(x, y);

首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值;而且,在主调函数中,函数返回值必须赋给同类型的指针变量。

例如:

float *fun();

float *p;

p = fun(a);

注意指针函数与函数指针表示方法的不同,千万不要混淆。最简单的辨别方式就是看函数名前面的指针*号有没有被括号()包含,如果被包含就是函数指针,反之则是指针函数。

代码:

int * GetDate(int wk,int dy);
        void main()
        {
            int wk,dy;
            do
            {
                printf("Enter week(1-5)day(1-7)\n");
                scanf("%d%d, &wk, &dy");
            }
            while(wk<1||wk>5||dy<1||dy>7);
            printf("%d\n", *GetDate(wk,dy));
        }
        int * GetDate(int wk,int dy)
        {
            static int calendar[5][7]=
            {
               {1,2,3,4,5,6,7},
               {8,9,10,11,12,13,14},
               {15,16,17,18,19,20,21},
               {22,23,24,25,26,27,28},
               {29,30,31,-1}
            };
            return &calendar[wk-1][dy-1];
        }

程序子函数返回的是数组某元素的地址。输出的是这个地址里的值。

 

2. 函数指针

函数指针是指向函数的指针变量,即本质是一个指针变量。

类型标识符    *函数名(参数表) —— int (*f)(x, y);

2.1函数指针变量的申明

就象某一数据变量的内存地址可以存储在相应的指针变量中一样,函数的首地址也以存储在某个函数指针变量里的。这样,我就可以通过这个函数指针变量来调用所指向的函数了。
     
C系列语言中,任何一个变量,总是要先申明,之后才能使用的。那么,函数指针变量也应该要先申明吧?那又是如何来申明呢?以上面的例子为例,我来申明一个可以指向MyFun函数的函数指针变量FunP。下面就是申明FunP变量的方法:

void (*FunP)(int) ;   //也可写成void (*FunP)(int x);
     
你看,整个函数指针变量的申明格式如同函数MyFun的申明处一样,只不过我们把MyFun改成(*FunP)而已,这样就有了一个能指向MyFun函数的指针FunP了。当然,这个FunP指针变量也可以指向所有其它具有相同参数及返回值的函数了。

2.2通过函数指针变量调用函数
     
有了FunP指针变量后,我们就可以对它赋值指向MyFun,然后通过FunP来调用MyFun函数了。看看如何通过FunP指针变量来调用MyFun函数:

void MyFun(int x);    //这个申明也可写成:void MyFun( int );

void (*FunP)(int );   //也可申明成void(*FunP)(int x),但习惯上一般不这样。
int main(int argc, char* argv[])
{
   MyFun(10);     //
这是直接调用MyFun函数
FunP=&MyFun;  //
MyFun函数的地址赋给FunP变量
(*FunP)(20);    //
这是通过函数指针变量FunP来调用MyFun函数的。
}
void MyFun(int x)  //
这里定义一个MyFun函数
{
   printf(“%d\n”,x);
}

在这里,MyFunFunP的类型关系类似于int int *的关系。函数MyFun好像是一个如int的变量(或常量),而FunP则像一个如int *一样的指针变量。

int i,*pi;

pi=&i;    //FunP=&MyFun比较。

2.3调用函数的其它书写格式

函数指针也可如下使用,来完成同样的事情:

void MyFun(int x);    
void (*FunP)(int );    //
申明一个用以指向同样参数,返回值函数的指针变量。
int main(int argc, char* argv[])
{
   MyFun(10);     //
这里是调用MyFun(10);函数
   FunP=MyFun;  //
MyFun函数的地址赋给FunP变量
   FunP(20);    //
这是通过函数指针变量来调用MyFun函数的。
      return 0;
}
void MyFun(int x)  //
这里定义一个MyFun函数
{
   printf(“%d\n”,x);
}
在这里,语句“FunP=MyFun;”可以这样将MyFun值同赋值给FunP,难道MyFunFunP是同一数据类型(即如同的int int的关系),而不是如同int int*的关系了.

代码之三:

int main(int argc, char* argv[])
{
   MyFun(10);     //
这里是调用MyFun(10);函数
   FunP=&MyFun;  //
MyFun函数的地址赋给FunP变量
   FunP(20);    //
这是通过函数指针变量来调用MyFun函数的。
      return 0;
}
代码之四:
int main(int argc, char* argv[])
{
   MyFun(10);     //
这里是调用MyFun(10);函数
   FunP=MyFun;  //
MyFun函数的地址赋给FunP变量
   (*FunP)(20);    //
这是通过函数指针变量来调用MyFun函数的。
      return 0;
}
同时一下方法也可以使用:
int main(int argc, char* argv[])
{
  
*MyFun(10);     //看,函数名MyFun也可以有这样的调用格式
      return 0;
}
由此分析并推断出以下的结论:

1. 其实,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
2
. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用(这样方便多了并与数学中的函数形式一样,不是吗?)。
3
. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
4
. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
请这样理解吧!这可是有助于你对函数指针的应用喽! 补充说明一点:在函数的申明处:
void MyFun(int );    //
不能写成void (*MyFun)(int )
void (*FunP)(int );   //
不能写成void FunP(int )

2.4定义某一函数的指针类型:

就像自定义数据类型一样,我们也可以先定义一个函数指针类型,然后再用这个类型来申明函数指针变量。

先看一个自定义数据类型的例子。

typedef int* PINT;    //int* 类型定义了一个PINT的别名

int main()
{
  int x;
  PINT px=&x;   //
int * px=&x;是等价的。PINT类型其实就是int * 类型
  *px=10;       //px
就是int*类型的变量  
  return 0;
}

下面看一下函数指针类型的定义及使用:
void MyFun(int x);    //
此处的申明也可写成:void MyFun( int );
typedef void (*FunType)(int );   //
这样只是定义一个函数指针类型
FunType FunP;              //
然后用FunType类型来申明全局FunP变量
int main(int argc, char* argv[])
{
//FunType FunP;    //
函数指针变量当然也是可以是局部的 ,那就请在这里申明了。
   MyFun(10);     
   FunP=&MyFun;  
   (*FunP)(20);    
      return 0;
}
void MyFun(int x)  
{
   printf(“%d\n”,x);
}

首先,在void (*FunType)(int ); 前加了一个typedef 。这样只是定义一个名为FunType函数指针类型,而不是一个FunType变量。 然后,FunType FunP;  这句就如PINT px;一样地申明一个FunP变量。 其它相同。整个程序完成了相同的事。

这样做法的好处是:有了FunType类型后,我们就可以同样地、很方便地用FunType类型来申明多个同类型的函数指针变量了。如下:

FunType FunP2;

FunType FunP3;

//……

2.5函数指针作为某个函数的参数

既然函数指针变量是一个变量,当然也可以作为某个函数的参数来使用的。所以,你还应知道函数指针是如何作为某个函数的参数来传递使用的。

要求:我要设计一个CallMyFun函数,这个函数可以通过参数中的函数指针值不同来分别调用MyFun1MyFun2MyFun3这三个函数(注:这三个函数的定义格式应相同)。

实现:代码如下:
void MyFun1(int x);  
void MyFun2(int x);  
void MyFun3(int x);  
typedef void (*FunType)(int ); //
. 定义一个函数指针类型FunType,与①函数类型一至
void CallMyFun(FunType fp,int x);
int main(int argc, char* argv[])
{
   CallMyFun(MyFun1,10);   //
. 通过CallMyFun函数分别调用三个不同的函数
   CallMyFun(MyFun2,20);   
   CallMyFun(MyFun3,30);   
}
void CallMyFun(FunType fp,int x) //
. 参数fp的类型是FunType
{
  fp(x);//
. 通过fp的指针执行传递进来的函数,注意fp所指的函数是有一个参数的
}
void MyFun1(int x) //
. 这是个有一个参数的函数,以下两个函数也相同
{
   printf(“
函数MyFun1中输出:%d\n”,x);
}
void MyFun2(int x)  
{
   printf(“
函数MyFun2中输出:%d\n”,x);
}
void MyFun3(int x)  
{
   printf(“
函数MyFun3中输出:%d\n”,x);
}

 

本文出自 “stay hangry,stay foolish” 博客,请务必保留此出处http://hjctty.blog.51cto.com/1031616/559744

0 0
原创粉丝点击