2012-01-28 54 views
8

我對C++中使用無符號整數而不是有符號整數的循環進行了反轉的Stackoverflow做了一些研究。但我仍然不明白爲什麼會出現問題(請參閱Unsigned int reverse iteration with for loops)。爲什麼下面的代碼會產生分段錯誤?C++ for循環中的無符號整數

#include <vector> 
#include <iostream> 
using namespace std; 

int main(void) 
{ 
    vector<double> x(10); 

    for (unsigned int i = 9; i >= 0; i--) 
    { 
     cout << "i= " << i << endl; 
     x[i] = 1.0; 
    } 

    cout << "x0= " << x[0] << endl; 

    return 0; 
} 

我知道問題是當索引i等於零,因爲有像溢出一樣的東西。但我認爲一個無符號整數可以取零值,不是嗎?現在,如果我用有符號整數替換它,那絕對沒有問題。

有人可以解釋我背後的反向循環與無符號整數的機制?

非常感謝!

+3

對於無符號'i','i> = 0'總是如此,所以循環永遠不會終止。 – TonyK 2012-01-28 08:58:35

+0

閱讀編譯器警告,它們很有用。在這種情況下,您的編譯器應該已經警告過您,循環中的條件始終爲真。 – dragonroot 2012-01-28 09:20:05

+0

@dragonroot:不幸的不是。我使用g ++的-Wall標誌。你知道一個編譯器標誌可以檢測到這種問題嗎?謝謝。 – Benjamin 2012-01-28 09:27:44

回答

24

這裏的問題是一個無符號整數永遠不會是負數。

因此,循環測試:

i >= 0 

永遠是正確的。因此你得到一個無限循環。

當它下降到零以下時,它將包裝到最大值unsigned值。
因此,你也將訪問x[i]出界外

這不是一個有符號整數,因爲它會簡單地去否定,因而不能i >= 0問題。

因此,如果你想使用無符號整數,你可以嘗試以下可能性之一:

for (unsigned int i = 9; i-- != 0;) 

for (unsigned int i = 9; i != -1; i--) 

這兩個被GManNickG和AndreyT從意見建議。


下面是我原來的3個版本:

for (unsigned int i = 9; i != (unsigned)0 - 1; i--) 

for (unsigned int i = 9; i != ~(unsigned)0; i--) 

for (unsigned int i = 9; i != UINT_MAX; i--) 
+0

或者'i'​​比索引*多一個*,因此'0'是一個正確的終止條件。像其他人一樣棘手。 – 2012-01-28 13:23:31

+0

不是整數溢出和下溢未定義的行爲? – josefx 2012-01-28 14:17:44

+2

@josefx只有有符號整數溢出/下溢是未定義的行爲。 – Mysticial 2012-01-28 18:19:44

4

不管的unsigned int i值它始終是真實的i >= 0桑尼我們的for循環永不結束。

換句話說,如果在某個時刻i是0,你遞減它,它仍然保持非負,因爲它則蘊含着巨大的數字,大概4294967295(即2 -1)。

6

問題是,你的循環允許i到低至爲零,僅期望退出循環如果i小於0。由於i是無符號的,它可以永遠不會小於0。翻轉到2^32-1。這大於你的矢量的大小,因此導致段錯誤。

3

的問題是在這裏:

for (unsigned int i = 9; i >= 0; i--) 

你開始與一個unsigned int a的9價值和你退出定義爲i> = 0,這將是總是如此。 (unsigned int永遠不會是負面的!!!)。正因爲如此,你的循環將重新開始(無限循環,因爲我= 0,然後-1變成最大值)。