为什么start+(end–start)/2比(start+end)/2更适合计算数组的中间部分?

我非常确信,一旦知道数组的开始索引和结束索引,每个人都可以找到数组的中间索引,但使用 开始+(结束-开始)/2 结束 (开始+结束)/2 ,如下所述:

null

找到中间索引的第一种方法是

mid = (start + end)/2

但这种方法存在问题,如果start或end或两者的值都是 INT_MAX ,它将导致整数溢出。 计算中间指数的更好方法是:

mid = start + (end - start)/2

让我们在C程序中尝试这两种方法:

C

// program for calculating mid of array
#include <stdio.h>
#include <limits.h>
int main()
{
int start = INT_MAX, end = INT_MAX;
printf ( "start = %dn" , start);
printf ( "end = %dn" , end);
// method 1
int mid1 = (start + end) / 2;
printf ( "mid using (start + end)/2 = %dn" , mid1);
// method 2
int mid2 = start + (end - start) / 2;
printf ( "mid using start + (end - start)/2 = %dn" , mid2);
return 0;
}


输出:

start = 2147483647end = 2147483647mid using (start + end)/2 = -1mid using start + (end - start)/2 = 2147483647

注: 如果end<0或start<0,则(end–start)可能溢出 如果你看到了输出,使用第二种方法你得到了正确的输出,第一种方法无法计算mid,如果你使用这个指数 (-1在这种情况下) ,它可能会因为数组索引无效而导致分段错误。

start+(end–start)/2即使在使用指针时也可以工作:

例子: 方法1

C

int s = 2, e = 3;
int * start = &s;
int * end = &e;
int * mid = (start + end) / 2;


输出:

error: invalid operands of types ‘int*’ and ‘int*’ to binary ‘operator+’     int *mid = (start + end)/2;

方法2

C

int s = 2, e = 3;
int * start = &s;
int * end = &e;
int * mid = start + (end - start) / 2;


输出:

It will compile and give expected results

说明: C语言中不支持指针加法,而支持指针减法,原因是减法的结果是操作数之间的差异(在数组元素中)。减法表达式产生类型为ptrdiff_t(在标准include文件STDDEF.H中定义)的带符号整数结果 (简而言之,减法给出了记忆距离) ,但在中添加两个指针没有意义,这就是为什么不支持

参考资料: 1) 加法运算符:+和– 2) why-preference-start-end-start-2-over-start-end-2-when-computing-the 3) 指针加减

本文由 曼迪星 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享