2012-08-18 95 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標準中的一個奇怪現象,但您必須通過強制轉換(但在這種情況下這將是錯誤)或者在這種情況下,通過使用有符號整數來保存這兩個值來處理它。

相關問題