无符号和有符号int(对我)之间的比较显示需要(C++)
我正在做一个游戏(为了好玩),它有一个滚动屏幕。以下代码位更新位置:无符号和有符号int(对我)之间的比较显示需要(C++)
screen_x += screen_scroll_x;
if(screen_x < 0)
screen_x = 0;
if(screen_x > map_width - screen_width)
screen_x = map_width - screen_width;
我很努力地为screen_x选择正确的整数类型。如果已签名,则screen_x > map_width - screen_width
会引发“无符号和有符号比较”的警告。如果它未经签名,if(screen_x < 0)
失败(带有创意结果),因为screen_x永远不会成为负数。
map_width
比较加载地图时的字符串长度,所以如果我们让map_width
签名,问题就转移到了那部分代码。
很多人都说过你应该使用正确的整数。他们也说要注意你的警告,并且它让我感到我得到了警告(太多了,你不再关注它们)。
什么是理想的解决方案?
如果您对数学上合理的比较感兴趣,您不应该直接比较任意unsigned
和signed ints
。那是因为C(++)的算术不是你常规的数学算术。
在涉及signed int
和unsigned int
一个C(++)的表达,所述signed int
首先被转换为一个unsigned int
,然后执行操作(+,*,<,等)。
要正确比较signed int
和unsigned int
,您应该考虑C(++)的“算术规则”以及编程语言规定的并且对于未初始化者不可见的类型/值转换。
所以,你可以比较两个这样的:
/* returns -1 if s < u,
returns 0 if s == u,
returns 1 if s > u */
int CompareSignedUnsigned(int s, unsigned u)
{
if (s < 0) return -1; // negative is always smaller than 0 or positive
if (s < u) return -1; // obvious
if (s > u) return 1; // obvious
return 0; // obvious
}
至于使用正确的整数,这是一个很好的建议,但有时一个尺寸不适合所有。而屏幕上的坐标就是这样一个区域,在这个区域里签署坐标可能更合理。例如,想象一下,你想要一个例程在屏幕上渲染一个盒子,并且你希望能够画出一个在屏幕上移动的盒子,从屏幕外部移动(移动到屏幕外部)并在外部结束(搬出去)。
如果你选择这样的API:
void DrawBox(unsigned x, unsigned y, unsigned width, unsigned height, color c);
这一功能的用户将不得不做绘图盒的一部分时,一些额外的数学,当一个部分是在屏幕上,另一个是关闭屏幕。所有这些都是因为根本没有办法告诉这个功能,原来的/未被收缩的盒子确实不在屏幕上。
现在,如果你选择这一项,而不是:
void DrawBox(int x, int y, unsigned width, unsigned height, color c);
和移动额外的裁剪数学函数里面,突然这个功能的用户能够编写代码非常简单。它可以是这样简单:
for (int x = -100; x < SCREEN_WIDTH + 100, x++)
DrawBox(x, SCREEN_HEIGHT/2, 100, 50, GREEN);
当二元运算符的双方的签名不同时,带符号的操作数将被提升为无符号。这是C标准中的一个奇怪现象,但您必须通过强制转换(但在这种情况下这将是错误)或者在这种情况下,通过使用有符号整数来保存这两个值来处理它。
谢谢,我会给顶部一个镜头(或类似的东西)。我不认为会有一个“好”的出路。再次感谢! – Cramer 2012-08-19 06:35:41