再上一篇:8.2 指针与数组
上一篇:8.3 指针数组与指向指针的指针变量
主页
下一篇:8.5 new与delete
再下一篇:8.6 引用和其它类型的指针
文章列表

8.4 指针与函数

《VC++程序设计基础》,讲述C++语言的语法和标准库,以及Visual C++ 函数库和MFC类库的使用,并附相关代码示例。

8.4.1 指针作为函数的参数

将指针作为函数的参数时,传递给函数的是某一个变量的地址,这种情况称为地址传递。当函数的参数为指针时,可将指针值和指针所指向的数据作为函数的输入参数,即在函数体内可使用指针值和指针所指向的数据值。也可将指针所指向的数据作为函数的输出参数,即在函数体内改变了形参指针所指向的数据值,调用函数后,实参指针所指向的数据也随之改变。换言之,函数除了用return返回一个值外,还可以通过指针类型的参数带回一个或多个值。

例8.12 实现二个数据的交换。

#include

void swap( int *p1 , int *p2)

{

int temp ;

temp = *p1;

*p1 = *p2;

*p2 = temp;

}

void main(void)

{

int a , b ;

cout << "Input a and b: ";

cin >> a >> b;

cout << "\na = " << a << " , b = "<< b << "\n";

swap(&a, &b); //A

cout << "a = " << a << " , b = "<< b << "\n"; //B

}

执行程序时,输入100和200,程序输出:

a = 100 , b = 200

a = 200 , b = 100

swap( )函数实现交换二个变量的值。它的二个形参均为指针变量。当输入a、b的值为100和200后,执行到A行调用函数swap( ),当进入该函数,还没有执行swap( )函数体时,p1指向a,p2指向b,如图8.8(a)所示。接着执行swap( )的函数体,使*p1和*p2的值互换,也就是使a和b的值互换。如图8.8(b)所示。函数调用结束后,系统收回p1和p2所占的内存空间,变量p1和p2不再存在,这时变量a,b的取值如图8.8(c)所示。B行输出的a和b的值已是交换之后的值。

p1 a p1 a a

100 200 200

p2 b p2 b b

200 100 100

(a) (b) (c)

图8.8

如果将上面的swap( )函数的二个指针参数改为二个整型变量,并把swap( )函数改写出为:

void swap1(int x,int y)

{ int t;

t=x;x=y;y=t;

}

将主函数中的“swap(&a,&b);”改为”swap1(a,b);”,是否会实现二数的交换呢?如图8.9所示,在函数调用开始前,将a的值传给x,将b 的值传给y,见图(a)。执行完swap1( )的函数体后,x与y值已交换,但a和b的值仍是原来的值。所以函数swap1( )不能实现二个数的交换,这就是我们在5.2.3节所介绍的函数参数的值传递方式。

a b a b

100 200 100 200

x y x y

100 200 200 100

(a) (b)

图8.9

由于数组名的值为数组的起始地址,当把数组名作为函数的参数时,其作用与指针相同。数组或指针作为函数的参数的情况可以有四种: 第一种是函数的形参为数组,调用函数时的实参数组名;第二种是形参为指针型变量,而实参用数组名;第三种是形参为数组名,而实参为指针;第四种是形参和实参都用指针型变量。这四种形式的效果完全一样。

例8.13 数组或指针作为函数的参数,实现整型数组的排序。

#include

void sort1( int *p, int n)

{

int i, j, temp ;

for ( i = 0; i < n-1 ; i ++)

for ( j = i + 1 ; j < n ; j ++)

if ( *(p+i ) > *(p+j) ){

temp = *(p+i);

*(p+i) = *(p+j);

*(p+j) = temp;

}

}

void sort2( int *p, int n)

{

int i, j, temp ;

for ( i = 0; i < n-1 ; i ++)

for ( j = i + 1 ; j < n ; j ++)

if ( p[i] > p[j] ){

temp = p[i];

p[i] = p[j];

p[j] = temp;

}

}

void sort3( int b[], int n)

{

int i, j, temp ;

for ( i = 0; i < n-1 ; i ++)

for ( j = i + 1 ; j < n ; j ++)

if ( b[i] > b[j] ){

temp = b[i];

b[i] = b[j];

b[j] = temp;

}

}

void main(void)

