簡體   English   中英

似乎需要對unsigned和signed int之間進行比較(C ++)

[英]comparison between unsigned and signed int (to me) appears required (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簽名,則問題將轉移到該部分代碼。

許多人說過,您應該使用正確的整數。 他們還說要注意您的警告,這使我感到困惑,因為我確實收到了警告(警告太多了,您就停止關注它們了)。

什么是理想的解決方案?

當二進制運算符的兩端具有不同的符號性時,有符號的操作數將被提升為無符號。 在C標准中,這是一個奇怪的問題,但是您必須通過強制轉換(但在這種情況下將是一個錯誤)或在這種情況下通過使用帶符號的整數來保存這兩個值來處理它。

如果您對數學上合理的比較感興趣,則不應直接比較任意的unsigned和有signed ints 那是因為C(++)的算術不是您的常規數學算術。

在涉及一個C(++)表達signed intunsigned int ,所述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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM