C++学习之:函数指针(指向函数的指针)

前两天在看FFMPEG源码,里边很多实用函数指针的地方,自己就顺便去看了看函数指针。记录备用。

函数的指针

函数指针:指向函数代码的起始地址

定义

返回类型  (*指针变量名)( ) ;  
//如:
int (*p)(int a,int b);//定义函数指针

使用 :

//定义+赋值
int (*p)(int a,int b);
int isdigit(int a,int b)
{
...
}
p=isdigit;
//引用
a=isdigit(n,k);
//等同于
a=p(n,k);

用途

  • 菜单选择的实现
  • 作为函数的参数

例子一:菜单的实现

在一个工资管理系统中有如下功能:
1。添加员工;2。删除员工;3。修改员工信息;4。打印工资单;5。打印汇总表;6。退出。

在设计中,一般把每个功能设计成一个函数。如添加员工的函数为add,删除员工的函数为delete,修改员工信息的函数为modify,打印工资单的函数为printSalary,打印汇总表函数为printReport。主程序是一个循环,显示所有功能和它的编号,请用户输入编号,根据编号调用相应的函数。
1.不使用函数指针时,代码实现:

int main()
{ int select;
  while(1) {     
   cout << "1--add \n";
   cout << "2--delete\n";
   cout << "3--modify\n";
   cout << "4--print salary\n";
   cout << "5--print report\n";
   cout << "0--quit\n";
   cin >> select;

  switch(select) 
  {
  case 0: return 0;
  case 1: add(); break;
  case 2: erase(); break;
  case 3: modify(); break;
  case 4: printSalary(); break;
  case 5: printReport(); break;
  default: cout << "input error\n";
  }
 }
}

这样写的缺点是代码太过冗长,如果有100个函数功能,那就要写很长了。
2.使用函数指针,代码实现:

int main()
{ int select;
  void (*func[6])() = {NULL, add, erase, modify, printSalary, printReport};//定义函数指针的数组,注意写法!
  while(1) { 
  cout << "1--add \n";
  cout << "2--delete\n";
  cout << "3--modify\n";
  cout << "4--print salary\n";
  cout << "5--print report\n";
  cout << "0--quit\n";
  cin >> select;
  if (select == 0) return 0;
  if (select > 5) 
  cout << "input error\n"; 
  else func[select]();
    }
}

这样写看着清爽很多,注意void (*func[6])() = {NULL, add, erase, modify, printSalary, printReport};是定义了一个函数指针的数组

例子二:作为函数参数

设计一个通用的冒泡排序函数,可以排序任何类型的数据 。
如何表示要排序的数据:将快速排序设计成一个函数模板,将待排序的数据类型设计成模板参数
不同类型的数据有不同的比较方式:向排序函数传递一个比较函数来解决。

先回顾冒泡法

void sort(int a[], int size)
{   bool flag;//用于冒泡中提前结束冒泡
    int i, j;
    for (i = 1; i < size; ++i) {
        flag = false;
        for (j = 0; j <size - i; ++j)   
        if (a[j+1] < a[j])  {   
           int tmp = a[j];
           a[j] = a[j+1];
           a[j+1] = tmp;
           flag = true;
        }
           if (!flag) break;    
    }
}

这样写缺点是只能用于整型数的排序,现在写一个能适用于任意类型不符合排序规则的。把排序规则写在函数里边

template <class T>//使用函数模板
void sort(T a[], int size, bool (*f)(T,T))
bool flag;//用于冒泡中提前结束冒泡
int i, j;
for (i = 1; i < size; ++i) {
        flag = false;
        for (j = 0; j <size - i; ++j)   
        if (f(a[j+1],a[j]))  //用函数f(T,T)来表示排序规则
        {   
           int tmp = a[j];
           a[j] = a[j+1];
           a[j+1] = tmp;
           flag = true;
        }
           if (!flag) break;    
    }
}
//排序规则
bool decreaseInt(int x, int y) {return y<x;}
bool increaseString(char *x, char *y)  {return strcmp(x,y)<0;}
int main()
{
       int a[] = {3,1,4,2,5,8,6,7,0,9}, i;
       char *b[]= {"aaa","bbb","fff","ttt","hhh","ddd","ggg","www","rrr","vvv"};
 
       sort(a, 10,  decreaseInt);
       for ( i = 0; i < 10; ++i) cout << a[i] << "\t";
       cout << endl;  
 
            sort(b, 10, increaseString );
       for (i = 0; i < 10; ++i) cout << b[i] << "\t";
       cout << endl;

      return 0;
}

猜你喜欢

转载自blog.csdn.net/Wu_qz/article/details/81274158
今日推荐