• C Traps:优先级常见错误


    逻辑与关系运算符

    if (flags & FLAG != 0) {...}
    

    这类错误以前也犯过,因为!=的优先级比&要高所以实际上是这样的

    if (flags & (FLAG != 0))
    

    可以把&、|也作为一种逻辑操作,而逻辑操作符的优先级总是比比较操作符、运算操作符来得低。可以这样想,首先进行了一些运算,然后才比较他们的值,通过比较有了布尔值,最后就进行逻辑与、或操作了。

     位移与算术运算符

    上面的错误可能会在不清楚的情况下使用括号,但是下面的情况则很难会觉察到,记得好几次都是莫名其妙的位移操作出现过问题。

    res = hi << 4 + low
    

    实际上相当于:

    res = hi << (4 + low)
    

    这种编码错误个人感觉非常难以察觉,尤其在对优先级生疏的情况下。类似的有

    res = low + hi << 4
    

    相当于

    res = (low + hi) << 4
    

    赋值与比较运算符

    while ((c=getc(in) != EOF) {...}
    

    内层的括号是不可缺少的,因为赋值运算优先级低于比较运算符。

    虽然有时码农编码是重复劳动,但是码农的基本功还是需要努力修炼的。

    给出一个C++的优先级表

    PrecedenceOperatorDescriptionAssociativity
    1 :: Scope resolution Left-to-right
    2 ++   -- Suffix/postfix increment and decrement
    () Function call
    [] Array subscripting
    . Element selection by reference
    -> Element selection through pointer
    3 ++   -- Prefix increment and decrement Right-to-left
    +    Unary plus and minus
    !   ~ Logical NOT and bitwise NOT
    (type) Type cast
    * Indirection (dereference)
    & Address-of
    sizeof Size-of
    newnew[] Dynamic memory allocation
    deletedelete[] Dynamic memory deallocation
    4 .*   ->* Pointer to member Left-to-right
    5 *   /   % Multiplication, division, and remainder
    6 +    Addition and subtraction
    7 <<   >> Bitwise left shift and right shift
    8 <   <= For relational operators < and ≤ respectively
    >   >= For relational operators > and ≥ respectively
    9 ==   != For relational = and ≠ respectively
    10 & Bitwise AND
    11 ^ Bitwise XOR (exclusive or)
    12 | Bitwise OR (inclusive or)
    13 && Logical AND
    14 || Logical OR
    15 ?: Ternary conditional Right-to-left
    = Direct assignment (provided by default for C++ classes)
    +=   −= Assignment by sum and difference
    *=   /=   %= Assignment by product, quotient, and remainder
    <<=   >>= Assignment by bitwise left shift and right shift
    &=   ^=   |= Assignment by bitwise AND, XOR, and OR
    16 throw Throw operator (for exceptions)
    17 , Comma Left-to-right

    记忆:

    1. 获得要进行操作的数(()函数返回值或括号表达式值,[]数组下表,. ->成员引用,从左向右结合:a->b->c->d合法)

    2. 进行单目操作(自增,自减,取地址,解引用,sizeof等,从右向左结合:*p++等同于*(p++))

    3. 进行双目操作(乘除模,加减,位移,关系,位逻辑,逻辑,逻辑运算优先级低于其他关系算术运算,或低于与,从左向右结合)

    4. 赋值(从右向左结合:a=b=c)

    5. 逗号表达式(从左向右结合)

    () 函数调用、括号肯定可以记住

    参考:

      1. C traps and pitfalls

      2. http://en.cppreference.com/w/cpp/language/operator_precedence

  • 相关阅读:
    1022 D进制的A+B
    1021 个位数统计
    L1-040 最佳情侣身高差
    Celery--基本使用
    Celery--安装
    Celery--简介
    RabbitMQ--常用命令
    RabbitMQ--RPC实现
    RabbitMQ发布订阅
    RabbitMQ基本使用
  • 原文地址:https://www.cnblogs.com/lailailai/p/3660536.html
Copyright © 2020-2023  润新知