ITEEDU

5.11 函数指针

函数指针包含函数在内存中的地址。第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
图5.28 声明和使用函数的指针数组