目录
- 开头
- 1.什么是``bsearch``函数
- 2.``bsearch``函数的第五个参数的写法
- 3.``bsearch``函数的实际运用
- 有序数组查询
- 有序字符串查询
- 有序二维字符串数组查询
- 结尾
开头
大家好,我叫这是我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
。1那么,为什么bsearch
函数的第一,第二个参数的类型和第五个参数(第五个参数为函数)的所有参数的类型都是const void*
呢?其实啊,这样做既是为了增加这个bsearch
函数的健壮性(鲁棒性),又是让这个函数什么类型的数据都能查找呢!那么,bsearch
函数的第五个参数可以怎样写呢?想知道的话,就看看下面的内容吧。
2.bsearch
函数的第五个参数的写法
如果要从类型为char
的有序的字符数组(字符串)查找你想要的字符元素到底在不在,那么bsearch
函数的第五个参数可以这样写:
int chrcmp(const void* vp,const void* vpa) {
return *(char*)vp - *(char*)vpa;
}
int chrcmp(const void* vp, const void* vpa) {
return *(char*)vpa - *(char*)vp;
}
int chrcmp(const void* vp, const void* 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_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int intcmp(const void* vp, const void* vpa) {
return *(int*)vpa - *(int*)vp;
}
int main() {
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);
return 0;
}
有序字符串查询
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int chrcmp(const void* vp, const void* vpa) {
return *(char*)vp - *(char*)vpa;
}
int main() {
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);
return 0;
}
有序二维字符串数组查询
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
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);
return 0;
}
结尾
在你看到这里之后,可以评论来互动一下我哦。
选自C语言中的
bsearch
函数的简介 ↩︎