{

int a[6] ={4,67,3,45,34,78}, *point ;

int b[6] ={4,67,3,45,34,78};

int c[6] ={4,67,3,45,34,78};

point = c;

sort1(a , 6 );

sort2 (b, 6 );

sort3 (point,6);

for ( point=a; point < a+6 ;) cout<< *point++ << "\t";

cout<<"\n";

for ( point=b; point < b+6 ;) cout<< *point++ << "\t";

cout<<"\n";

for ( point=c; point < c+6 ;) cout<< *point++ << "\t";

cout<<"\n";

}

执行程序后的输出为:

3 4 34 45 67 78

3 4 34 45 67 78

3 4 34 45 67 78

我们在程序中定义了三个函数sort1( )、sort2( )和 sort3( )。它们的功能完全相同。函数 sort1( )的第一个形参是指向整数的指针变量,调用该函数时的第一个实参,可以是指针也可以是数组名。由于数组名和指针都是传递地址,所以二者的作用完全相同,可以互换。

多维数组作为函数参数的方法有三种:第一种是函数的形参定义为多维数组,调用函数时的实参为多维数组名。第二种方法是把多维数组作为一维数组来处理,函数的形参定义为一维数组或一级指针变量,另一个参数指明数组的元素个数;对应的实参给出数组的起始地址。第三种方法是用指向一维数组的指针变量作为函数的参数。

例8.14 设计一个通用的矩阵相乘的函数。

分析:设a为m×n阶的矩阵,b为n×p阶的矩阵,a矩阵乘以b矩阵得到c矩阵。c为m×p阶的矩阵。实现通用的矩阵相乘的函数,要求m、n和p均是一个可变的正整数。唯一的办法是将二维数组作为一维数组来处理。根据矩阵相乘的公式:

c =k=n−1a ×b

ij ∑ ik kj

k=0

我们可编写矩阵相乘的函数如下:

