Operators in C
A practical tour of arithmetic, comparison, logical, bitwise, assignment, and other operators in C with runnable Docker examples
Operators are the verbs of C. They combine values and variables into expressions that compute, compare, and transform data. As a procedural, statically-typed language sitting close to the hardware, C exposes a particularly rich set of operators — including bitwise operators that map almost directly onto CPU instructions, and pointer arithmetic that other languages quietly hide.
C’s operators are largely inherited by C++, Java, C#, Go, and JavaScript, so understanding them here pays dividends across the entire C-family of languages. C’s weakly-typed nature also means operators sometimes behave in surprising ways: integer division truncates, signed overflow is undefined, and a non-zero int is “true.” These behaviors are not bugs — they reflect the language’s preference for letting the machine speak directly.
In this tutorial you will work through arithmetic, comparison, logical, bitwise, compound assignment, increment/decrement, the ternary conditional, and the sizeof operator, with a quick look at operator precedence.
A Comprehensive Operators Example
The program below exercises each major category of C operator and prints the result so you can verify the behavior yourself.
Create a file named operators.c:
| |
Running with Docker
| |
Expected Output
a + b = 22
a - b = 12
a * b = 85
a / b = 3 (integer division truncates)
a % b = 2 (modulus / remainder)
x / y = 3.40
a == b: 0
a != b: 1
a > b: 1
a < b: 0
t && f: 0
t || f: 1
!t : 0
m & n = 0
m | n = 255
m ^ n = 255
n << 4 = 240
m >> 4 = 15
c += 5 -> 15
c -= 3 -> 12
c *= 2 -> 24
c /= 4 -> 6
i++ returns 5 (i is now 6)
++i returns 7
max(a, b) = 17
2 + 3 * 4 = 14
(2 + 3) * 4 = 20
sizeof(int) = 4 bytes
sizeof(double) = 8 bytes
Pointers and the Address-of Operator
C exposes two operators that other languages typically hide: & (address-of) and * (dereference). These are operators, not just syntax for declarations, and they let you read and write through pointers.
Create a file named pointer_ops.c:
| |
Run it the same way:
| |
Expected Output
value = 42
*p (deref) = 42
value after *p = 100 -> 100
q[0] = 10, *(q+1) = 20, *(q+2) = 30
A Note on Integer Division and Overflow
C’s weak typing shows up most often around arithmetic:
- Integer division truncates toward zero.
17 / 5is3, not3.4. If either operand is a floating-point type, the result is floating-point. - Signed integer overflow is undefined behavior — the compiler is allowed to assume it cannot happen. Use
unsignedtypes for well-defined wrap-around arithmetic. - Mixing signed and unsigned in a comparison can produce surprising results because the signed value is converted to unsigned. Prefer matching types.
Key Concepts
- Integer division truncates toward zero; use a floating-point operand to get a fractional result.
- Comparison and logical operators produce
intvalues of0or1— C has no dedicated boolean type until_Bool/stdbool.h(introduced in C99). - Bitwise operators (
&,|,^,~,<<,>>) operate on individual bits and map directly onto common CPU instructions, making them cheap and fast. - Compound assignment (
+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=) is shorthand that evaluates the left-hand side only once. - Postfix
i++returns the old value, then increments; prefix++iincrements first, then returns the new value. sizeofis a compile-time operator, not a function — it returns asize_tand never evaluates its operand at runtime.&and*are operators, giving you the address of an object and the value at an address respectively — pointer arithmetic respects the pointed-to type’s size.- Operator precedence and associativity matter: when in doubt, add parentheses — the compiler will not penalize you for clarity.
Comments
Loading comments...
Leave a Comment