指向函数的指针
我们知道,一个指针变量可以指向整型变量,字符串,数组,也可以指向一个函数。一个函数在编译的时候被分配给一个入口地址,这个入口地址就称为函数的指针。可以用一个指针变量指向函数,然后通过指针变量调用这个函数。因为每个函数都占有一段内存单元,它们有一个起始地址。所以,我们可以用一个指针变量指向一个函数,通过指针变量来访问它指向的函数。
如:
#include "stdio.h"
main()
{
int max( int,int );
int (* p)();
int a,b,c;
p = max;
scanf( "%d,%d",&a,&b );
c = (* p)(a,b);
printf( "a = %d,b = %d,max = %d",a,b,c );
getch();
}
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
max( int x,int y )
{
int z;
if( x>y )z = x;
else z = y;
return(z);
}
我们看到,其中int (* p)();,首先,p和*结合,表明了p是一个指针变量,后面的括号表明指针是指向函数的。 int表明了此函数带回了整型的返回值。
赋值语句“p = max;”的作用是将函数max 的入口地址赋给指针变量p。和数组名代表数组起始地址一样,函数名代表该函数的入口地址。也就是说,p和max都指向函数的开头。值得注意的是,p是指向函数的指针变量,它只能指向函数的入口处,而不能指向函数中间的某一条指令处,因此不能用*(p+1)来表示下一个指令。
这里说明一下,
(1) 指向函数的指针变量的一般形式为:
数据类型 (* 指针变量名 )();
数据类型指的是函数返回值的类型。
(2) 函数的调用可以通过函数名调用,也可以通过函数指针调用。
(3) (*p)()表示定义一个指向函数的指针变量,它不固定指向哪一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存入函数的入口地址的。要调用的时候,程序把哪一个函数的地址赋给它,它就指向哪一个函数。也就是说,一个指针变量可以先后指向返回类型相同的不同函数。
(4) 在给函数指针变量赋值时,只需要给出函数名而不必给出参数。如:
P = max;
因为是将函数入口地址赋给p,而不牵涉到实参与形参的结合问题。不能写成“p = max(a,b)”形式。
(5) 在函数指针变量调用时,只需要将(*p)代替函数名即可。在(*p)后的括号中根据需要写上实参。如下面程序表示:“调用由p指向的函数,实参为a,b。得到的函数值赋给c。”
c = (* p)(a,b);
(6)对于指向函数的指针变量像p++,p—等运算是无意义的。
指针数组和指向指针的指针
一个数组,其元素均为指针类型数据,称为指针数组。也就是说,指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义形式为:
类型名 * 数组名[数组长度];
例如: int * p[22];
P先与[4]结合,形成p[22]的形式,就显然是数组形式,它有四个元素,然后再与p前面的“*”结合,“*”表示此数组是指针类型的,每个数组元素(相当于一个指针变量)都可以指向一个整型变量。
为什么要用到指针数组呢?它比较适合于用来指向若干个字符串,使字符串处理起来更加方便。也会节省更多的内存单元。
比如:分别定义一些字符串,然后用指针数组中的元素分别指向各字符串,如果想对字符串排序,不必屐字符串的位置,只需要改变指针数组中各元素的指向(即改变各元素的值,这些值是各字符串的首地址),这样,各字符串的长度可以不同,而且移动指针变量的值(地址)会比移动字符串所花的时间少得多。
比如:
#include
#include
void main()
{
void sort( char *name[],int n );
void print( char * name[],int n );
char * name[] = { "Follow me","BASIC","Great Wall","FORTRAN","Computer"};
int n = 5;
sort( name,n );
print( name,n );
getch();
}
void sort( char * name[],int n ) //对书排序
{
char * temp;
int i,j,k;
for( i = 0;i
{
k = i;
for( j = i+1;j
if(strcmp( name[k],name[j])>0)k = j;
if( k!=i )
{temp = name;name = name[k];name[k] = temp;}
}
}
void print( char * name[],int n ) //打印出来
{
int i = 0;
char * p;
p = name[0];
while(i
{
p = *(name+i++);
printf("%s\n",p);
}
}
指向指针的指针:
怎么样定义一个指向指针数据的指针变量呢?例如:
char **p;
因为*运算符的结合性是从右向左,所以它相当于:*(*p),显然,(*p)是指针变量的定义形式,如果没有前面的*,那就是定义了一个指向字符数据的指针变量,现在它前面又多了一个*,表示指针变量p指向一个字符指针变量的。(*p)是p指向的另一个指针变量。
例:
void main()
{
char * name[] = { "Follow me","BASIC","Great Wall","FORTRAN","Computer"};
char **p;
int i;
for( i = 0;i<5;i++)
{
p = name + i;
printf("%s\n",*p);
}
getch();
}
我们知道,在赋值的时候,p = name + i;是指p指向指针数组的第i行,加一个*后,*p是指向数组的第i行第0列的首地址,再加一个*后, **p指向第i行第0列地址中的内容。这个就比较好理解了。
文章评论(0条评论)
登录后参与讨论