1、通常我们在对一组数据进行排序的时候,只能是从小到大或者从大到小的顺序进行排序,除非去修改对应的判断条件,例如下边这个排序函数,按照从小到大排序:
void sort(int *str,int size,int (*select)(int,int))
{
int i,j,k,temp;
for(i=0;i<size-1;i++)
{
for(j=0;j<size-1-i;j++)
{
if(str[j]<str[j+1])
{
temp=str[j];
str[j]=str[j+1];
str[j+1]=temp;
}
}
}
for(int k=0;k<5;k++)
{
printf("%d ",str[k]);
}
}
假设我们要从大到小进行排序,需要修改里边的if()判断条件为str[j]>str[j+1],如下:
void sort(int *str,int size,int (*select)(int,int))
{
int i,j,k,temp;
for(i=0;i<size-1;i++)
{
for(j=0;j<size-1-i;j++)
{
if(str[j]>str[j+1])
{
temp=str[j];
str[j]=str[j+1];
str[j+1]=temp;
}
}
}
for(int k=0;k<5;k++)
{
printf("%d ",str[k]);
}
}
所以这样用起来就需要去修改代码,移植性不是很方便,假设我们定义一个函数指针,指向两个判断大小返回1与0的函数,然后调用它们进行判断,按照传参的方式来选择排序的顺序,如下:
void sort(int *str,int size,int (*select)(int,int))
{
int i,j,k,temp;
for(i=0;i<size-1;i++)
{
for(j=0;j<size-1-i;j++)
{
if(select(str[j],str[j+1]))//原判断:str[j]>str[j+1]或者 str[j]<str[j+1],等于直接用1或者0代替判断真假执行
{
temp=str[j];
str[j]=str[j+1];
str[j+1]=temp;
}
}
}
for(int k=0;k<5;k++)
{
printf("%d ",str[k]);
}
}
2、完整的代码如下:
#include <stdio.h>
//写一个函数关于回调函数的灵活运用,比如写一个排序函数,希望通过传参的方式实现从小到大或者从大到小排序
//只需在调用的时候传递对应参数即可,不用再去修改排序算法
int small_to_big(int a,int b);
int big_to_small(int a,int b);
void sort(int *str,int size,int (*select)(int,int));
//定义一个函数指针
int (*select)(int,int);
int main(void)
{
int str[5]={1,5,2,4,3};
sort(str,5,big_to_small);
return 0;
}
int small_to_big(int a,int b)
{
return (a>b)?1:0;
}
int big_to_small(int a,int b)
{
return (a<b)?1:0;
}
//冒泡排序函数
void sort(int *str,int size,int (*select)(int,int))
{
int i,j,k,temp;
for(i=0;i<size-1;i++)
{
for(j=0;j<size-1-i;j++)
{
if(select(str[j],str[j+1]))//原判断:str[j]>str[j+1]或者 str[j]<str[j+1],等于直接用1或者0代替判断真假执行
{
temp=str[j];
str[j]=str[j+1];
str[j+1]=temp;
}
}
}
for(int k=0;k<5;k++)
{
printf("%d ",str[k]);
}
}