弄C++很多年了,没想到还居然被这种问题所困,其实不光我了,问了几个同道中人,都未能很好解释为什么,不过我还是记录一下,有知情人士看到的话不妨留言告知。
代码是hello world级别的,很简单:
int _tmain(int argc, _TCHAR* argv[])
{
int ni = 50;
unsigned int ui = 100;
printf("%d\n", ni-ui);
printf("%d\n", (ni-ui)*2);
printf("%d\n", (ni-ui)/2);
printf("%d\n", (ni-(int)ui)/2);
return 0;
}
问题:输出结果是什么?
我预期的输出结果应该是这样:
-50
-100
-25
-25
而事实上是:
-50
-100
2147483623
-25
在VC6,VS2005和VS2008上调试过,结果完全一致,这就表示,(ni-ui)/2的结果被认为是一个无符号整型,为什么会这样呢?我看了一下反汇编……其实,我没看明白。(汇编没学好)
这种小问题可能会引发大问题,我最近在设计一个程序,把图片贴到窗口上,图片的宽和高被我设计为无符号的,因为宽和高最小为0,不可能是负数,而图片的绘制位置则有可能是负数,这跟坐标系有关,这样有符号和无符号之间就有可能出现了上面的那种操作,导致程序出现了一些怪异的行为,通过调试,发现是这个问题。
解决方法很简单,只要加上一个强制转换即可,像代码最后一个printf语句那样。但为什么这样我就不太清楚了,是C++的规范,还是编译器的问题,有其它编译器的朋友可以试试看。