需要比较unsigned和signed int(对我来说)(c ++)

时间:2012-08-18 11:30:46

标签: c++ types sign

我正在制作游戏(为了好玩),它有一个滚动屏幕。以下代码更新了位置:

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进行了签名,问题就会转移到代码部分。

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

什么是理想的解决方案?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

在涉及signed intunsigned int的C(++)表达式中,signed int首先转换为unsigned int,然后执行操作(+ ,*,&lt;,etc等。

要正确比较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);