C Operators
Operator Categories Overview
Operators are symbols that perform actions on values. C has rich operator sets for arithmetic, comparison, logic, assignment, bitwise manipulation, pointers, and more.
Understanding precedence (which binds tighter) and associativity (left-to-right or right-to-left) is crucial for correct results. Note that some symbols have different meanings depending on context, e.g., unary '&' (address-of) vs binary '&' (bitwise AND).
Category | Operators | Examples |
---|---|---|
Arithmetic | + - * / % | a+b a*b a/b a%2 |
Increment/Decrement | ++ -- (prefix/postfix) | ++i i-- |
Comparison | < <= > >= == != | a |
Logical | && || ! | a&&b !flag |
Assignment | = += -= *= /= %= <<= >>= &= ^= |= | x+=2 x<<=1 |
Bitwise | & | ^ ~ << >> | a&b a|b a^b ~a a<<1 |
Ternary | ?: | cond?x:y |
Pointer/Member | & * . -> [] | &x *p s.x ps->x arr[i] |
Other | sizeof, (type)cast, , (comma) | sizeof(int) (double)x a=(b,c) |
Arithmetic & Integer Division
/ between integers truncates toward zero; % gives the remainder (with the same sign as the dividend).
Use parentheses to make intent explicit and avoid precedence surprises.
#include <stdio.h>
int main(void){
printf("%d", 7/2);
printf(" %d", 7%2);
printf(" %.2f\n", 7/2.0);
return 0;
}
3 1 3.50
Prefix vs Postfix ++/--
Prefix increments then yields the new value; postfix yields the old value then increments.
Avoid expressions that modify and also read the same variable without sequencing (e.g., using multiple ++ on the same variable in one expression) — behavior can be undefined.
#include <stdio.h>
int main(void){
int i=3;
printf("%d", ++i);
i=3; printf(" %d\n", i++);
return 0;
}
4 3
Comparison and Logical (Short-Circuit)
Comparison operators produce an int result: 0 (false) or 1 (true). Logical && and || short-circuit: if the result is known from the left operand, the right operand is not evaluated.
Use short-circuit for null checks and guarding computations.
#include <stdio.h>
int main(void){
int x=0;
if (x!=0 && (10/x)>1) { printf("won't print"); }
printf("safe\n");
return 0;
}
safe
Logical vs Bitwise
Don't confuse logical operators with bitwise operators: '&&' and '||' operate on truth values and short-circuit; '&', '|', and '^' operate on individual bits and do not short-circuit.
#include <stdio.h>
int main(void){
unsigned a=0x5, b=0x2; // 0101 and 0010
printf("%u ", a & b); // bitwise AND => 0000 0010 -> 2
int p=0, q=1;
printf("%d\n", p && q); // logical AND => 0
return 0;
}
2 0
Bitwise Operators (Masking and Shifts)
Bitwise operators operate on individual bits—useful for flags, embedded systems, and performance-sensitive code.
Shifts move bits left/right; be careful with shifting negative values (right shift of signed negatives is implementation-defined).
#include <stdio.h>
int main(void){
unsigned char flags = 0;
const unsigned char READ=1u<<0, WRITE=1u<<1;
flags |= READ;
printf("%d ", (flags & READ)!=0);
flags |= WRITE;
printf("%d\n", (flags & WRITE)!=0);
return 0;
}
1 1
Pointers and Member Access
Unary '&' takes an address; unary '*' dereferences a pointer. Use '.' to access a struct member; use '->' when you have a pointer to a struct.
[] indexes an array (equivalent to *(base+index)).
#include <stdio.h>
typedef struct { int x; } Point;
int main(void){
Point p = { .x = 5 };
Point *pp = &p;
printf("%d %d\n", p.x, pp->x);
return 0;
}
5 5
Ternary, sizeof, Cast
Use cond ? a : b for concise conditional expressions (both arms should be compatible types).
sizeof yields the size in bytes at compile time; casting (type)expr converts the value to another type (may truncate).
#include <stdio.h>
int main(void){
int n=5; double d=(double)n/2;
const char* s = (n%2==0) ? "even" : "odd";
printf("%s %.1f %zu\n", s, d, sizeof(long));
return 0;
}
odd 2.5 8
The Comma Operator
The comma operator evaluates its left operand, discards the result, then evaluates and yields the right operand. It has the lowest precedence and left-to-right associativity. (This is different from commas used as separators in declarations/argument lists.)
#include <stdio.h>
int main(void){
int a=0, b=0;
int r = (a=1, b=2, a+b);
printf("a=%d b=%d r=%d\n", a, b, r);
return 0;
}
a=1 b=2 r=3
Precedence & Associativity Quick Reference
When in doubt, add parentheses for clarity.
Level (high→low) | Operators (grouped by precedence) | Associativity |
---|---|---|
Postfix | [] () . -> x++ x-- | Left-to-right |
Unary | ++x --x + - ! ~ (type) * & sizeof | Right-to-left |
Multiplicative | * / % | Left-to-right |
Additive | + - | Left-to-right |
Shift | << >> | Left-to-right |
Relational | < <= > >= | Left-to-right |
Equality | == != | Left-to-right |
Bitwise AND | & | Left-to-right |
Bitwise XOR | ^ | Left-to-right |
Bitwise OR | | | Left-to-right |
Logical AND | && | Left-to-right |
Logical OR | || | Left-to-right |
Conditional | ?: | Right-to-left |
Assignment | = += -= *= /= %= <<= >>= &= ^= |= | Right-to-left |
Comma | , | Left-to-right |