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コードのどこにも設定していなくても、一部のビットが設定されているため、最後の質問が追加されました...

よろしくお願いします!

4

1 に答える 1

4

最初の質問に対処するには: 問題は、演算子の優先順位と、ビットごとの演算子がどのように機能するかを理解することです。

if (lexStatus & fInCommentBlock == fInCommentBlock)

これは、 so==よりも優先順位が高いという理由だけで機能します。したがって、 と同じであり、 と同じです。これは、フラグが含まれているため、 true になります。&fInCommentBlock == fInCommentBlocklexStatus & 1lexStatus & OnlySpaceslexStatus == initStateinitStateOnlySpaces

より良い方法はありますか?

ビットごとの比較を 1 つまたは 2 つのヘルパー関数に抽象化します。

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

次に、次のように記述できます。

if (LexStatus_IsNot(fInComment))

どちらがより直感的でしょう。

于 2012-11-03T00:09:48.190 に答える