目录
开头
大家好,我叫这是我58。今天,我们来学一下关于C语言里的
bsearch
函数的一些知识。
1.什么是
bsearch
函数
bsearch
函数,来自于
stdlib.h
头文件,也叫
binary search
函数(二分查找函数)就是一个用二分查找法来查询要查询的有序数组中的某一个要查找的元素的函数,
bsearch
函数有5个参数,分别是
const void* key, const void* base, size_t num, size_t size
和
int (*compar)(const void*,const void*)
,这五个参数分别代表了:要查询的元素的指针(需强制转换成
void*
类型),从哪个有序数组查询,要查询的有序数组的元素个数,要查询的有序数组的每个元素的大小和判断检测到的元素是否为查找的元素的方法。而在
bsearch
函数的第五个参数中,如果返回
<0
的值,那么这个参数就是在告诉
bsearch
函数解引用之后的要查询的元素的指针比要查询的有序数组的某一个元素小了,否则如果返回
>0
的值,那么这个参数就是在告诉
bsearch
函数解引用之后的要查询的元素的指针比要查询的有序数组的某一个元素大了,如果既不返回
<0
的值又不返回
>0
的值,那这个参数就是在告诉找到解引用之后的要查询的元素的指针在要查询的有序数组的那个位置了,也就是说,
bsearch
函数解引用之后的要查询的元素的指针就是等于要查询的有序数组的某一个元素了。而这个
bsearch
函数,如果解引用之后的要查询的元素的指针等于要查询的有序数组的其中一个元素,就返回类型为
void*
的指向已经查询好的数组中与要查询的元素的指针匹配的条目的指针,如果有一个以上的匹配元素(即
bsearch
函数的第五个参数会输出一个以上的
0
),
bsearch
函数就可能返回指向其中任何一个与要查询的元素的指针匹配的条目的指针(不一定是第一个与要查询的元素的指针匹配的条目的指针)。否则如果查询好的有序数组的每一个元素都不等于解引用之后的要查询的元素的指针,那么
bsearch
函数就输出
NULL
。那么,为什么
bsearch
函数的第一,第二个参数的类型和第五个参数(第五个参数为函数)的所有参数的类型都是
const void*
呢?其实啊,这样做既是为了增加这个
bsearch
函数的健壮性(鲁棒性),又是让这个函数什么类型的数据都能查找呢!那么,
bsearch
函数的第五个参数可以怎样写呢?想知道的话,就看看下面的内容吧。
2.
bsearch
函数的第五个参数的写法
如果要从类型为
char
的有序的字符数组(字符串)查找你想要的字符元素到底在不在,那么
bsearch
函数的第五个参数可以这样写:
intchrcmp(constvoid* vp,constvoid* vpa){return*(char*)vp -*(char*)vpa;}
intchrcmp(constvoid* vp,constvoid* vpa){return*(char*)vpa -*(char*)vp;}
intchrcmp(constvoid* vp,constvoid* vpa){return-(*(char*)vp -*(char*)vpa);}
在上面的第一个函数中,先把
void*
类型的指针
vp
和
vpa
强制转换成了
char*
类型的指针,然后再把这些强制转换成了
char*
类型的指针解引用一下,最后返回解引用之后的字符指针
vp
减去解引用之后的字符指针
vpa
的值。而第二个函数就是在第一个函数的基础上把返回值的被减数换成了解引用并被强制转换成
char*
类型之后的
vpa
,而返回值的减数则换成了解引用并被强制转换成
char*
类型之后的
vp
,而第三个函数则是返回了第一个函数的返回值的相反数了。因此,这三个函数的返回值以表格的形式可以这样写。
从这个表格中,我们可以看到如果
0==*(char*)vp - *(char*)vpa
,那么这三个函数都返回
0
,因此,不管怎么样,这三个函数最终都会正常地找到或者没找到要查询的元素。
而如果要从类型为
char
的二维字符数组查找你想要的字符串元素到底在不在,那么在你导入
string.h
头文件之后,
bsearch
函数的第五个参数就可以是
strcmp
函数的地址了,因为
strcmp
函数与
bsearch
函数的第五个参数的返回值是一模一样的。因此,
bsearch
函数的第五个参数就可以是
strcmp
函数的地址了。
3.
bsearch
函数的实际运用
有序数组查询
#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>#include<stdlib.h>intintcmp(constvoid* vp,constvoid* vpa){return*(int*)vpa -*(int*)vp;}intmain(){int arr[10]={1,42,3,5,7,342,54,43,3,3332};int i =0;printf("请输入你要查询的数字 -> ");scanf("%d",&i);qsort(arr,10,4, intcmp);int* ip =((int*)(bsearch((void*)(&i), arr,10,4, intcmp)));
ip &&printf("“%d”在这个有序的arr数组里",*ip), ip ||printf("“%d”不在这个有序的arr数组里",i);return0;}
有序字符串查询
#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>#include<stdlib.h>intchrcmp(constvoid* vp,constvoid* vpa){return*(char*)vp -*(char*)vpa;}intmain(){char str[11]="hfu3jkdue-";char ch =0;printf("请输入你要查询的字符 -> ");scanf("%c",&ch);qsort(str,11,1, chrcmp);char* cp =((char*)(bsearch((void*)(&ch), str,11,1, chrcmp)));
cp &&printf("“%c”在这个有序的str字符串里",*cp), cp ||printf("“%c”不在这个有序的str字符串里",ch);return0;}
有序二维字符串数组查询
#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>#include<stdlib.h>#include<string.h>intmain(){char str[10][11]={"fagsfdrefd","454fv41ddd","64vfd7#$%)","&&&%%gbdla",";;;;;h;h;o","qgsdjeh52g","alalalalal","jfhryf5555","jndhejbrfd","jfgrjhzvas"};char stra[11]="";printf("请输入你要查询的字符串 -> ");scanf("%s", stra);qsort(str,10,11, strcmp);char* cp =((char*)bsearch((void*)(&stra), str,10,11, strcmp));
cp &&printf("“%s”这个字符串在这个有序的str二维数组里", cp), cp ||printf("“%s”这个字符串不在这个有序的str二维数组里",stra);return0;}
结尾
在你看到这里之后,可以评论来互动一下我哦。
版权归原作者 这是我58 所有, 如有侵权,请联系我们删除。