我看到很多人在qsort比较器函数中使用减法.我认为这是错误的,因为在处理这些数字时:int nums[]={-2147483648,1,2,3}; INT_MIN = -2147483648;
int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
Run Code Online (Sandbox Code Playgroud)
我写了这个函数来测试:
#include <stdio.h>
#include <limits.h>
int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main(void)
{
int a = 1;
int b = INT_MIN;
printf("%d %d\n", a,b);
printf("%d\n",compare((void *)&a,(void *)&b));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
1 -2147483648
-2147483647
Run Code Online (Sandbox Code Playgroud)
但a > b所以输出应该是积极的.我看过很多书写得像这样.我认为这是错的; 处理int类型时应该这样写:
int compare (const void * a, const void * b)
{
if(*(int *)a < *(int *)b)
return -1;
else if(*(int *)a > *(int *)b)
return 1;
else
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚为什么许多书籍和网站以这种误导的方式写作.如果您有任何不同的观点,请告诉我.
我认为这是错误的
是的,简单的减法可能导致int溢出,这是未定义的行为,应该避免.
return *(int*)a - *(int*)b; // Potential undefined behavior.
Run Code Online (Sandbox Code Playgroud)
一个常见的习语是减去两个整数比较.各种编译器都认识到这一点并创建了高效良好的代码. 保留const-ness也很好的形式.
const int *ca = a;
const int *cb = b;
return (*ca > *cb) - (*ca < *cb);
Run Code Online (Sandbox Code Playgroud)
为什么许多书籍和网站都以这种误导的方式写作.
return *a - *b;在概念上很容易消化 - 即使它提供了极端值的错误答案 - 通常学习者代码省略了边缘条件来理解 - "知道"价值永远不会很大.
或者考虑 与NaN 相比long doubles的复杂性.
| 归档时间: |
|
| 查看次数: |
348 次 |
| 最近记录: |