这是代码:
char binarySearch(unsigned int target, int* primes, unsigned int size){
int* ptrToArray = primes;
unsigned int first = 0;
unsigned int last = size;
while (first <= last){
unsigned int middle = first + (last - first) / 2;
printf("first: %d, last: %d, middle: %d\n", first, last , middle);
if (ptrToArray[middle] == target){
return 1;
}
if (ptrToArray[middle] < target){
first = middle + 1;
}else{
last = middle - 1;
}
}
return 0;
}
这是输出:
我一直盯着不止一个代码的和平,但仍然无法弄清楚这个缺陷在哪里。
答案 0 :(得分:3)
如果middle
为0
,则在调试输出的末尾附近,语句为
last = middle - 1
导致整数溢出;条件必须重新修改。
答案 1 :(得分:3)
问题在于您将索引变量(first
,last
,middle
)定义为unsigned int
,而在您的逻辑中,last
实际上可以变得消极。但是,在这种情况下,由于它们被定义为unsigned
,并且由于负数的2的补码表示方式有效,因此while
循环中的条件仍然正确。
请查看以下示例代码以进行说明:
#include <stdio.h>
int main() {
/* defining the variables as unsigned */
unsigned int first_u = 0;
unsigned int last_u = -1;
if (first_u <= last_u)
printf("less than\n");
else
printf("greater or equal\n");
/* defining the variables as signed */
int first_s = 0;
int last_s = -1;
if (first_s <= last_s)
printf("less than\n");
else
printf("greater or equal\n");
return 0;
}
除此之外,您应在<
条件中使用while
,或将last
的初始值定义为size-1
。否则,如果您要搜索的元素大于数组中的最后一个元素,则会超出范围。
答案 2 :(得分:3)
首先,middle的负值是溢出(unsigned int)。
另外我认为你应该有:unsigned int last = size-1因为如果first等于last = size,你将使用ptrToArray [middle]和middle = size,因此它将超出数组边界。这也将解决上面提到的size = 0的情况。
最后,为了使您的代码更易于阅读,您可以编写:
middle =(first+last)/2
是[第一个,最后一个]空格的中间位置,equals to first+(last-first)/2
。
答案 3 :(得分:2)
当你在寻找一个不在数组中的元素并且比数组大时,你可能会越界,因为当last
和first
相等时,允许继续迭代while (first <= last)
想想发送空数组时会发生什么:size == 0
:
first = 0, last = 0
,因此:(first <= last) == true
。
然后,middle = 0 + (0 - 0)/2 = 0
,然后您访问ptrToArray[0]
,这是超出范围的。