2012-08-18 52 views
1

我正在做一个游戏(为了好玩),它有一个滚动屏幕。以下代码位更新位置:无符号和有符号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签名,问题就转移到了那部分代码。

很多人都说过你应该使用正确的整数。他们也说要注意你的警告,并且它让我感到我得到了警告(太多了,你不再关注它们)。

什么是理想的解决方案?

回答

0

如果您对数学上合理的比较感兴趣,您不应该直接比较任意unsignedsigned ints。那是因为C(++)的算术不是你常规的数学算术。

在涉及signed intunsigned int一个C(++)的表达,所述signed int首先被转换为一个unsigned int,然后执行操作(+,*,<,等)。

要正确比较signed intunsigned 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); 
+0

谢谢,我会给顶部一个镜头(或类似的东西)。我不认为会有一个“好”的出路。再次感谢! – Cramer 2012-08-19 06:35:41

0

当二元运算符的双方的签名不同时,带符号的操作数将被提升为无符号。这是C标准中的一个奇怪现象,但您必须通过强制转换(但在这种情况下这将是错误)或者在这种情况下,通过使用有符号整数来保存这两个值来处理它。

相关问题