2012-11-02 94 views
1

無法找到相關的答案,我的情況,所以我會盡力解釋我的情況:是否有檢查標誌和狀態的直觀方式?

我有以下代碼:

enum Flags { 
    OnlySpaces  = 1 << 0, 

    valComment  = 1 << 1, 
    valCommentBlock = 1 << 2, 
    valLabelName = 1 << 3, 
    valVariableName = 1 << 4, 
    valFunctionName = 1 << 5, 

    invSyntax  = 1 << 32, 

    fInVarLab  = valLabelName|valVariableName, 
    fInIdentifier = valLabelName|valVariableName|valFunctionName, 
    fInCommentBlock = OnlySpaces|valCommentBlock, 

    initState  = OnlySpaces|fInIdentifier|valComment, 
}; 

int lexStatus = initState; 

for (int i = 0; sc.More(); sc.Forward(), i++) { 

    if (sc.atLineStart) { 
     if (lexStatus & fInCommentBlock != fInCommentBlock) // Here is the problem 
      sc.SetState(DEFAULT); 

     lexStatus = initState; 
    } 
... // More code 
} 

我的代碼是詞法的文檔,我試圖做一個動作只有當我不在評論塊。問題是,上述說法正好返回,當我在評論我不是相反...

下面的語句正確地做這項工作,但似乎有悖常理,而:

if (lexStatus & fInCommentBlock == fInCommentBlock)

所以問題是:

  • 爲什麼?爲什麼它完全與我所期待的完全相反?

由於運算符優先級if ((lexStatus & fInCommentBlock) != fInCommentBlock)修復問題

  • 我是接近正確的方法是什麼?
  • 有沒有更好的方法?
  • 有沒有辦法確保每個標誌都有獨特的價值?

最後一個問題,因爲某些原因lexStatus & fInCommentBlock,因爲即使我不代碼的任何位置進行設置一些位的設置,因爲加...

預先感謝您的幫助!

+3

剛纔if(lexStatus&fInCommentBlock)'有什麼問題? –

+0

始終返回true ...: LexStatus = 10,fInCommentBlock = 118,LexStatus&fInCommentBlock = 2 – RaptorX

+0

'fInCommentBlock == fInCommentBlock'總是會返回true,對不對? – evanmcdonnal

回答

4

要解決您的第一個問題:您的問題是運算符的優先級以及對按位運算符的工作方式的理解。

if (lexStatus & fInCommentBlock == fInCommentBlock)

這適用於你,只是因爲==具有更高的優先級比&所以fInCommentBlock == fInCommentBlock始終是真實的,因此同樣的事情lexStatus & 1,這是同樣的事情lexStatus & OnlySpaces。由於initState包含標記OnlySpaces,因此lexStatus == initState將爲真。

有沒有更好的方法?

您想將按位比較抽象爲一個或兩個輔助函數。

int LexStatus_Is(int flags) { return (lexStatus & flags) == flags; } 
int LexStatus_IsNot(int flags) { return (lexStatus & flags) != flags; } 

然後,你可以寫:

if (LexStatus_IsNot(fInComment))

這將是更直觀。

+0

yep +1優先 – Caribou