前两天在看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;
}