Adding values, comparing them, logically combining them, and changing their format are all done by operators. The operators covered in this section become the basis for all subsequent sections.
Learning Objectives
- Distinguish between Arithmetic/Relationship/Logic/Assignment/Increment/Decrement/Bit operators.
- Be aware of operator priority.
- Avoid the pitfalls of integer division and type casting.
Why do operators need a separate section?
Although it looks like a familiar arithmetic operation on the surface, there are many pitfalls in C.
- The result of
7 / 2is3(integer division), not3.5. a == banda = bare completely different (comparison vs substitution).- Expressions like
a++ + ++amay have different results across compilers (undefined behavior).
In this section, you will learn in advance why the results are the way they are.
Key concepts
1) Arithmetic operators
| operator | Meaning | Yes |
|---|---|---|
+ - * / |
Four basic operations | 7 / 2 → 3 (integer) |
% |
remainder (integer types only) | 7 % 2 → 1 |
Integer / Integer = Integer, Real / Integer = Real, Integer / Real = Real.
2) Increment/decrement operator (prefix/postfix)
int a = 5;
int b = a++; //Postfix: b is 5, a is 6
int c = ++a; //Potential: After making a to 7, c also becomes 7.
Because the timing is different, it is dangerous to write ++/-- twice for the same variable on one line.
3) Relational operators
==, !=, <, >, <=, >=. The result is 0 or 1.
4) Logical operators and shorthand evaluation
| operator | Meaning |
|---|---|
&& |
AND. If the left side is false, the right side is not evaluated |
|| |
OR. If the left side is true, the right side is not evaluated |
! |
NOT |
if (p != NULL && *p > 0) { /*If p is NULL, *p is not evaluated and is therefore safe.*/ }
5) Assignment operator family
=, +=, -=, *=, /=, %=. a += 3 is the same as a = a + 3.
6) Bitwise operators (reference)
&, |, ^, ~, <<, >>. It is often used in the Embedded/Bit flag.
7) Type conversion (casting)
int total = 95, count = 4;
double avg = (double)total / count; // 23.75
If (double) accidentally promotes one side, the rest will also be automatically promoted by mistake.
See as example
Example 1 — ex01_arith.c: Four basic operations and remainder
int a = 17, b = 5;
Execution result
a = 17, b = 5
a + b = 22
a - b = 12
a * b = 85
a / b = 3 (integer division)
a % b = 2 (remainder)
a / (double)b = 3.400
Key point: The results (3 vs 3.4) vary depending on the same It-s-17/5 data type.
Example 2 — ex02_increment.c: Prefix and postfix difference
a = 5; b = a++; //rearguard
a = 5; b = ++a; //potential
a += 10; a *= 2;
Execution result
Postfix: a=6, b=5
Potential: a=6, b=6
a += 10 -> 16
a *= 2 -> 32
Key point: postfix “use then increase”, prefix “increase then use”. As a result, a is both 6.
Example 3 — ex03_logical.c: Relationships and Logic
int age = 25, has_license = 1;
Execution result
a == b : 0
a != b : 1
a < b : 1
a >= b : 0
Adult and licensed: 1
Minor or No License: 0
Key point: The result of the logical operation is 0/1-and, all non-zero values are treated as true.
Example 4 — ex04_cast.c: The power of casting
int total = 95, count = 4;
double avg_wrong = total / count; // 23
double avg_right = (double)total / count; // 23.75
Execution result
Bad average (integer division): 23.000
Average Correct (Casting): 23.750
(int)3.99 = 3 (truncate)
Key point: Casting to int is truncation, not rounding.
A different perspective — a one-line summary of priorities
High → Low
( ) [ ] -> . (Parentheses/Approach)
! ++ -- (cast) sizeof &(address) (unary)
* / % (multiplication type)
+ - (addition type)
< <= > >= (relationship)
== != (equivalent)
&& || (logic)
?: (ternary)
= += -= *= /= (assignment)
, (comma)
If it's difficult to remember, always use parentheses.
a * b + c is clearer if written as (a * b) + c.
Common Mistakes
- Integer division trap: When calculating the average, write
sum / countand the decimal point disappears. - Confusion between
==and=:if (a = 5)is always true + side effects. - Unknown shortened evaluation: It is safe to put the guard condition first like
if (count != 0 && total / count > 10). - Compare sign There-is/Not-there: When comparing
int -1andunsigned 1, -1 is interpreted as a very large positive number. - Multiple use of
++:a = a++ + ++a;has undefined behavior.
Cleanup
- In arithmetic operations, when data types are mixed, the resulting data type is determined (usually promoted to a larger one).
- integer/integer division truncates the decimal part. Casting is essential for average, etc.
- The result of the Relationship/Logic operator is 0 or 1, and a non-0 value is true.
- Safety guards such as NULL checks can be created with shortened evaluation.
- If ambiguous, specify priority in parentheses.
Try it yourself
cd src
gcc -std=c11 -Wall -o ex01 ex01_arith.c && ./ex01
gcc -std=c11 -Wall -o ex02 ex02_increment.c && ./ex02
gcc -std=c11 -Wall -o ex03 ex03_logical.c && ./ex03
gcc -std=c11 -Wall -o ex04 ex04_cast.c && ./ex04
Application:
- Change the a and b values of
ex01to negative numbers and observe the resulting sign of%. - Predict and check what the results of
(int)(-3.99)will be inex04.