指向函数的指针定义,指向函数的指针变量的用法

http://www.itjxue.com  2023-01-07 02:06  来源:未知  点击次数: 

函数指针的定义是什么

函数指针的定义是什么

顾名思义,函数指针就是函数的指针。它是一个指针,指向一个函数。看例子:

A),char * (*fun1)(char * p1,char * p2);

B),char * *fun2(char * p1,char * p2);

C),char * fun3(char * p1,char * p2);

数组参数等效的指针参数

数组的数组:char a[3][4] 数组的指针:char (*p)[10]

指针数组: char *a[5] 指针的指针:char **p

看看上面三个表达式分别是什么意思?

C):这很容易,fun3 是函数名,p1,p2 是参数,其类型为char *型,函数的`返回值为char *类型。

B):也很简单,与C)表达式相比,唯一不同的就是函数的返回值类型为char**,是个二级指针。

A):fun1 是函数名吗?回忆一下前面讲解数组指针时的情形。我们说数组指针这么定义或许更清晰:

int (*)[10] p;

再看看A)表达式与这里何其相似!明白了吧。这里fun1 不是什么函数名,而是一个指针变量,它指向一个函数。这个函数有两个指针类型的参数,函数的返回值也是一个指针。

同样,我们把这个表达式改写一下:char * (*)(char * p1,char * p2) fun1; 这样子是不是好看一些呢?只可惜编译器不这么想

;

如何定义指向函数的指针?

这个用typedef可以完成:

先定义一个函数指针的类型:typedef

void

(*pfun)();

然后用这个类型pfun定义一个数组

pfun

ptr[5];//[]里的数字是数组元素的个数,依情况而定:这儿用5做例子

这样ptr就是一个指向函数指针的数组。

对于“把一个指针强制定义”这我还没听过这个说法,只听过把指针强制转换成某个类型的指针:

强制类型转换用()运算,仍然用上面的定义类型。

例如:

void

*p;//p是一个void指针

pfun

ptr;//ptr是一个指向void函数的指针

ptr=(pfun)p;//把p强制转换成指向void函数的指针,然后就可以把它赋值给ptr指针。

不用typedef也可以,只要合并就可以了:

void

(*ptr[5])();//这样ptr就是一个函数指针数组了.这样看很费解的!不如用typedef。

对于强制类型转换最好还是用typedef,那样可读性好。

而且个人认为指针没有那种基本类型(指向函数的指针类型),那是一种新的类型。所以要先定义那种类型才行。

用typedef定义新类型又没有什么副作用,而且容易读懂,何必非要不用typedef呢?!没必要把简单的问题复杂化!!

程序代码的可读性是很重要的,写复杂的类型而不用typedef是很令人反感的!

C++怎么定义一个指向函数的指针?

C++指向函数的指针定义方式为:

返回类型

(*指针名)(函数参数列表),例如

void

(*p)(int)是指向一个返回值为void

参数为int类型的函数。

而若想定义一个指向类成员函数的函数指针该怎么定义呢?对成员函数指针的使用。

(1)非静态成员函数

定义方式:返回类型

(类名::*指针名)(函数参数列表)例如void

(A::*p)(int)是一个指向A类中成员函数的函数指针。

赋值方式:p=A::函数名,而一般的函数指针的赋值是p=函数名即可,注意区别。(成员函数必须是public类型的)

调用方式:成员函数指针的调用必须通过类对象进行调用,a.*p(int)即可调用成员函数(该成员函数是public类型的)

(2)静态成员函数

对于静态成员函数的定义和使用方法都与普通函数指针的相同,只是在赋值的时候和非静态成员们函数指针的赋值方法相同。

因为静态成员函数的指针类型是与普通函数指针类型相同的。

如何定义一个指向任何函数的指针

 (一) 用函数指针变量调用函数

可以用指针变量指向整形变量、字符串、数组、结构体、也可以指向一个函数。一个函数在编译时被分配一个入口地址。这个入口地址就称为函数指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。用简单的数值比较为例:

1 #include stdio.h

2 #include stdlib.h

3

4 int main()

5 {

6 int max(int,int);

7 int (*p)(int,int);

8 int a,b,c;

9 p = max;

10 scanf("%d,%d",a,b);

11 c = (*p)(a,b);

12 printf("a=%d,b=%d,max=%d\n",a,b,c);

13 return 0;

14 }

15

16 int max(int x,int y)

17 {

18 int z;

19 if(xy) z = x;

20 else z = y;

21 return(z);

22 }

main函数中的" c = max(a,b); " 包括了一次函数的调用。每一个函数都占用一段内存单元。因此,可以用一个指针变量指向一个函数,通过指针变量来访问它指向的函数。

第7行:int (*p)( int,int ); 用来定义 p 是一个指向函数的指针变量,该函数有两个整形参数,函数值为整形。注意 *p 两侧的括号不可省略,表示 p 先与 * 结合,是指针变量,然后再与后面的 ( ) 结合,表示此指针变量指向函数,这个函数值 (即函数的返回值) 是整形的。如果写成 int *p ( int,int ) ,由于( )的优先级高于 *,它就成了声明一个函数P( 这个函数的返回值是指向整形变量的指针)。

赋值语句 p = max ; 作用是将函数 max 的入口地址赋给指针变量p。和数组名代表数组首元素地址类似,函数名代表该函数的入口地址。这时 p 就是指向函数 max 的指针变量,此时 p 和 max都指向函数开头,调用 *p 就是调用 max 函数。但是p作为指向函数的指针变量,它只能指向函数入口处而不可能指向函数中间的某一处指令处,因此不能用 *(p + 1)来表示指向下一条指令。

注意:

(1) 指向函数的指针变量的一般定义形式为:

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

这里数据类型就是函数返回值的类型

(2) int (* p) ( int,int ); 它只是定义一个指向函数的指针变量 p, 它不是固定指向哪一个函数的,而只是表示定义这样一个类型的变量,它是专门用来存放函数的入口地址的。在程序中把哪一函数(该函数的值应该是整形的,且有两个整形参数)的地址赋给它,他就指向哪一个函数。在一个函数中,一个函数指针变量可以先后指向同类型的不同函数。

(3) p = max; 在给函数指针变量赋值时,只需给出函数名而不必给出函数参数,因为是将函数的入口地址赋给 p ,而不涉及 实参和形参的结合问题,不能写成 p = max(a,b);

(4) c = (*p)(a,b) 在函数调用时,只需将( *p ) 代替函数名即可,后面实参依旧。

(5) 对于指向函数的指针变量,像 p++ ,p+n.....是无意义的。

(二) 用指向函数的指针作为函数参数

函数指针变量通常的用途之一就是把指针作为参数传递到其他函数。

函数的参数可以是变量、指向变量的指针变量、数组名、指向数组的指针变量,也可以是指向函数的指针也可以作为参数,以实现函数地址的传递,这样就能够在被调用的函数中使用实参函数。

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

{

int a,b,i,j;

a = (*x1)(i);  /* 调用 f1 函数 */

b = (*x2)(i)(j);/* 调用 f2 函数 */

}

如果实参为两个 函数名 f1 和 f2. 在函数首部定义x1、x2为函数指针变量,x1指向的函数有一个整形形参,x2指向的函数有两个形参。i 和 j 是函数f1 和 f2所要的参数。函数sub的形参 x1、x2(指针变量)在函数 sub 未被调用时并不占用内存单元,也不指向任何函数。在sub被调用时,把实参函数 f1 和 f2的入口地址传给形式指针变量 x1 和 x2.

既然在 sub 函数中要调用 f1 和 f2 函数,为什么不直接调用f1 和 f2而要用函数指针变量呢? 确实,如果只是用到f1 和 f2 函数,完全可以在sub函数中直接调用f1 和 f2,而不必设指针变量 x1 和 x2。 但是,如果在每次调用sub时,调用的函数不是固定的,下次是f3 和 f4,再是f5 和 f6...这时用指针变量就比较方便了。

(责任编辑:IT教学网)

更多

推荐网站策划文章