DEV Community

loading...

C Operators

freethebit profile image Bruno Diniz ใƒป4 min read

TOC


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.

Operator Precedence and Associativity

  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.

Operators That Change Operands

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Alternative Representation of Operators

<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

Discussion (0)

pic
Editor guide