Signed vs Unsigned in C: Key Differences and When to Use Each
signed types can represent both positive and negative numbers, while unsigned types represent only zero and positive numbers. This affects the range of values each type can hold and how arithmetic operations behave.Quick Comparison
Here is a quick comparison between signed and unsigned integer types in C:
| Aspect | Signed | Unsigned |
|---|---|---|
| Value Range | Can be negative, zero, or positive | Only zero and positive |
| Default Sign | Yes (default for int) | No |
| Typical Range (int 32-bit) | -2,147,483,648 to 2,147,483,647 | 0 to 4,294,967,295 |
| Use Case | When negative values are needed | When only non-negative values are needed |
| Overflow Behavior | Undefined behavior on overflow | Wraps around using modulo arithmetic |
| Memory Size | Same as unsigned of same type | Same as signed of same type |
Key Differences
Signed integers in C can store both negative and positive numbers because one bit is reserved for the sign (usually the highest bit). This means the range is split between negative and positive values. For example, a 32-bit signed int typically ranges from -2,147,483,648 to 2,147,483,647.
On the other hand, unsigned integers use all bits to represent only non-negative numbers, effectively doubling the maximum positive value compared to signed integers of the same size. For a 32-bit unsigned int, the range is from 0 to 4,294,967,295.
Arithmetic operations behave differently: signed overflow is undefined behavior in C, while unsigned overflow wraps around using modulo arithmetic. This difference is important when choosing the type for variables, especially in loops, counters, or bitwise operations.
Code Comparison
This example shows how a signed int handles negative values and overflow:
#include <stdio.h> int main() { int a = 2147483647; // max signed int int b = a + 1; // overflow int c = -10; // negative value printf("a = %d\n", a); printf("b (overflow) = %d\n", b); printf("c = %d\n", c); return 0; }
Unsigned Equivalent
This example shows how an unsigned int handles values and overflow differently:
#include <stdio.h> int main() { unsigned int a = 4294967295U; // max unsigned int unsigned int b = a + 1; // wraps to 0 unsigned int c = 10; // positive value printf("a = %u\n", a); printf("b (overflow) = %u\n", b); printf("c = %u\n", c); return 0; }
When to Use Which
Choose signed types when you need to represent negative numbers, such as temperatures, balances, or differences. Use unsigned types when you know values will never be negative, like sizes, counts, or bit flags, to get a larger positive range and predictable wrap-around behavior.
Be careful with mixing signed and unsigned types in expressions to avoid unexpected results or warnings.