Skip to content

Chapter 5 of 21

Operators

Master arithmetic, relational, logical, bitwise, assignment, and precedence.

28 minutes 10 quick checksBy Subha Prasad
Lesson 5 of 21Course navigation

Lesson content

Read, practise, then check your understanding

Operators build expressions from values. Every expression has a type, a value or side effect, and rules about evaluation. Clear code uses parentheses and intermediate names when precedence or sequencing is not immediately obvious.

Arithmetic and conversion

+, -, *, /, and % perform arithmetic. Integer division truncates toward zero, and remainder works on integers.

int quotient = 7 / 2;       // 3
double precise = 7.0 / 2.0; // 3.5
int remainder = 7 % 2;      // 1

Signed integer overflow is undefined behavior. Unsigned arithmetic wraps modulo one more than its maximum value; use that property only when it is intentional.

Comparison and logic

Relational operators are <, <=, >, and >=; equality uses == and !=. Logical && and || short-circuit, so the right operand is evaluated only when needed. ! reverses truth.

if (pointer != NULL && pointer->ready) {
    process(pointer);
}

Short-circuiting makes the dereference safe only because the null test comes first.

Increment and assignment

++i increments and yields the new value; i++ yields the old value and then increments. When the yielded value is unused, prefer the style your project applies consistently.

Compound assignments such as total += value evaluate the left operand once. Do not modify the same scalar multiple times without a sequencing guarantee; expressions such as i = i++ + 1 have undefined behavior.

Bitwise operators

Bitwise &, |, ^, ~, <<, and >> operate on integer representations. Unsigned types are usually best for masks.

enum { READ = 1u << 0, WRITE = 1u << 1, EXECUTE = 1u << 2 };

unsigned permissions = READ | WRITE; // set
permissions &= ~WRITE;               // clear
permissions ^= EXECUTE;              // toggle
if ((permissions & READ) != 0u) { /* test */ }

Shift counts must be nonnegative and less than the width of the promoted left operand. Left-shifting signed values can be undefined; use a suitable unsigned type.

Conditional and other operators

The conditional operator chooses one expression: condition ? when_true : when_false. sizeof reports storage size, & takes an address, * dereferences, . and -> access members, and the comma operator evaluates left then right.

Precedence is not evaluation order

Precedence groups tokens; it does not generally decide which operand runs first. Function arguments, for example, have an unspecified evaluation order. Avoid placing dependent side effects in one expression. Parentheses document intended grouping, but only language sequencing rules control when side effects occur.

Knowledge check

Answer every question correctly to complete this chapter.

What is the result of integer expression 7 / 2?
Which operator sets selected bits in a bit mask?
Which operator computes an integer remainder?
What does logical && guarantee about its right operand when the left is false?
Which operator toggles selected bits?
Which operator compares two values for equality?
What does prefix ++i yield?
Which expression tests whether every bit in mask is set in value?
What is true of signed integer overflow?
Does operator precedence generally determine operand evaluation order?

0 of 10 checks passed

Your progress is saved on this device.