一、编程范式。
在编写一个查找关键字的函数时,我们会考虑到所要查找的关键字的类型是什么,在什么类型的数据里面查找,以及这个数据的长度等信息。
例如:在一个 len 大小的 数组 中查找一个 整型关键字 。
int *Search_int(int *arr,int len,int key)
{
for(int i=0;i<len;i++)
{
if(arr[i] == key)
{
return &arr[i];//假如找到则返回这个值的地址。
}
}
return NULL;
}
但平时我们查找的数据不仅仅只有整型,还可能会查找到其他类型的数据,例如,char型,double型,或者还会在结构体中查找,所以我们需要编写一个查找如何数据类型的数据。
不同的数据,所查找的关键字类型不同,字节大小也不同,判断关键字和数据中是否有一样的函数也不同。所以在编写的函数中的参数列表要有:在什么数据类型中查找,所查找的数据的每个数据单元的字节数,数据的长度,关键字,判断关键字是否在数据中的函数。
例如:
void *Search(void *arr,int elemsize,int len,void* key,CmpFun cmpf)
//参数列表:所要查找的数据,所找数据的每个数据单元的字节数,所找数据的大小,关键字,判断关键字是否在数据里的函数
{
void *tmp;
for(int i=0;i<len;i++)
{
tmp = (char *)arr+i*elemsize;
//if(memcmp(tmp,key,elemsize) == 0)
if(cmpf(tmp,key) == 0)//如果关键字在数据里面,则返回所找到的关键字
{
return tmp;
}
}
return NULL;//否则返回空
}
用来判断关键字是否在所找数据中的函数,因为数据类型不相同,所以需要编写不同的判断函数也不同。
typedef int (*CmpFun)(void *,void*);//用typedef来给函数取名为CmpFun
typedef struct Student
{
char name[20];
int score;
}Student;//定义一个结构体
int Cmp_int(void *vp1,void *vp2)//int *,int *
{
return *(int*)vp1 - *(int *)vp2;
}//判断整型函数
int Cmp_double(void *vp1,void *vp2)//double *,double *
{
#define EPS 0.0000001
double tmp = *(double *)vp1 - *(double *)vp2;
if(-EPS<=tmp && tmp<=EPS)
{
return 0;
}
else if(tmp < -EPS)
{
return -1;
}
else
{
return 1;
}
}//判断double型函数
int Cmp_stu_name(void *vp1,void *vp2)
{
return strcmp(((Student *)vp1)->name ,(char *)vp2);
}//判断结构体中的名字
int Cmp_stu_sco(void *vp1,void*vp2)
{
return ((Student *)vp1)->score - *(int *)vp2;
}//判断结构体中的分数
完整的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
typedef int (*CmpFun)(void *,void*);
void *Search(void *arr,int elemsize,int len,void* key,CmpFun cmpf)
{
void *tmp;
for(int i=0;i<len;i++)
{
tmp = (char *)arr+i*elemsize;
//if(memcmp(tmp,key,elemsize) == 0)
if(cmpf(tmp,key) == 0)
{
return tmp;
}
}
return NULL;
}
typedef struct Student
{
char name[20];
int score;
}Student;
int Cmp_int(void *vp1,void *vp2)//int *,int *
{
return *(int*)vp1 - *(int *)vp2;
}
int Cmp_double(void *vp1,void *vp2)//double *,double *
{
#define EPS 0.0000001
double tmp = *(double *)vp1 - *(double *)vp2;
if(-EPS<=tmp && tmp<=EPS)
{
return 0;
}
else if(tmp < -EPS)
{
return -1;
}
else
{
return 1;
}
}
int Cmp_stu_name(void *vp1,void *vp2)
{
return strcmp(((Student *)vp1)->name ,(char *)vp2);
}
int Cmp_stu_sco(void *vp1,void*vp2)
{
return ((Student *)vp1)->score - *(int *)vp2;
}
int main()
{
int arr[] = {3,6,8,0,1,30,5};
int nkey = 10;
int *p = (int *)Search(arr,sizeof(int),7,&nkey,Cmp_int);
if(p != NULL)
{
printf("%d\n",*p);
}
double brr[] = {12.3,45.6,9.4,66.7};
double dkey = 45.61;
double *dp = (double *)Search(brr,8,4,&dkey,Cmp_double);
if(dp != NULL)
{
printf("%f\n",*dp);
}
Student crr[] = {"caocao",85,"liubei",30,"sunquan",100};
int ikey = 100;
Student *sp = (Student *)Search(crr,24,3,&ikey,Cmp_stu_sco);
if(sp != NULL)
{
printf("%s,%d\n",sp->name,sp->score);
}
return 0;
}