void matrixmul(float *pa,float *pb,float *pc,int m,int n,int p){

int i,j,k;

float t;

for ( i=0;i

for(j=0;j

t=0; //A

for(k=0;k

t += *(pa+i*n+k) * *(pb+k*p+j);

*(pc+i*p+j) = t; //C

}

}

程序中的B行实现求出C矩阵中第i行第j列的元素。变量t用来存放求一个元素时的累加和,每求C矩阵中的一个元素前,先要将t置为0。所以A行是不可缺少的。C行将t中已求出的元素值赋给C矩阵中第i行第j列元素。指针变量pa中存放了矩阵a的起始地址,矩阵a的每一行有n个元素,所以矩阵a的第i行的起始地址为:

pa+i*n

矩阵a的第i行第k列的地址为:

pa+i*n+k

计算矩阵b和c中某一个元素地址的方法完全类同。

例8.15 求二维数组的平均值。

#include

float average1(float * p, int n)

{

float sum = 0 ;

int i;

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

sum += *p++;

return sum/n;

}

float average2(float p[][4], int n)

{

float sum = 0 ;

int i, j;

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

for ( j = 0 ; j < 4 ; j++)

sum += p[i][j];

return sum/(n*4);

}

float average3(float (*p)[4], int n)

{

float sum = 0 ;

int i, j;

for ( i = 0; i < n ; i ++){

for ( j = 0 ; j < 4 ; j++)

sum += (*p)[j];

p++;

}

return sum/(n*4);

}

void main(void)

{

float score[3][4] = {{65,67,70 ,60},{80,87,90,81},{90,99,100,98}};

cout<<"平均值="<

cout<<"平均值="<

cout<<"平均值="<

}

执行程序后的输出为:

平均值=82.25

平均值=82.25

平均值=82.25

从输出结果可以看出,三个函数average1( )、average2( ) 和average3( )的作用是相同的,都是求二维数组的平均值。average1( )的第一个参数是一级指针,它把二维数组作为一维数组来处理,第二个参数是二维数组中的元素个数。其对应的第一个实参应是第0行第0列元素的地址,即*score。average2( )的第一个形参是二维数组,第二个形参为二维数组的行数。对应的第一个实参为二维数组名 score。average3( )的第一个形参为指向一维数组的指针变量,第二个形参为二维数组的行数,对应的第一个实参为指向第0行的列地址,即&score[0]。*例8.16 实现C语言的Printf()库函数,为了简化程序设计,我们适当地简化了Printf()函数有关格式符方面的功能。

#include

#include

void main(void )

{

int Print(char *...);

char *str ="C++ language";

float f=34.5;

Print("%s,%d,%c,%%,%f\n",str,25,'c',f); //A}

int Print(char *format...)

{

va_list ap;

char ch;

int i=0;

va_start(ap,format);

while ((ch=*format++ )!='\0') { //Bi++;

if(ch!='%') cout << ch;

else

switch ( ch=*format++) {

case '%': cout << '%';

break;

case 's': {

char *p = va_arg(ap,char *);

cout << p;

}

break;

case 'd': {

int p = va_arg(ap,int);

cout << p;

}

break;

case 'f': {

double p = va_arg(ap,double);

cout << p;

}

break;

case 'c': {

char p = va_arg(ap,char);

cout << p;

}

break;

}

}

va_end(ap);

return i;

}

执行该程序后的输出为:

C++ language,25,c,%,34.5

函数的第一个参数是一个字符串,并把它称为格式串。在该字符串中,百分号“%”与紧跟其后的一个格式说明字符一起指出与其对应参数的数据类型。本例中,格式说明字符只考虑了五种:s对应一个字符串,d对应一个整型数据,f对应一个实型数据,c对应一个字符型数据,%则表示要输出一个%。调用函数时,给出的每一个缺省的参数,在格式串中都有一个对应的%后跟一个格式说明字符。如A行中函数调用:

Print("%s,%d,%c,%%,%f\n",str,25,'c',f);

%s指明将第二个参数str所指向字符串输出,%d指明第三个参数25按整数输出,%c把第四个参数'c'按字符数据输出,%%表示输出一个%,而%f把第五个参数f的值按实数输出。

Print( )函数体中的B行,while()循环语句通过字符指针format逐一地取出格式串中的每一个字符;若不是%,则输出该字符;否则根据%后面的格式字符,依次对其后的可变参数按指定的格式输出,这部分是通过开关语句(switch())来实现的。

va_start() ,va_arg() 和va_end()的功能和作用参看5.6节。

8.4.2 函数返回值为指针的函数

任一函数,在其函数体内用语句“return”可以不返回值,也可以返回一个值,并且至多只能返回一个值。当希望函数体内计算的多个值带回给调用者时,必须通过函数的参数来实现。当然函数也可以返回一个指针,该指针可以指向一个已定义的任一类型的数据。定义函数返回指针值的格式是:

<类型标识符> * <函数名>(<形式参数表>){ <函数体>}

其中“*”说明函数返回一个指针,该指针所指向的数据的类型由“类型标识符”指定。如,定义函数:

float * f1(...)

{

......

}

说明函数f1()要返回一个指向实数的指针。

例8.17 将输入的一个字符串按逆序输出。

分析:设输入的字符串为:“ABCDEFG”。建立二个字符型指针变量p1和p2,开始使p1指向字符串的第0个字符,p2指向字符串中的最后一个字符。第一步将p1和p2所指向的字符对换(第一次是将A与G 交换)。第二步,使p1指向前一个字符,p2指向后一个字符,即执行p1++,p2--。第三步,若p1的值小于p2,则重复执行第一步;否则表明字符串的字符已逆序,结束交换。

#include

char * flip(char * ptr)

{

char *p1, *p2, temp;

p1 = p2 = ptr; //A

while ( *p2 ++) ; //B

p2 -= 2; //C

while ( p1 < p2 ) { //D

temp = *p2; *p2 -- = *p1;

*p1 ++ = temp;

}

return ptr;

}

void main(void)

{

char str[200];

cout<<"输入一个字符串:";

cin.getline(str,200);

cout << str << "\n";

cout << flip(str) << '\n';

}

执行程序时,若输入字符串“Computer Department.”,输出的结果为:.tnemtrapeD retupmoC

程序中的A行,首先使p1和p2指向字符串的第0个字符位置。当B行的循环语句执行完后,p2已指向字符串结束字符后面的一个字符位置。要使p2指向字符串的最后一个字符的位置,应使p2回退二个字符位置,C行实现这一目的。D行中的循环体,一方面实现p1所指向的字符与p2指向字符交换,另一方面完成p1++和p2--,使p1指向前一个字符,p2指向后一个字符。

也可以用递归函数实现输入字符串的逆序输出。程序为:

#include

void p(char s[],int i)

{

if(s[i]!=0)p(s,i+1);

cout<

}

void main(void)

{

char str[200];

cout<<"输入一个字符串:";

cin.getline(str,200);

cout << str << "\n";

p(str,0);

cout <<'\n';

}

执行上面的程序时,若输入字符串“Computer Department.”,输出的结果为:.tnemtrapeD retupmoC

读者自行分析上例中递归函数的实现过程。这个程序比前面的程序要简短一些。

例8.18 输入二个字符串,把这二个字符串拼成一个新的字符串,然后输出这三个字符串,实现字符拷贝和拼接的函数自己设计。

#include

char * copy( char *to, char *from)

{ char *p=to;

while (*to++ = *from++);

return p;

}

char * stringcat( char *to, char *from)

{

char *p=to;

while (*to++);

to--;

while(*to++=*from++);

return p;

}

void main(void)

{

char s1[100],s2[100],s3[200];

cout<<"输入第一个字符串:";

cin.getline(s1,100);

cout<<"输入第二个字符串:";

cin.getline(s2,100);

copy(s3,s1);

cout <<"s1=" << s1<<"\n";

cout <<"s2=" << s2<<"\n";

cout<<"拼接后的字符串为:"<

}

执行程序时,输入字符串“C++ Program”和“ming Score.”,则输出的结果为:

s1=C++ Program

s2=ming Score.

拼接后的字符串为:C++ Programming Score.

函数copy( )实现字符串的拷贝,而函数stringcat( )实现二个字符串的拼接。读者亦可自行分析二个函数的实现过程。

*例8.19 对函数返回的指针所指向的内存单元赋值。

#include

int i;

int * f( )

{ return &i;}

void main(void )

{

*f() = 200; //A

cout<

*f( ) = 400;

cout<

}

执行程序后的输出为:

200 400

表达式“*f() = 200”中,函数调用运算符的优先级最高,而赋值运算符的优先最低。执行这表达式的顺序为:先调用函数f(),返回一个指向全局变量i的指针,然后将200赋给该指针所指向的变量i。必须说明,本例没有实用意义,只是说明在C++中允许向函数返回的指针所指向的内存单元赋值。在某些应用中,使用这种赋值方式,可简化程序。

注意,函数只能返回全局变量或静态变量的指针,不能返回局部变量的指针。如以下函数:

int * f1( )

{ int i;

......

return &i;

}

因执行return后,系统已收回为变量i分配的存储空间,即函数执行完后,变量i已不存在,所以不能返回变量i的指针。

8.4.3 带参数的main()函数及命令行参数

在前面介绍的 main()函数中,都没有使用参数。实际上,C++语言中为了增加程序的灵活性和可适应性, 允许main()函数带有二个或三个形参, 其函数的一般原型为:

int main(int argc , char *argv[],char *evn[]);

或者

int main(int argc , char **argv, char **evn);

或者

int main(int argc , char *argv[]);

其中第一个参数为实际命令行所带的参数个数;第二个参数是一个指向字符串的指针数组,它的每一个元素依次指向该命令的一个参数;而第三个参数也是一个指向字符串的指针变量,它的每一个元素指向当前运行系统的环境变量。

例8.20 显示命令行参数。

#include

//ECHO.CPP

main(int argc, char *argv[])

{

for(int i=0;i< argc ;i++)

cout << argv[i] << '\t';

cout<<'\n';

}

首先将这源程序存放到文件ECHO.CPP中,经编译和连接后,产生一个可执行文件ECHO.EXE。在DOS的环境下,打入命令:

ECHO Apple Orange China.

则输出:

C:\T\ECHO.EXE Apple Orange China.

argv[0] C:\T\ECHO.EXE

argv[1]

argv[2] Apple

argv[3]

Orange

China.

图 8.10 argv的指向

打入命令中的“ECHO”,“Apple”,“Orange”,“China.”作为 main( )函数的实参,因有四个参数,传递给argc的值为4,在开始执行main( )函数时,系统使argv中每一个元素依次指向这四个实参,如图8.10所示。主函数中的循环语句依次输出argv[i]所指向的字符串。

例8.21 输出环境变量。

//EXE8_22.cpp

#include

void main(int argc, char *argv[],char *eve[])

{

int i;

for(i=0; eve[i];i++)

cout << "eve["<

}

执行程序时,输出:

eve[0]=TMP=C:\WINDOWS\TEMP

eve[1]=TEMP=C:\WINDOWS\TEMP

eve[2]=PROMPT=$p$g

eve[3]=winbootdir=C:\WINDOWS

eve[4]=COMSPEC=C:\WINDOWS\COMMAND.COM

eve[5]=PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;C:\UCDOS

eve[6]=windir=C:\WINDOWS

eve[7]=BLASTER=A220 I5 D1 T4

eve[8]=CMDLINE=a

环境变量的多少及其内容随不同的操作系统环境而变化。上面的程序在不同的系统上执行时,输出的结果是不同的。在一些特殊的应用场合,C++程序要用到操作系统提供的环境变量。有关环境变量的讨论已超出本书的范围,不作进一步讨论了。

C++提供的main()函数可有如下四种格式,其函数的原型为:

main(void ) ; //不带任何参数

main(int );//带一个参数,所带的参数是没有意义的,几乎不用该格式

main(int ,char **); //带二个命令行参数,经常这样使用

main(int , char **,char **) // 带三个参数,特殊场合使用

如果带有参数,各参数的顺序和类型必须符合以上的格式。通常其参数用argc,argv,eve分别表示参数的个数,指向参数的指针数组和指向环境变量的指针数组。由于这三个变量属于main( )函数的形参,当然也可以使用其它的变量名。

当没定义 main()函数的返回值类型时,系统约定其返回值的类型为 int型,且只能返回一个整数或没有返回值。当没有返回值时,必须将它说明为void类型。

8.4.4 指向函数的指针

一个函数的入口地址称为函数的指针,一个指针变量的值为一个函数的入口地址时,称其为指向函数的指针变量。

对指向函数的指针变量,说明以下几点:

1、定义指向函数的指针变量的格式为:

<类型标识符> (*<变量名>) (《参数表》);

其中类型标识符是函数返回值的类型,《参数表》可以只有参数的类型说明。因括号运算优先,“(*<变量名>)”表明是一个指针变量,而“(《参数表》)”表示是一个函数。所以,二者相结合,表示这变量名是一个指向函数的指针变量。如:

float (*fp1)( void);

float * (*fp2)( float *, float **);

2、函数名表示该函数的入口地址(在内存中的起始地址),可以将函数名赋给指向函数的指针变量。在不作强制类型转换时,只能将与指向函数的指针变量具有相同返回值和相同的参数表的函数名赋给指向函数的指针变量。换言之,指向函数的指针变量只能指向与该指针变量具有相同返回值类型和相同参数(个数及顺序一致)的任一函数。如:

float f(float);

float * f2(float *,float **);

fp1=f; //是不可以的

fp2= f2; //可以

3、指向函数的指针变量除了可以进行赋值操作和关系运算外,通常进行其它操作是没有意义的。

4、对指向函数的指针变量进行赋值后,可用这指针变量来调用函数。调用函数格式为:

(*<指针变量名>) (<实参表>)

<指针变量名> (<实参表>)

5、指向函数的指针变量主要用作函数的参数。

例8.22 完成二个操作数的加、减、乘、除四则运算。

#include

#include

float add(float x,float y)

{

cout<

return x-y;

}

float mul(float x,float y)

{

cout<

return x/y;

}

void main( void )

{

float a,b;

char c;

float (*p)(float ,float);

cout<<"输入数据格式:操作数1 运算符 操作数2\n";

cin >>a>>c>>b;

switch(c){ //A

case '+': p=add; break;

case '-': p=sub; break;

case '*': p=mul; break;

case '/': p=dev; break;

default: cout<<"输入数据的格式不对!\n"; exit(1);

}

cout<

}

执行程序时,若输入“45+55”,则输出:

45 + 55 = 100

A行的开关语句,根据输入的运算符,将完成不同运算的函数指针赋给指针变量p。B行用指针变量调用函数。

例 8.23 已知一个一维数组的各个元素值,分别求出:数组的各个元素之和,最大元素值,下标为奇数的元素之和,各元素的平均值。

#include

#include

float sum(float *p, int n)

{

float sum =0;

for(int i=0;i

return sum;

}

float max(float *p,int n)

{

float m=*p++;

for(int i=1;i

if(*p>m) m=*p;

p++;

}

return m;

}

float oddsum(float *p,int n)

{

float sum =0;

for(int i=1;i

sum += *p++;

p++;

}

return sum;

}

float ave(float *p, int n )

{

return sum(p,n)/n;

}

void process(float *p, int n, float (*fp)(float *,int))

{

cout<

}

void main( void )

{

float x[] = {2.3,4.5,7.8 ,345.6,56.9,77,3.34,7.87,200};

int n = sizeof(x)/sizeof(float);

cout<

process(x,n,sum);

cout<

process(x,n,max);

cout<<"奇数下标元素之和: ";

process(x,n,oddsum);

cout<

process(x,n,ave);

}

执行程序后的输出为:

9个元素之和是: 705.31

9个元素中的最大值是: 345.6

奇数下标元素之和: 70.34

9个元素的平均值是: 78.3678

程序中的函数sum( ),max( ),oddsum( ),ave( )分别求出数组各元素之和、最大元素值、下标为奇数的元素之和、各元素的平均值。函数 process( )的功能是调用一个函数并输出该函数的返回值,它有三个参数,第一个是指向数组的指针,第二个是数组中元素的个数,第三个是指向函数的指针。把指向函数的指针变量作为函数的形参时,其说明形式与定义指向函数的指针变量完全类同。如本例:

void process(float *p, int n, float (*fp)(float *,int));即说明函数的类型,指针所指向函数的各个参数的类型。第一次调用process( )时的实参为x,n,sum。sum是函数名,它的值为函数的入口地址,即把函数指针传给形参fp。此时,A行中的表达式“fp(p,n)”,等同于“sum(p,n)”,即调用了函数sum(p,n),并输出该函数的返回值(所有元素之和)。第二次调用process( )时的实参为x,n, max。将函数max的入口地址传给形参fp。此时,A行中的表达式“fp(p,n)”,等同于“max (p,n)”,即调用了函数max (p,n),并输出该函数的返回值(最大元素值)。第三、第四次调用process( )的情况依此类推。

把指向函数的指针变量作为函数的参数,能在调用一个相同名的函数过程中执行功能不同的函数(由对应的实参确定),这大大增加了程序设计的灵活性。本例中,四次调用 process( ),在执行该函数体时,调用了四个不同的函数:sum( )、max( )、oddsum( )、ave ( )。

例8.24 用梯形法求定积分的近似值,求下列三个定积分:

4 2

area1=∫(1+x )dx

2

2.5 x

area2= ∫ dx

1 2

(1+x )

3 2

area3= x+x dx

∫ 2

11+sinx+x

用梯形法求定积分的通用公式为:

f(a)+ f(b) i=n−1

area=[ + ∑ f(a+i×h)]×h

2 i=1

其中,a和b分别为积分的下限和上限,n为积分区间的分隔数; h= ( b-a) /n,h为积分步长;f(x)为被积函数。为此,先编写一个求定积分的通用函数jifen( ),它需要四个形参:指向被积函数的指针,积分的下限,积分的上限,积分区间的分隔数。程序为:

#include

#include

float f1(float x)

{

return (x+x*x)/(1+sin(x)+x*x);

}

float f2(float x)

{

return (1+x*x);

}

float f3(float x)

{

return x/(1+x*x);

}

float jifen ( float (*f)(float), float a, float b,int n )

{

float y,h;

int i;

y=(f(a)+f(b))/2;

h= (b-a)/n;

for(i=1;i< n;i++) y += f(a+i*h);

return (y*h);

}

main()

{

cout<<"第一个积分值:"<

cout<<"第二个积分值:"<

cout<<"第三个积分值:"<

}

执行程序是的输出为:

第一个积分值:1.98498

第二个积分值:20.6667

第三个积分值:0.643927

数组是同一类型数据的集合,当然其数据类型可以是指向函数的指针,由函数指针所组成的数组称为函数指针数组。其一维数组的定义形式为:

《存储类型》 类型 (*数组名[数组大小])(《参数表》);

如:

float (*funarr[20])(float *,int );

括号内的部分 “*funarr[20]” 优 先,说明funarr是一个指针数组,“(float*,int )”指明是函数,二者结合后,说明funarr是一个函数指针数组,函数的返回值为实型。当然,这种数组也可以是多维的,但用得较多的是一维的函数指针数组。

*例8.25 编写一个简单的计算器程序。

用命令行带入三个参数:第一操作数,运算符和第二操作数。程序为:#include

#include

int add(int x,int y)

{

cout << x<<"+"< example: \n";

cout << "EX 34 * 25 \n";

exit(1);

}

char op=argv[2][0];

switch (op) { //B

case '+': i=0;break;

case '-': i=1;break;

case '*': i=2;break;

case '/': i=3;break;

default : cout << "Operater is error!\n";

exit(1);

}

OutResult(atoi(argv[1]),atoi(argv[3]),fun[i]); //C

}

程序中的A行定义了一个函数指针数组fun,它的四个元素分别指向实现加、减、乘、除的四个函数。B行根据运算符确定数组fun的下标值,C行把函数指针数组fun中元素作为实参,以实现由运算符确定的运算。