C演算子


TOC
  • Operators
  • Operator Precedence and Associativity
  • Operators That Change Operands
  • Alternative Representation of Operators

  • 演算子

    Until C99, 50 operators. Since C11, 51 operators, _Alignof . compound literal [C99] not included in the total.

    • 6 bitwise operators:
      • Unary bitwise NOT ~ .
      • Binary operators << , >> , & , ^ , | .
    • 5 binary operators:
      • Bitwise left shift << .
      • Bitwise right shift >> .
      • Bitwise AND & .
      • Bitwise exclusive or (XOR) ^ .
      • Bitwise inclusive or (OR) | .
    • 3 logical operators:
      • Logical AND && .
      • Logical OR || .
      • Unary not ! .
    • 11 assignment operators:
      • Simple assignment = .
      • Compound assignment, augmented assignment, or combined assignment *= , /= , %= , += , -= , <<= , >>= , &= , ^= , |= .
    • 6 unary operators:
      • Address of & .
      • Pointer type * .
      • Unary arithmetic + , - , ~ , ! .
    • 4 unary arithmetic operators:
      • Plus (integer promotion) + , result is an arithmetic type.
      • Minus (additive inverse) - , result is an arithmetic type.
      • Bitwise NOT ~ , result is integer type.
      • Logical negation NOT ! , result is a scalar type of int
    • 13 arithmetic operators:
      • Unary + ( +x ) and - ( -x ).
      • Additive + ( x+y ) and - ( x-y ).
      • Multiplicative * ( x*y ), / ( x/y ) and % ( x%y ).
      • Bitwise ~ ( ~x ), << ( x<<y ), >> ( x>>y ), & ( x&y ), ^ ( x^y ) and | ( x|y ).
    • 3 multiplicative operators:
      • Multiplication * .
      • Division / .
      • Modulo % , result is integer type.
    • 2 additive operators:
      • Addition + .
      • Subtraction - .
    • 6 comparison operators:
      • Equality == , != .
      • Relational < , > , <= , >= .
    • 4 relational operators:
      • Less than < .
      • Bigger than > .
      • Less than or equal to <= .
      • Bigger than or equal to >= .
    • 2 equality operators:
      • Equal to == .
      • Not equal to != .
    • 5 member access:
      • Array subscription [] ( x[y] ).
      • Indirection operator, pointer type * ( *x ).
      • Address operator & ( &x ).
      • Access member of struct or union . ( x.y ).
      • Access member of struct or union using pointer -> ( x->y ).
    • 2 prefix, increment and decrement operators: ++prefix and --prefix .
    • 2 postfix, increment and decrement operators: postfix++ and postfix-- .
    • 7 miscellaneous operators:
      • Comma , .
      • Conditional operator or ternary ? : , x > y ? 1 : 0; .
      • Function call ( ) , x(y,z) .
      • sizeof , result is size in bytes.
      • [C11] _Alignof( type ) , result is the alignment requirement of the type.
      • Conversion, c-style cast: ( type ) x .
      • Compound literal[C99] ( type ){ initializer-list } , the result is a unnamed object.

    Notes:

    • Compound literal behave as an operator but is not explicit in the standard as part of the group operators, but in this guide is considered an operator.
    • Same Symbol Different Operators. The behavior is defined by how it is used:
      • Bitwise AND & vs Address Of & .
      • Multiplication * vs Indirection Operator * (Pointer).
      • Unary Minus - and Unary Plus + vs Additive Operators - and + .
    • 💩 Applying comparison operators to Infinite or Not-a-Number (NaN) values will cause an exception. NaN does not compare to anything, even between NaN and NaN. To proper compare use isnan function from <math.h> . To compare an Infinite value use isinf or isfinite macros.
    • ⚠️ Arithmetic operators applied to floating-point types may cause NaN or Infinite value.

    演算子の優先順位と結合性
    1. Associativity: Left-to-right
      • () - Function call
      • [] - Array subscripting
      • . - Structure and union member access
      • -> - Structure and union member access through pointer
      • ++ , -- - Suffix/postfix increment and decrement
      • (type){list} - Compound literal [C99]
    2. Associativity: Right-to-left
      • ! , ~ - Logical NOT and bitwise NOT
      • ++ , -- - Prefix increment and decrement
      • + , - - Unary plus and minus
      • (type) - Type cast
      • sizeof - Size-of
      • * - Indirection (dereference), pointer syntax
      • & - Address-of
      • _Alignof - Alignment requirement [C11]
    3. Associativity: Left-to-right
      • * - Multiplication
      • / - Division
      • % - Modulus
    4. Associativity: Left-to-right
      • + - Addition
      • - - Subtraction
    5. Associativity: Left-to-right
      • << - Bitwise left shift
      • >> - Bitwise right shift
    6. Associativity: Left-to-right
      • < - Less than
      • <= - Less than OR equal to
      • > - Greater than
      • >= - Greater than OR equal to
    7. Associativity: Left-to-right
      • == - Equal to
      • != - NOT equal to
    8. Associativity: Left-to-right
      • & - Bitwise AND
    9. Associativity: Left-to-right
      • ^ - Bitwise XOR (exclusive or)
    10. Associativity: Left-to-right
      • | - Bitwise OR (inclusive or)
    11. Associativity: Left-to-right
      • && - Logical AND
    12. Associativity: Left-to-right
      • || - Logical OR
    13. Associativity: Right-to-Left
      • ?: - Ternary conditional. Test your compiler precedence on this one.
    14. Associativity: Right-to-Left
      • = - Simple assignment
      • += , -= - 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
    15. Associativity: Left-to-right
      • , - Comma

    Notes:

    • Precedence and associativity are independent from order of evaluation.
    • C language standard doesn't specify operator precedence.
    • When parsing an expression, an operator which is listed on the same row will be bound tighter ( as if by parentheses ) to its arguments than any operator that is listed on a row further below it. For example, the expression *p++ is parsed as *(p++) , and not as (*p)++ .
    • Operators that are in the same cell (there may be several rows of operators listed in a cell) are evaluated with the same precedence, in the given direction. For example, the expression a=b=c is parsed as a=(b=c) , and not as (a=b)=c because of right-to-left associativity.

    演算子を変更する演算子

    Most operators does not change the operands values, but a few do:

    • Assignment operators change the left-operand value.
    • Increment and decrement operators change the operands value.

    This is why some programmers use constant value on the left operand. E.g.: instead of == for equality comparison, the programmer mistakable use = that is the simple assignment, the compiler will not be able to recognize the problem:

    if(value = 0){} // 💩, It is valid expression for the compiler
    

    To better mitigate risks, exchange the position and the compiler will be able to output a proper error if this mistake happen.

    if(0 = value){} // Compiler output a proper error on this
    

    演算子の代替表現

    <iso646.h> define 11 macros, that are alternative spellings for some operators. Why <iso646.h> ? European keyboards are not programming-friendly. Some programmers argue that this make easy to parse by human eyes when heavy use of bitwise operators is done with comparison operators.

    Symbol Alternative spelling Example
    && and x and y
    &= and_eq x and_eq y
    & bitand x bitand y
    | bitor x bitor
    ~ compl x compl y
    ! not not x
    != not_eq not_eq x
    || or x or y
    |= or_eq x or_eq y
    ^ xor x xor y
    ^= xor_eq x xor_eq y

    References

  • N1256
  • N1570
  • N2596