我正在制作游戏(为了好玩),它有一个滚动屏幕。以下代码更新了位置:
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 :(得分:0)
当二元运算符的两边具有不同的符号时,带符号的操作数将被提升为无符号。这在C标准中是一个奇怪的东西,但你必须通过强制转换来处理它(但在这种情况下这将是一个错误),或者在这种情况下,通过使用有符号整数来保存这两个值。
答案 1 :(得分:0)
如果您对数学上合理的比较感兴趣,则不应直接比较任意unsigned
和signed ints
。那是因为C(++)的算术不是常规的数学运算。
在涉及signed int
和unsigned int
的C(++)表达式中,signed int
首先转换为unsigned int
,然后执行操作(+ ,*,&lt;,etc等。
要正确比较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);