函数指针包含函数在内存中的地址。第4章介绍了数组名实际上是数组中第一个元素的内存地址。同样,函数名实际上是执行函数任务的代码在内存中的开始地址。函数指针可以传人函数、从函数返回、存放在数组中和赋给其他的函数指针。
要演示如何使用函数指针,我们修改图5.15的冒泡排序程序,变成图5.26的程序。新程序包括main和函数bubble、swap、ascending和descending。函数bubbleSort接收ascending或descending函数的函数指针参数以及一个整型数组和数组长度。程序提示用户选择按升序或降序排序。如果用户输入1,则向函数bubble传递ascending函数的指针,使数组按升序排列。如果用户输入2,则向函数bubble传递descending函数的指针,使数组按降序排列。图5.27显示了示例的执行结果。
// Fig. 5.26: fig0526.cpp
// Multipurpose sorting program using function pointers
#include < iostream.h>
#include < iomanip.h>
void bubble( int [], const int, int (*)( int, int ) );
iht ascending( int, int );
int descending( int, int );
int main()
{
const int arraySize = 10;
int order,
counter,
a[ arraySize ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };
cout << "Enter 1 to sort in ascending order,\n"
<< "Enter 2 to sort descending order: ";
cin >> order;
cout << "\nData items in original order\n";
for ( counter = 0; counter < arraySize; counter++ )
cout << setw( 4 ) << a[ counter ];
if ( order == 1 ) {
bubble( a, arraySize, ascending );
cout << "\nData items in ascending order\n";
else {
bubble( a, arraySize, descending );
cout << "\nData items in descending order\n";
}
for ( counter = 0; coun er < arraySize; counter++ )
cout << setw( 4 )<< a[ counter ]
cout << endl;
return 0;
}
void bubble( int work[ ], const int size,
int (*compare)( int, int) )
{
void swap( int *, int* );
for ( int pass = 1; pass < size; pass++ )
for ( int count = 0; count < size - 1; count++ )
if( (*compare)( work[ count ], work[count + 1 ] ) )
swap( &work[ count ], &work[ count + 1 ] );
}
void swap( int *element1Ptr, int *element2Ptr )
{
int temp;
temp = *element1Ptr;
*element1Ptr = *element2Ptr;
*element2Ptr = temp;
return b < a; // swap if b is less than a
}
int descending( int a, int b )
{
return b > a; // swap if b is greater than a
}
图5.26 使用函数指针的多用途排序程序 输出结果:
Enter 1 to sort in ascending order,
Enter 2 to sort in descending order:1
Data items in original order
2 6 4 8 1O 12 89 68 45 37
Data items in ascending order
2 4 6 8 1O 12 37 45 68 89
Enter 1 to sort in ascendinq order,
En(e[ 2 to sort in descending order: 1
Data items in Oriqinal order
2 6 4 8 10 12 89 68 45 37
Dats items in ascendinQ order
89 68 45 37 12 10 9 6 4 2
图5.27 使用函数指针的多用途排序程序的执行结果
注意这里只包括类型,程序员可以加上名称.但参数名只用于程序中的说明,编译器将其忽略。
if语句中调用传人bubble的函数,如下所示:
if(( *compare )( work[ count ], work[ count + 1 ] ))
就像复引用变量指针可以访问变量值一样,复引用函数指针可以执行这个函数。
也可以不复引用指针而调用函数,如下所示:
if ( compare( work[ count ],work[ count + 1 ] ) )
直接用指针作为函数名。我们更愿意使用第一种通过指针调用函数的方法,因为它显式说明compare是函数指针,通过复引用指针而调用这个函数。第二种通过指针调用函数的方法使compare好像是个实际函数。程序用户可能搞糊涂,想看看compare函数的定义却怎么也找不到。
函数指针的一个用法是建立菜单驱动系统,提示用户从菜单选择一个选项(例如从1到5)。每个选项由不同函数提供服务,每个函数的指针存放在函数指针数组中。用户选项作为数组下标,数组中的指针用于调用这个函数。
图5.28的程序提供了声明和使用函数指针数组的一般例子。这些函数(function1、function2和function3)都定义成取整数参数并且不返回值。这些函数的指针存放在数组f中,声明如下:
void(*f[ 3 ] )(int) = { function1, function2,function3}
声明从最左边的括号读起,表示f是3个函数指针的数组,各取整数参数并返回void。数组用三个函数名(是指针)初始化。用户输入0到2的值时,用这些值作为函数指针数组的下标。函数调用如下所示:
(*f[ choice ])(choice);
调用时,f[choice]选择数组中choice位置的指针。复引用指针以调用函数,并将choice作为参数传人函数中。每个函数打印自己的参数值和函数名,表示正确调用了这个函数。练习中要开发一个菜单驱动系统。
// Fig. 5.28: fig05_28.cpp
// Demonstrating an array of pointers to functions
#include < iostream.h>
void functionl( int );
void function2( iht );
void function3( int );
int main()
{
void (* f[ 3 ] )( int ) = { function1, function2, function3 };
int choice;
cout << "Enter a number between 0 and 2, 3 to end: ";
cin >> choice;
while ( choice >= 0 && choice < 3 ) {
(* f[ choice ] )( choice );
cout << "Enter a number between 0 and 2, 3 to end: ";
cin >> choice;
}
cout << "Program execution completed." << endl;
return 0;
}
void function1( int a )
{
cout << "You entered " << a
<< "so function1 was called\n\n";
}
void function2( int b )
{
cout << "you entered " << b
<< "so function2 was called\n\n";
}
void function3( int c )
{
cout << "You entered "<< c
<< "so function3 was called\n\n";
}
输出结果:
Enter a number between 0 and 2, 3 to end: 0
You entered 0 so functionl was called
Enter a number between 0 and 2, 3 to end: 1
You entered 1 so function2 was called
Enter a number between 0 and 2, 3 to end: 2
You entered 2 so function3 was called
Enter a number between 0 and 2, 3 to end: 3
Program execution completed