C|函数指针和指针函数的联系与区别

函数指针和指针函数是两个很容易混淆的概念,可以这样增直观理解:函数指针,是一个指针,一个指向函数基地址的指针,由此指针可以进行函数调用;指针函数是一个函数,一个返回指针值的函数。

1 指针函数

返回指针类型的函数简称指针函数。如用“TypeName"表示某一个数据类型,则“TypeName *pValue”表示定义一个返回TypeName类型的指针函数和一个指针变量pValue,而且这个指针变量必须正确初始化。假设这个指针变量不是通过参数表传递,而是在函数中产生,则可以表示为:

TypeName * FunName(参数表)

{

TypeName * pValue;

//函数体包括正确初始化指针变量pValue

//函数体

return pValue;

}

一个简单实例的代码:

//返回结构及结构指针的例子

#include <stdlib.h>

#include <stdio.h>

#include <stdlib.h>

//定义一个全局的结构体

struct LIST{

int a,b;

}d[3],*p;

//返回结构值

struct LIST make1(int x, int y)

{

struct LIST temp;

temp.a=x;

temp.b=y;

return temp;

}

//返回结构指针

struct LIST *make2(int x, int y)

{

struct LIST *temp;

temp=(struct LIST *)malloc(sizeof(struct LIST));

temp->a=x;

temp->b=y;

return temp;

}

int main()

{

int i;

d[0]=make1(215, 512);

p=make2(815,518);

d[1]=*p;

d[2]=d[0]; //结构可以整体赋值

for(i=0;i<3;i++)

printf("d[%d].a=%d,d[%d].b=%d\n", i,d[i].a,i,d[i].b);

system("pause");

return 0;

}

运行结果:

d[0].a=215,d[0].b=512

d[1].a=815,d[1].b=518

d[2].a=215,d[2].b=512

假设函数的参数表中有“TypeN *”类型的参数value,则可以表示为如下形式:

TypeName FunName(TypeName *value, 其他参数表)

{

//函数体

return value;

}

一个简单实例:

#include <stdlib.h>

//将结构指针作为返回值的例子。

#include <stdio.h>

struct LIST{

int a,b;

}d[3], b, *p;

struct LIST make(int , int); //返回结构的函数

struct LIST *change (struct LIST*, struct LIST [ ]); //返回结构的指针

void disp(struct LIST [ ]); //使用结构参数

int main()

{

d[0]=make(215,512);

d[1]=make(815,518);

d[2]=make(618,816);

p=&b; //初始化指针p

p=change(p,d); //表达式调用

disp(d);

printf("b.a=%d\t\tb.b=%d\n", b.a, b.b);

printf("p->a=%d\t\tp->b=%d\n", p->a, p->b);

system("pause");

return 0;

}

struct LIST make(int x, int y)

{

struct LIST temp;

temp.a=x;

temp.b=y;

return temp;

}

void disp(struct LIST d[ ])

{

int i;

for(i=0;i<3;i++)

printf("d[%d].a=%d\td[%d].b=%d\n", i,d[i].a,i,d[i].b);

}

//将传递的一个结构参数作为函数的返回值

struct LIST* change(struct LIST *b,struct LIST d[ ])

{

b->a=d[0].a;

b->b=d[2].b;

return b;

}

运行结果:

d[0].a=215 d[0].b=512

d[1].a=815 d[1].b=518

d[2].a=618 d[2].b=816

b.a=215 b.b=816

p->a=215 p->b=816

2 函数指针

指针变量可以指向整型变量、字符变量及字符串、浮点变量和数组。其实,指针变量也可以指向一个函数。因为尽管函数本身不是一个变量,但它在内存中仍然有其物理地址。在编译过程中,原代码被转换成目标代码,函数的入口地址也同时确立,所以就能够将函数的入口地址赋给指针变量。程序调用函数,也就是机器语言的"CALL"指向了这个入口点。因为指向函数的指针实际上包含了函数的入口点的内存地址,所以赋给指针变量的地址就是函数的入口地址,从而该指针就可以用来代替函数名。这一特性也使得函数可以作为实参传递给其他函数。

通过函数指针变量可以完成对函数的调用。其原理是通过把一个函数(函数名)赋给一个函数指针变量,然后又通过该函数指针变量来完成对函数的引用。

一个小实例:

使用函数指针输出多项式x³-4x+6和x²-3x在区间[-1,1]增长步长为0.1时的所有结果。

#include <stdlib.h>

#include <stdio.h>

double f1(double x);

double f2(double x);

//double (*p)(double);

#define STEP 0.1

int main( )

{

int i;

double x;

double (*p)(double); //double (*p)(double)与double (*p)( )等效

for ( i=0; i<2; i++)

{

printf("第%d个方程:\n",i+1);

if ( i==0)

p = f1;

//p = f1(x);

else

p = f2;

for( x = -1; x <= 1; x += STEP)

printf("%f\t%f\n", x, (*p)(x));

}

system("pause");

return 0;

}

//函数 f1

double f1(double x)

{ return ( x*x*x - 5*x -4);}

// 函数f2

double f2(double x)

{return( x*x - 3*x +2);}

运行结果:

第1个方程:

-1.000000 0.000000

-0.900000 -0.229000

-0.800000 -0.512000

-0.700000 -0.843000

-0.600000 -1.216000

-0.500000 -1.625000

-0.400000 -2.064000

-0.300000 -2.527000

-0.200000 -3.008000

-0.100000 -3.501000

-0.000000 -4.000000

0.100000 -4.499000

0.200000 -4.992000

0.300000 -5.473000

0.400000 -5.936000

0.500000 -6.375000

0.600000 -6.784000

0.700000 -7.157000

0.800000 -7.488000

0.900000 -7.771000

1.000000 -8.000000

第2个方程:

-1.000000 6.000000

-0.900000 5.510000

-0.800000 5.040000

-0.700000 4.590000

-0.600000 4.160000

-0.500000 3.750000

-0.400000 3.360000

-0.300000 2.990000

-0.200000 2.640000

-0.100000 2.310000

-0.000000 2.000000

0.100000 1.710000

0.200000 1.440000

0.300000 1.190000

0.400000 0.960000

0.500000 0.750000

0.600000 0.560000

0.700000 0.390000

0.800000 0.240000

0.900000 0.110000

1.000000 0.000000

语句double (*p)( );仅仅说明p是一个指向函数的指针变量,此函数带回实型的返回值。但这并不是固定指向哪一个函数的,而只是表示定义了这样一个类型的变量,专门用来存储函数的入口地址。在程序中把哪一个函数的地址赋给它,它就指向哪一个函数。

函数指针声明相对于函数声明,多了“(*)”符号,即多了一对圆括号和一个星号。

如果再增加一对中括号和一个数字,如double (*p[3])( );则成了一个函数指针数组变量,也就是拥有了三个函数指针,分别是p[0]、p[1]、p[2]。

函数指针还可以用作函数参数或函数返回值,具体内容请见:C|函数指针做为函数参数或函数返回值

-End-

举报
评论 0