回调函数实现对整形数组和字符串的排序

(一)冒泡排序实现对整形数组的排序

    在以前,我们只会使用冒泡排序的方法对整行数组进行排序,简单的两个for循环,外层循环控制循环次数,内层循环控制比较次数,就像下面代码,便可实现:

#include<stdio.h>

int main()

{

int arr[10]={11,9,8,7,6,5,4,3,2,1};

    int i=0;

int j=0;

    int tmp=0;

for(j=0;j<10;j++)

   { for(i=0;i<10-j;i++)

 

if(arr[i]>arr[i+1])

{

tmp=arr[i];

    arr[i]=arr[i+1];

    arr[i+1]=tmp;

}

   }

for(i=0;i<10;i++)

printf("%d  ",arr[i]);

return 0;

在此基础上我们可以使用回调函数,能够同时实现对整形数组和字符串的排序

 

(二)什么是回调函数

   回调函数就是一个通过函数指针(void (*perfect)(int ))调用的函数 。如果你把函数的指针(地址)作为java培训机构排名的参数传递给另一个函数void myCallback(void (*perfect)(int ),int n),当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。

    通俗一点的可以这样理解,你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。回答完毕。

     为什么要使用回调函数?

  因为可以把调用者与被调用者分开。调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某种特定原型、某些限制条件(如返回值为int)的被调用函数。

下面便是一个简单的回调函数例子,相比其他的那些复杂的代码,我觉得这个更容易理解:

#include<stdio.h>
#include<stdlib.h>
void perfect(int n)
{
 int i=1;
    int count=0;
 for(i=1;i<n;i++)
 {
     
  if(0==n%i)
  {
   count+=i;
  }
 }
 if(count==n)
  printf("%d是完数\n",n);
 else printf("%d不是完数\n",n);
}
void myCallback(void (*perfect)(int ),int n)
{
 perfect(n);
}

int main()
{
 int n;
 printf("请输入一个正整数\n");
 scanf("%d",&n);

 myCallback(perfect,n);
 return 0;
 
}

(三)回调函数实现对整形数组和字符串的排序

冒泡排序可以实现对任意类型的数据进行排序,函数原型如下:

void bubble(void *base, int count, int length, int(*cmp)(const void *,const void *))

 其中:

void *base:待排序数组的首地址

int count:数组中待排序元素的个数

int length:各个元素占用空间的大小

int(*cmp)(const void *,const void *):指向比较函数的指针,用于确定排序的顺序

compare的函数原型为:

int cmp_char(const void *p1,const *p2)

{

assert(p1);

assert(p2);

return strcmp((char *)(*(int *)p1), (char *)(*(int *)p2));

}

以下代码写出了字符数组和整形数组的比较函数:

#include<stdio.h>

#include<stdlib.h>

#include<assert.h>

#include<string.h>

/*整型数组比较函数*/

int cmp_int(const void *p1, const void *p2)

{

assert(p1);//检测指针的有效性

assert(p2);

//由于只要满足(*(int *)p1 > *(int *)p2))>0时才交换,其余情况都不交换

return (*(int *)p1 > *(int *)p2) ? 1 : -1;

//if (*(int *)p1 > *(int *)p2)

// return 1;

//else if (*(int *)p1 == *(int *)p2)

// return 0;

//else return -1;

}

/*字符型数组比较函数*/

int cmp_char(const void *p1,const *p2)

{

assert(p1);

assert(p2);

return strcmp((char *)(*(int *)p1), (char *)(*(int *)p2));//将p1强制类型转化为整形,然后截引用,因为进行的是字符串的比较,所以又要将它再次强制类型转化为字符类型

}

/*交换函数*/

void swap(void *p1, void *p2, int size)

{

int i = 0;

assert(p1);

assert(p2);

for (i = 0; i < size; i++)

{

char temp = *((char *)p1+i);

*((char *)p1+i) = *((char *)p2+i);

*((char *)p2+i) = temp;

}

}

/*冒泡排序*/

void bubble(void *base, int count, int length, int(*cmp)(const void *,const void *))//利用回调函数实现

{

int i = 0;

int j = 0;

assert(base);

for (i = 0; i < count-1; i++)

{

for (j = 0; j < count - i - 1; j++)

{

if (cmp((char*)base + length*j, (char*)base + length*(j + 1))>0)

swap((char*)base + length*j, (char*)base + length*(j + 1),length);

}

}

}

 

int main()

{

int arr[] = { 2, 3, 6, 7, 0, 9, 1, 5, 4, 8 };

char *str[] = { "cdefc", "dcbar", "aefva", "beksf","cbsle", "cdefg"};

int len = sizeof(arr) / sizeof(arr[0]);

int size = sizeof(str) / sizeof(str[0]);

int i ,j;

bubble(arr, len,sizeof(int *),cmp_int);

bubble(str, size,sizeof(char *),cmp_char);

for (i = 0; i < len; i++)

{

printf("%d ",arr[i]);

}

printf("\n");

for (j = 0; j < size; j++)

{

printf("%s\n", str[j]);

}

system("pause");

return 0;

}

posted @ 2015-12-07 10:12  jinshiyill  阅读(624)  评论(0编辑  收藏  举报