C Operators - Complete Reference Guide
Master all C operators with detailed explanations, usage examples, and programming best practices for effective C programming.
7 Categories
Comprehensive coverage
Practical Examples
Real-world usage
Precedence Rules
Operator hierarchy
Introduction to C Operators
Operators are special symbols that perform operations on variables and values. C provides a rich set of operators to manipulate data, make decisions, and control program flow.
Key Characteristics
- Operators work on operands (variables, constants, expressions)
- Operators have precedence (order of evaluation)
- Operators have associativity (left-to-right or right-to-left)
- Some operators can be overloaded (used for different operations)
- Operators can be unary, binary, or ternary
Operator Categories
- Arithmetic Operators: Mathematical calculations
- Relational Operators: Comparison operations
- Logical Operators: Boolean logic operations
- Bitwise Operators: Bit-level operations
- Assignment Operators: Value assignment
- Other Operators: Special purpose operators
Important Note About Operators
Operator precedence determines which operations are performed first in an expression. When in doubt, use parentheses () to explicitly define the order of operations.
C Operators Classification
Here is a comprehensive classification of all C operators organized by their operation type:
| Operation Type | Operators |
|---|---|
|
Unary Operators
Operate on a single operand
|
++
--
++ (increment), -- (decrement)
|
|
Arithmetic Operators
Perform mathematical calculations
|
+
-
*
/
%
+ (add), - (subtract), * (multiply), / (divide), % (modulus)
|
|
Logical Operators
Perform Boolean logic operations
|
&&
||
!
&& (AND), || (OR), ! (NOT)
|
|
Relational Operators
Compare values and return Boolean results
|
<
<=
>
>=
==
!=
<, <=, >, >=, ==, !=
|
|
Bit-wise Operators
Perform operations at bit level
|
&
|
<<
>>
~
^
& (AND), | (OR), << (left shift), >> (right shift), ~ (NOT), ^ (XOR)
|
|
Assignment Operators
Assign values to variables
|
=
+=
-=
*=
/=
%=
=, +=, -=, *=, /=, %=
|
|
Ternary or Conditional Operator
Compact if-else statement replacement
|
? :
? : (conditional operator)
|
Complete C Operators Reference
Here is the complete list of C operators with their categories, descriptions, and examples:
| Operator | Category | Description & Purpose | Example |
|---|---|---|---|
| + | Arithmetic | Addition - Adds two operands | int sum = a + b; |
| - | Arithmetic | Subtraction - Subtracts right operand from left | int diff = a - b; |
| * | Arithmetic | Multiplication - Multiplies two operands | int prod = a * b; |
| / | Arithmetic | Division - Divides left operand by right | int quot = a / b; |
| % | Arithmetic | Modulus - Returns remainder of division | int rem = a % b; |
| ++ | Arithmetic | Increment - Increases value by 1 | a++; or ++a; |
| -- | Arithmetic | Decrement - Decreases value by 1 | a--; or --a; |
| == | Relational | Equal to - Checks if two values are equal | if (a == b) { ... } |
| != | Relational | Not equal to - Checks if two values are not equal | if (a != b) { ... } |
| > | Relational | Greater than - Checks if left is greater than right | if (a > b) { ... } |
| < | Relational | Less than - Checks if left is less than right | if (a < b) { ... } |
| >= | Relational | Greater than or equal to | if (a >= b) { ... } |
| <= | Relational | Less than or equal to | if (a <= b) { ... } |
| && | Logical | Logical AND - True if both operands are true | if (a > 0 && b > 0) |
| || | Logical | Logical OR - True if at least one operand is true | if (a > 0 || b > 0) |
| ! | Logical | Logical NOT - Reverses logical state | if (!flag) { ... } |
| & | Bitwise | Bitwise AND - Performs AND on each bit | int result = a & b; |
| | | Bitwise | Bitwise OR - Performs OR on each bit | int result = a | b; |
| ^ | Bitwise | Bitwise XOR - Performs XOR on each bit | int result = a ^ b; |
| ~ | Bitwise | Bitwise NOT - Inverts all bits (one's complement) | int result = ~a; |
| << | Bitwise | Left shift - Shifts bits to the left | int result = a << 2; |
| >> | Bitwise | Right shift - Shifts bits to the right | int result = a >> 2; |
| = | Assignment | Simple assignment - Assigns right value to left | int a = 10; |
| += | Assignment | Add and assign - a += b is same as a = a + b | a += 5; |
| -= | Assignment | Subtract and assign - a -= b is same as a = a - b | a -= 3; |
| *= | Assignment | Multiply and assign - a *= b is same as a = a * b | a *= 2; |
| /= | Assignment | Divide and assign - a /= b is same as a = a / b | a /= 2; |
| %= | Assignment | Modulus and assign - a %= b is same as a = a % b | a %= 3; |
| ?: | Other | Ternary/Conditional operator - Short form of if-else | max = (a > b) ? a : b; |
| sizeof() | Other | Returns size of variable or type in bytes | int size = sizeof(int); |
| & | Other | Address of operator - Returns memory address | int *ptr = &a; |
| * | Other | Pointer dereference - Accesses value at address | int value = *ptr; |
| -> | Other | Arrow operator - Accesses struct member via pointer | ptr->member = 10; |
| . | Other | Dot operator - Accesses struct/union member | obj.member = 10; |
| , | Other | Comma operator - Evaluates multiple expressions | a = (b=3, b+2); // a=5 |
= (assignment), + - * / (arithmetic), == != < > (relational), && || ! (logical), and ++ -- (increment/decrement).
Detailed Operator Examples
#include <stdio.h>
int main() {
int a = 15, b = 4;
printf("a = %d, b = %d\n", a, b);
printf("Addition: a + b = %d\n", a + b);
printf("Subtraction: a - b = %d\n", a - b);
printf("Multiplication: a * b = %d\n", a * b);
printf("Division: a / b = %d\n", a / b);
printf("Modulus: a %% b = %d\n", a % b);
// Increment/Decrement
int x = 5;
printf("Original x: %d\n", x);
printf("Post-increment: x++ = %d\n", x++);
printf("After post-increment: x = %d\n", x);
printf("Pre-increment: ++x = %d\n", ++x);
return 0;
}
#include <stdio.h>
int main() {
int a = 10, b = 20, c = 10;
// Relational operators
printf("a == b: %d\n", a == b); // 0 (false)
printf("a != b: %d\n", a != b); // 1 (true)
printf("a < b: %d\n", a < b); // 1 (true)
printf("a > b: %d\n", a > b); // 0 (false)
printf("a <= c: %d\n", a <= c); // 1 (true)
printf("a >= c: %d\n", a >= c); // 1 (true)
// Logical operators
int age = 25;
int hasLicense = 1;
printf("Can drive? %d\n", age >= 18 && hasLicense);
printf("Is teenager? %d\n", age >= 13 && age <= 19);
printf("Not a teenager? %d\n", !(age >= 13 && age <= 19));
return 0;
}
#include <stdio.h>
int main() {
unsigned char a = 12, b = 5;
printf("a & b = %u\n", a & b);
printf("a | b = %u\n", a | b);
printf("a ^ b = %u\n", a ^ b);
printf("a << 2 = %u\n", a << 2);
printf("a >> 2 = %u\n", a >> 2);
return 0;
}
How Bitwise Operators Work (Positive & Negative)
Bitwise operators (&, |, ^, ~, <<, >>) work on the binary representation of an integer, one bit at a time. For unsigned types, bits are plain binary. For signed int, negative values are stored in two's complement on virtually all modern systems (including C on typical platforms).
One's Complement and Two's Complement Explained
1. One's Complement
Definition: Invert all bits (change 0→1 and 1→0).
How it works: Positive numbers stay the same in one's complement. To get the negative of a value, flip every bit.
Example: 8-bit system, +5 to −5
Example: 8-bit one's complement table (selected values)
| Decimal | One's complement binary | Decimal | One's complement binary |
|---|---|---|---|
| +0 | 0000 0000 | −0 | 1111 1111 |
| +1 | 0000 0001 | −1 | 1111 1110 |
| +2 | 0000 0010 | −2 | 1111 1101 |
| +3 | 0000 0011 | −3 | 1111 1100 |
| +4 | 0000 0100 | −4 | 1111 1011 |
| +5 | 0000 0101 | −5 | 1111 1010 |
| +6 | 0000 0110 | −6 | 1111 1001 |
| +7 | 0000 0111 | −7 | 1111 1000 |
| +8 | 0000 1000 | −8 | 1111 0111 |
This wastes one bit pattern and complicates arithmetic.
One's complement addition (end-around carry):
2. Two's Complement
Definition: One's complement + 1 (flip all bits, then add 1).
- Write the positive number in binary.
- Flip all bits (one's complement).
- Add 1 to the result.
Example: +5 to −5 (8-bit)
Example: +12 to −12
Example: −5 back to +5
4-bit two's complement table
| Decimal | Binary | Decimal | Binary |
|---|---|---|---|
| +0 | 0000 | −1 | 1111 |
| +1 | 0001 | −2 | 1110 |
| +2 | 0010 | −3 | 1101 |
| +3 | 0011 | −4 | 1100 |
| +4 | 0100 | −5 | 1011 |
| +5 | 0101 | −6 | 1010 |
| +6 | 0110 | −7 | 1001 |
| +7 | 0111 | −8 | 1000 |
Notice: Only one zero. Range is −8 to +7 (asymmetric) in 4 bits.
3. Key Differences Between One's and Two's Complement
| Feature | One's complement | Two's complement |
|---|---|---|
| Number of zeros | Two (+0 and −0) | One (0) |
| Range (4-bit) | −7 to +7 | −8 to +7 |
| Range (8-bit) | −127 to +127 | −128 to +127 |
| Negative representation | Flip all bits | Flip bits + add 1 |
| Addition | End-around carry needed | Normal binary addition |
| Used in | Old systems (UNIVAC, CDC) | All modern computers & C |
4. Why Two's Complement is Better
Benefit 1 — No negative zero:
Benefit 2 — Addition works naturally:
Benefit 3 — Subtraction becomes addition:
5. Converting Between Systems
- One's → two's: one's complement + 1. Example: −5 one's
1111 1010+ 1 =1111 1011(two's). - Two's → one's: two's complement − 1. Example: −5 two's
1111 1011− 1 =1111 1010(one's).
6. Practical Examples
Method 1 — Flip and add 1 (−7 in 8-bit):
Method 2 — From the rightmost 1:
Convert negative two's complement to decimal:
7. Overflow Examples (4-bit two's complement)
8. Summary Table (8-bit)
| Decimal | 8-bit binary | One's complement | Two's complement |
|---|---|---|---|
| +5 | 0000 0101 | 0000 0101 | 0000 0101 |
| −5 | — | 1111 1010 | 1111 1011 |
| 0 | 0000 0000 | 0000 0000 or 1111 1111 | 0000 0000 |
| −0 | — | 1111 1111 | does not exist |
9. Quick Reference Formula
Two's complement of n (same as C bitwise NOT + 1 for signed types):
Converting back:
10. Memory Representation (32-bit example)
~, &, |, ^, and shifts on negative values.
Bitwise Operators Theory with Examples (Positive & Negative Numbers)
1. Binary Representation Fundamentals
Positive numbers
Use standard binary positional notation. Example: 5 in 8-bit = 0000 0101
Negative numbers (two's complement)
C uses two's complement for negative integers on typical platforms.
- Write positive binary.
- Invert all bits.
- Add 1.
2. Bitwise AND (&)
Rule: Result is 1 only if both bits are 1.
| A | B | A&B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
Example 1 — positive & positive:
Example 2 — negative & positive:
Example 3 — negative & negative:
3. Bitwise OR (|)
Rule: Result is 1 if at least one bit is 1.
| A | B | A|B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
Example 1 — positive | positive:
Example 2 — negative | positive:
4. Bitwise XOR (^)
Rule: Result is 1 if bits differ.
| A | B | A^B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Example 1 — positive ^ positive:
Example 2 — negative ^ positive:
Example 3 — negative ^ negative:
5. Bitwise NOT (~)
Rule: Flip every bit.
| A | ~A |
|---|---|
| 0 | 1 |
| 1 | 0 |
Example 1 — positive:
Example 2 — negative:
6. Left Shift (<<)
Effect: x << n = x × 2n when valid.
Example — positive:
Example — negative:
7. Right Shift (>>)
- Positive: logical shift, fill with 0.
- Negative: arithmetic shift on most compilers (fill with 1).
Example — positive (logical shift):
Example — negative (arithmetic shift):
Note: Signed >> is implementation-defined in C; most use arithmetic shift.
8. Complete Comparison Table (8-bit)
| Number | Binary | ~Number | << 1 | >> 1 |
|---|---|---|---|---|
| +5 | 0000 0101 | −6 | 10 | 2 |
| −5 | 1111 1011 | 4 | −10 | −3 |
| +12 | 0000 1100 | −13 | 24 | 6 |
| −12 | 1111 0100 | 11 | −24 | −6 |
| +1 | 0000 0001 | −2 | 2 | 0 |
| −1 | 1111 1111 | 0 | −2 | −1 |
9. Quick Reference Formulas
| Op | Positive n | Negative n |
|---|---|---|
~n | −(n+1) | same rule |
n<<k | n×2k | watch UB |
n>>k | floor ÷ 2k | impl-defined |
10. Memory Representation (32-bit)
Try it in C
#include <stdio.h>
int main() {
int pos = 12, neg = -5;
printf("pos = %d (0x%08X)\n", pos, (unsigned int)pos);
printf("neg = %d (0x%08X)\n", neg, (unsigned int)neg);
printf("neg & 12 = %d\n", neg & 12);
printf("~neg = %d\n", ~neg);
printf("neg >> 1 = %d\n", neg >> 1);
return 0;
}
Operator Precedence and Associativity
Operator precedence determines the order in which operators are evaluated in an expression. When operators have the same precedence, associativity determines the order.
| Precedence | Category | Operators | Associativity |
|---|---|---|---|
| 1 (Highest) | Function call, Array subscript | () [] . -> | Left to Right |
| 2 | Unary | ! ~ ++ -- + - * & sizeof | Right to Left |
| 3 | Multiplicative | * / % | Left to Right |
| 4 | Additive | + - | Left to Right |
| 5 | Bitwise shift | << >> | Left to Right |
| 6 | Relational | < <= > >= | Left to Right |
| 7 | Equality | == != | Left to Right |
| 8 | Bitwise AND | & | Left to Right |
| 9 | Bitwise XOR | ^ | Left to Right |
| 10 | Bitwise OR | | | Left to Right |
| 11 | Logical AND | && | Left to Right |
| 12 | Logical OR | || | Left to Right |
| 13 | Conditional | ?: | Right to Left |
| 14 | Assignment | = += -= *= /= %= &= ^= |= <<= >>= | Right to Left |
| 15 (Lowest) | Comma | , | Left to Right |
#include <stdio.h>
int main() {
int a = 10, b = 5, c = 2;
int result;
// Example 1: Multiplication before addition
result = a + b * c; // 10 + (5 * 2) = 20
printf("a + b * c = %d\n", result);
// Example 2: Using parentheses to change order
result = (a + b) * c; // (10 + 5) * 2 = 30
printf("(a + b) * c = %d\n", result);
// Example 3: Complex expression
result = a * b + c / 2 - 1; // (10 * 5) + (2 / 2) - 1 = 50 + 1 - 1 = 50
printf("a * b + c / 2 - 1 = %d\n", result);
// Example 4: Assignment vs comparison
int x, y = 5;
x = y == 5; // First y == 5 evaluates to 1, then x = 1
printf("x = y == 5: x = %d\n", x);
return 0;
}
Tricky Points (All Operator Types)
Interview-style pitfalls grouped by operator category. See bitwise positive & negative above for two's complement detail.
Arithmetic operators
5 / 2 == 2 with integers — use (float)5 / 2 for 2.5.% sign follows the dividend: -7 % 3 == -1, not 2.++i increments before use; i++ after — matters in a[i++] = i;.Relational operators
if (x = 5) assigns; if (x == 5) compares.
==; use an epsilon.Logical operators
&& and || short-circuit — the right side may not execute.0 or 1, not arbitrary non-zero values.Bitwise operators
& is bitwise AND; && is logical AND — not interchangeable in if.~(-5) == 4; for signed n, ~n == -(n+1).>> on negative int is usually arithmetic shift (sign preserved); on unsigned, logical shift.Assignment, ternary, comma, precedence
a += b * c means a = a + (b * c), not (a + b) * c.?: has low precedence — use (a > b) ? a : b.x = (a=1, a+2) sets x to 3.a + b * c is a + (b * c) — use parentheses when you mean (a + b) * c.unsigned for bit masks; == and && for conditions.Key Takeaways
- C provides 7 categories of operators: Arithmetic, Relational, Logical, Bitwise, Assignment, and Others
- Operator precedence determines evaluation order; use parentheses for clarity
- == is for comparison, = is for assignment - don't confuse them!
- Integer division truncates the fractional part; cast to float for precise division
- ++ and -- can be prefix (++x) or postfix (x++) with different behaviors
- Bitwise operators work on individual bits; logical operators work on boolean values
- The ternary operator (?:) provides a compact if-else alternative
- Assignment operators can be combined with arithmetic (+=, -=, *=, /=, %=)
- sizeof() returns the size in bytes of a variable or type