2014-02-25 52 views
2

我想知道是否有可能有一個變量後,返回其值?複合語句返回後更改值?

有問題的函數是一個私有布爾標誌變量的簡單get函數。我想這個標誌的讀取是破壞性的,所以我想:

bool myGet (context_t * someContext) { 
    return (someContext->flag) ? (someContext->flag = false) : false; 
} 

推理評估聲明(someContext->flag = false)的結果將是true,但它似乎沒有。

也許它的評估之前條件(someContext->flag)?

是否有任何其他方式來實現預期的功能,而不訴諸臨時存儲標誌值,清除標誌,然後返回臨時副本?謝謝。

回答

5

return的所有參數必須在評估return本身之前進行評估,即在執行離開當前函數之前。

作業的值是分配的值,因此您的體驗值爲false

我認爲你可以最接近的是後增量,但這當然會嚴格限制可用的值。

沒有錯用做它的明確的方法:

bool getAndClear(context_t *someContext) 
{ 
    if(someContext->flag) 
    { 
    someContext->flag = false; 
    return true; 
    } 
    return false; 
} 

這是非常清楚的,更容易比你可怕的代碼來了解方式。很容易想象,編譯器可以優化它,因爲它非常簡單。

如果我想要弄巧,我可能會使用類似:

bool getAndClear2(context_t *someContext) 
{ 
    const bool flag = someContext->flag; 

    someContext->flag ^= flag; /* Clears if set, leaves alone if not set. */ 

    return flag; 
} 

需要注意的是它沒有分支,有時俏皮。但是,再次,聰明並不總是最好的選擇。

另外請注意,我認爲這是一個要求,此功能不只是命名爲「獲取」的東西,因爲它不需要const指針,這將是我腦海中的即時警告標誌。由於它具有超奇怪(對於吸氣劑)的副作用,因此應以某種方式反映在名稱中。

+0

我喜歡這個不需要臨時變量,並具有相同數量的分支 – Toby

2

推理評估語句(someContext->flag = false)的結果是正確的,但似乎沒有。

(someContext->flag = false)是一個賦值表達式。其值是分配表達式的值(即false)。

該作業確實經歷了,儘管它發生在返回之前,而不是之後。如果你想成爲幻想和留在三元運算符,你可以使用逗號運算符,就像這樣:

return (someContext->flag) ? (someContext->flag = false, true) : false; 

這不是很可讀,雖然如此,我寧願這相當於實現,它沒有條件語句:

bool temp = someContext->flag; 
someContext->flag = false; 
return temp; 
0

可以使用遞減後的運營商:

return (someContext->flag) ? someContext->flag-- : false; 

這隻會有希望的結果,如果你的標誌true值有n個數值爲1

2

當你做(someContext->flag = false)它將someContext->flag設置爲false,然後返回它。

你可以這樣做:

return (someContext->flag) ? !(someContext->flag = false) : false; 

這樣,您將回到您剛纔設置的someContext->flag的oposite假的(所以你返回true),但回報

編輯後someContext->flag會留下假

最不可讀的是:

return !(someContext->flag = !someContext->flag); 
+0

我喜歡這種方法,簡短又甜美:) 但是缺少一些可讀性,所以我可能不得不放棄一些回答 – Toby

+1

你剛剛習慣了它,但我承認。它甚至可能是最糟糕的! (見編輯) – EoiFirst