C Cheatsheet
Operators
Use this C reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Arithmetic Operators
| Operator | Description | Example |
|---|---|---|
+ | addition | a + b |
- | subtraction | a - b |
* | multiplication | a * b |
/ | division (integer truncates toward zero) | 7 / 2 → 3 |
% | modulo (remainder) | 7 % 2 → 1 |
- (unary) | negation | -a |
+ (unary) | unary plus (no-op) | +a |
int a = 7, b = 2; printf("%d %d %d %d %d\n", a+b, a-b, a*b, a/b, a%b); // 9 5 14 3 1 double d = 7.0 / 2; // 3.5 — at least one operand must be floating-point int neg = -a; // -7
Integer division truncates toward zero:
-7 / 2 == -3,7 / -2 == -3.%result has the same sign as the dividend in C99+:-7 % 2 == -1.
Relational Operators
| Operator | Meaning | Example |
|---|---|---|
== | equal to | a == b |
!= | not equal to | a != b |
< | less than | a < b |
> | greater than | a > b |
<= | less than or equal | a <= b |
>= | greater than or equal | a >= b |
All return int: 1 (true) or 0 (false).
int x = 5; if (x == 5) printf("equal\n"); if (x != 0) printf("nonzero\n"); int result = (x > 3); // result == 1
Logical Operators
| Operator | Meaning | Short-circuits |
|---|---|---|
&& | logical AND | yes — stops at first false |
|| | logical OR | yes — stops at first true |
! | logical NOT | N/A |
int a = 1, b = 0; if (a && b) { /* false */ } if (a || b) { /* true */ } if (!b) { /* true */ } // Short-circuit prevents side effects int *p = NULL; if (p != NULL && *p > 0) { /* safe — *p not evaluated if p==NULL */ }
Bitwise Operators
| Operator | Meaning | Example |
|---|---|---|
& | bitwise AND | 0b1100 & 0b1010 → 0b1000 |
| | bitwise OR | 0b1100 | 0b1010 → 0b1110 |
^ | bitwise XOR | 0b1100 ^ 0b1010 → 0b0110 |
~ | bitwise NOT (complement) | ~0b0001 → all 1s with bit 0 cleared |
<< | left shift | 1 << 3 → 8 |
>> | right shift | 8 >> 2 → 2 |
unsigned int flags = 0b1010; // Set bit 0 flags |= (1u << 0); // flags = 0b1011 // Clear bit 1 flags &= ~(1u << 1); // clears bit 1 // Toggle bit 3 flags ^= (1u << 3); // flips bit 3 // Test bit 2 if (flags & (1u << 2)) { /* bit 2 is set */ } // Extract bits 4..7 unsigned nibble = (flags >> 4) & 0xF;
Always use
unsignedtypes for bitwise ops. Right-shifting signed negative values is implementation-defined.
Assignment Operators
| Operator | Equivalent |
|---|---|
= | simple assignment |
+= | a = a + b |
-= | a = a - b |
*= | a = a * b |
/= | a = a / b |
%= | a = a % b |
&= | a = a & b |
|= | a = a | b |
^= | a = a ^ b |
<<= | a = a << b |
>>= | a = a >> b |
int x = 10; x += 5; // x = 15 x *= 2; // x = 30 x >>= 1; // x = 15
Assignment expressions return the assigned value: while ((c = getchar()) != EOF).
Increment and Decrement
int a = 5; int b = a++; // b = 5, a = 6 (post-increment: returns then increments) int c = ++a; // c = 7, a = 7 (pre-increment: increments then returns) int d = a--; // d = 7, a = 6 (post-decrement) int e = --a; // e = 5, a = 5 (pre-decrement)
Modifying a variable twice in one expression without a sequence point is UB:
a[i] = i++;.
Conditional (Ternary) Operator
// condition ? value_if_true : value_if_false int max = (a > b) ? a : b; const char *sign = (x >= 0) ? "positive" : "negative"; printf("%s\n", (n == 1) ? "item" : "items");
sizeof Operator
sizeof(int) // compile-time size in bytes; type: size_t sizeof(double) // 8 sizeof(arr) // total bytes of array sizeof arr // same — parentheses optional for expressions int arr[10]; size_t count = sizeof(arr) / sizeof(arr[0]); // 10
sizeofis evaluated at compile time (except for C99 VLAs). Never use on a pointer to get array size.
Address and Dereference
| Operator | Meaning |
|---|---|
&x | address of x (pointer to x) |
*p | dereference pointer p |
p->m | member m via pointer (equivalent to (*p).m) |
obj.m | member m of struct/union object |
int x = 42; int *p = &x; // p holds address of x *p = 100; // x is now 100 struct Point { int x, y; }; struct Point pt = {1, 2}; struct Point *pp = &pt; pp->x = 10; // same as (*pp).x = 10
Comma Operator
Evaluates left then right; result is the right operand. Mostly used in for loops.
int a = (1, 2, 3); // a = 3 for (int i = 0, j = 10; i < j; i++, j--) { }
Cast Operator
double d = 3.7; int i = (int)d; // truncates to 3 float f = (float)(1.0/3); // convert double to float void *vp = malloc(10); char *cp = (char *)vp; // cast void* to char*
Operator Precedence (High to Low)
| Level | Operators | Associativity |
|---|---|---|
| 1 | () [] -> . | left |
| 2 | ! ~ ++ -- + - * & (type) sizeof | right (unary) |
| 3 | * / % | left |
| 4 | + - | left |
| 5 | << >> | left |
| 6 | < <= > >= | left |
| 7 | == != | left |
| 8 | & | left |
| 9 | ^ | left |
| 10 | | | left |
| 11 | && | left |
| 12 | || | left |
| 13 | ?: | right |
| 14 | = += -= etc. | right |
| 15 | , | left |
When in doubt, use parentheses. Common pitfall:
*p++is*(p++), not(*p)++.
Common Operator Gotchas
// = vs == (assignment in condition) if (x = 5) { } // always true; assigns 5, probably a bug if (x == 5) { } // comparison // Integer division 5 / 2 // 2, not 2.5 5.0 / 2 // 2.5 // Pointer arithmetic scales by element size int arr[5]; int *p = arr; p + 1; // points to arr[1], not arr[0]+1 byte // Short-circuit: right side may not execute int result = (0 && some_function()); // some_function() never called