© Mikael Olsson 2019
Mikael OlssonModern C Quick Syntax Referencehttps://doi.org/10.1007/978-1-4842-4288-9_4

4. Operators

Mikael Olsson1 
(1)
Hammarland, Länsi-Suomi, Finland
 

A numerical operator is a symbol that makes the program perform a specific mathematical or logical manipulation. The numerical operators in C can be grouped into five types: arithmetic, assignment, comparison, logical, and bitwise operators.

Arithmetic Operators

There are the four basic arithmetic operators, as well as the modulus operator (%), which is used to obtain the division remainder.
int x = 3 + 2; /* 5 - addition */
    x = 3 - 2; /* 1 - subtraction */
    x = 3 * 2; /* 6 - multiplication */
    x = 3 / 2; /* 1 - division */
    x = 3 % 2; /* 1 - modulus (division remainder) */
Notice that the division sign gives an incorrect result. This is because it operates on two integer values and will therefore truncate the result and return an integer. To get the correct value, one of the numbers must be explicitly converted to a floating-point number.
float f = 3 / (float)2; /* 1.5 */

Assignment Operators

The second group is the assignment operators. Most important, it is the assignment operator (=) itself, which assigns a value to a variable.
int x = 0; /* assignment */
A common use of the assignment and arithmetic operators is to operate on a variable and then to save the result back into that same variable. These operations can be shortened with the combined assignment operators.
x += 5; /* x = x+5; */
x -= 5; /* x = x-5; */
x *= 5; /* x = x*5; */
x /= 5; /* x = x/5; */
x %= 5; /* x = x%5; */

Increment and Decrement Operators

Another common operation is to increment or decrement a variable by one. This can be simplified with the increment (++) and decrement (--) operators.
x++; /* x = x+1; */
x--; /* x = x-1; */
Both of these can be used either before or after a variable.
x++; /* post-increment */
x--; /* post-decrement */
++x; /* pre-increment */
--x; /* pre-decrement */
The result on the variable is the same whichever is used. The difference is that the post-operator returns the original value before it changes the variable, while the pre-operator changes the variable first and then returns the value.
int x, y;
x = 5; y = x++; /* y=5, x=6 */
x = 5; y = ++x; /* y=6, x=6 */

Comparison Operators

The comparison operators compare two values and return either 1 or 0, representing true or false. They are mainly used to specify conditions, which are expressions that evaluate to either true or false.
int x = (2 == 3); /* 0 - equal to */
    x = (2 != 3); /* 1 - not equal to */
    x = (2 > 3);  /* 0 - greater than */
    x = (2 < 3);  /* 1 - less than */
    x = (2 >= 3); /* 0 - greater than or equal to */
    x = (2 <= 3); /* 1 - less than or equal to */

Logical Operators

The logical operators are often used together with the comparison operators. Logical and (&&) evaluates to true if both the left and right sides are true, and logical or (||) is true if either the left or right side is true. For inverting a Boolean result, there is the logical not (!) operator. Note that for both “logical and” and “logical or” the right side will not be evaluated if the result is already determined by the left side.
int x = (1 && 0); /* 0 - logical and */
    x = (1 || 0); /* 1 - logical or  */
    x = !(1);     /* 0 - logical not */
Recall that as of C99, the stdbool.h header can be included to use the bool type to store Boolean values. The header also defines the constants true and false to represent 1 and 0, which allows the previous example to be rewritten as seen here.
#include <stdbool.h>
/* ... */
bool b = (true && false); /* false - logical and */
     b = (true || false); /* true  - logical or  */
     b = !(true);         /* false - logical not */

Bitwise Operators

The bitwise operators can manipulate individual bits inside an integer. For example, the bitwise left shift operator (<<) moves all bits to the left with the specified number of steps.
int x = 5 & 4;  /* 101 & 100 = 100 (4) - and */
    x = 5 | 4;  /* 101 | 100 = 101 (5) - or */
    x = 5 ^ 4;  /* 101 ^ 100 = 001 (1) - xor */
    x = 4 << 1; /* 100 << 1  =1000 (8) - left shift */
    x = 4 >> 1; /* 100 >> 1  =  10 (2) - right shift */
    x = ~4;     /* ~00000100 = 11111011 (-5) - invert */
The bitwise operators also have combined assignment operators.
int x=5; x &= 4;  /* 101 & 100 = 100 (4) - and */
    x=5; x |= 4;  /* 101 | 100 = 101 (5) - or */
    x=5; x ^= 4;  /* 101 ^ 100 = 001 (1) - xor */
    x=4; x <<= 1; /* 100 << 1  =1000 (8) - left shift */
    x=4; x >>= 1; /* 100 >> 1  =  10 (2) - right shift */

Operator Precedence

In C, expressions are normally evaluated from left to right. However, when an expression contains multiple operators, the precedence of those operators decides the order in which they are evaluated. The order of precedence can be seen in the following table, where the operator with the lowest precedence will be evaluated first. This same order also applies to many other languages, such as C++ and C#.

Pre

Operator

Pre

Operator

1

() [] . -> x++ x--

8

&

2

! ~ ++x --x (type) sizeof * &

9

^

3

* / %

10

|

4

+ -

11

&&

5

<< >>

12

||

6

< <= > >=

13

= op=

7

== !=

14

,

To give an example, multiplication binds harder than addition and will therefore be evaluated first in the following line of code.
int x = 4 + 3 * 2; /* 10 */
This can be clarified by enclosing the part of the expression that will be evaluated first in parentheses. As seen in the table, parentheses have the highest precedence of all operators.
int x = 4 + (3 * 2); /* 10 */