#include<stdio.h>
int binsearch(int arr[], int x, int sz)
{
int mid = 0;
int left = 0;
int right = sz - 1;
while (left <= right)
{
mid = ((right - left) / 2 + left);
if (x < arr[mid])
{
right = mid - 1;
}
else if (x > arr[mid])
{
left = mid + 1;
}
else
{
return mid;
}
}
return 0;
}
int main()
{
int i = 1;
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
scanf("%d", &i);
int sz = sizeof(arr1) / sizeof(arr1[0]);
int red = binsearch(arr1, i, sz);
if (red)
{
printf("找到了!下标为%d\n", red);
}
else
{
printf("未找到\n");
}
return 0;
}
在编写这段代码的时候,我遇到了一个非常容易被忽略的问题(就是这个问题折磨了我二十分钟!!!),那就是使用sizeof()去测量数组的长度(数组中元素个数)。下面附上sizeof()函数的使用手册。
"sizeof" - C++ Search results (cplusplus.com)
想必大家都知道sizeof()可以计算操作数的大小,那么数组的长度就是整个数组的大小除以数组中单个元素的大小。举个栗子,在上述代码中,给定数组arr1[] = { 1,2,3,4,5,6,7,8,9,10 },因为1个整型的大小为4Byte,则由10个整型构成的数组的大小为40Byte。故sizeof(arr1) = 40,sizeof(arr1[0]) = 4(求下标为0的元素的大小)。这样,我们就可以算出数组中所包含的元素个数啦。
其实,我还没有提到问题的关键。问题的关键在于,当我们将二分查找用函数实现时,实参和形参的关系!!!下面这段代码为错误示范(当时我至少白了三根头发!):
int binsearch(int arr[], int x)
{
int mid = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
while (left <= right)
{
mid = ((right - left) / 2 + left);
if (x < arr[mid])
{
right = mid - 1;
}
else if (x > arr[mid])
{
left = mid + 1;
}
else
{
return mid;
}
}
return 0;
}
int main()
{
int i = 1;
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
scanf("%d", &i);
int red = binsearch(arr1, i);
if (red)
{
printf("找到了!下标为%d\n",red);
}
else
{
printf("未找到\n");
}
return 0;
}
大家有看出什么问题吗?没错!我是将数组传给函数后,测量的数组的长度。此时我们所得到的sizeof(arr)和sizeof(arr[0])的值分别变为8、4。
这是因为我们在传参过程中,数组将下标为0的元素的地址以指针的形式传递给了函数,避免了形参拷贝实参而造成的空间浪费,而我采用了x64,这才得到了数组指针的大小 sizeof(arr) = 8;而指针数组中每个元素都是指针,整型指针的大小为4,即sizeof(arr[0]) = 4。自然而然,函数的返回值也就错了。
最后,希望你们,也希望自己越来越优秀......