2012-04-10 26 views
0

我有一個相對簡單的算法,走一個std ::向量尋找兩個相鄰的元組。一旦發現X值的左側和右側的元組,我可以在它們之間進行插值。不知怎的,這個工程:爲什麼2個NULL指針不計算爲false?

std::vector<LutTuple*>::iterator tuple_it; 
    LutTuple* left = NULL; 
    LutTuple* right = NULL; 
    bool found = 0; 

    // Only iterate as long as the points are not found 
    for(tuple_it = lut.begin(); (tuple_it != lut.end() && !found); tuple_it++) { 
    // If the tuple is less than r2 we found the first element 
    if((*tuple_it)->r < r) { 
     left = *tuple_it; 
    } 
    if ((*tuple_it)->r > r) { 
     right = *tuple_it; 
    } 
    if(left && right) { 
     found = 1; 
    } 
    } 

,而這一點:

std::vector<LutTuple*>::iterator tuple_it; 
    LutTuple* left = NULL; 
    LutTuple* right = NULL; 

    // Only iterate as long as the points are not found 
    for(tuple_it = lut.begin(); tuple_it != lut.end() && !left && !right; tuple_it++) { 
    // If the tuple is less than r2 we found the first element 
    if((*tuple_it)->r < r) { 
     left = *tuple_it; 
    } 
    if ((*tuple_it)->r > r) { 
     right = *tuple_it; 
    } 
    } 

沒有。這是爲什麼?我期望這樣的兩個NULL ptrs在否定時一起評估爲真。

+6

http://en.wikipedia.org/wiki/De_Morgan's_laws – HostileFork 2012-04-10 15:23:15

回答

4

這是一個合乎邏輯的問題。

在您的第一個片段(本質上)!(left && right)

在第二個片段中您有:!left && !right

那些不相同。

如果您構建真值表,您會意識到!(left && right)相當於(!left || !right)

+0

謝謝,這清除了我! – Julik 2012-04-11 13:53:23

5

第二個循環將在找到任何一個時立即終止。條件更改爲:

tuple_it != lut.end() && !(left && right) 

tuple_it != lut.end() && (!left || !right) 

繼續,直到兩個被發現。

0

我期望這樣的兩個NULL ptrs在 否定時一起評估爲真。

這沒有意義。不要「否定」指針,並期望在強制進入布爾表達式時他們將評估什麼。相反,我建議將它們明確地與NULL進行比較。

另外,移動你的複雜布爾表達式來繼續循環到一個單獨的行,否則很難在邏輯上跟隨代碼。

+2

從指針到布爾的標準轉換已經很好的定義了。是否使用這種選擇或明確的比較是純粹的審美。 – 2012-04-10 15:23:05

+0

@Mike,我的回答是可讀性,不正確。我確信代碼在編寫時的行爲是「正確的」 - 只是它不符合作者的期望,所以問題主要在於使其更具可讀性並且不易出錯。 – 2012-04-10 15:24:30

+1

人們可能會很容易認爲標準轉換更具可讀性且不易出錯;這個選擇純粹是美學的,你的個人偏好與這個問題無關。 – 2012-04-10 15:27:58

相關問題