Integer Types
C offers several flavors of integer type — short, int, long, and long long — each intended to give the programmer some control over the range of values a variable can hold and how much memory it consumes. Each of these can also be marked signed or unsigned.
The integer family
Type | Minimum guaranteed width | Typical width (most 64-bit platforms) |
|---|---|---|
| 16 bits | 16 bits |
| 16 bits | 32 bits |
| 32 bits | 32 or 64 bits (platform-dependent!) |
| 64 bits | 64 bits |
#include <stdio.h>
int main(void) {
short s = 100;
int i = 100000;
long l = 1000000000L;
long long ll = 9000000000000000000LL;
printf("sizeof(short)=%zu sizeof(int)=%zu sizeof(long)=%zu sizeof(long long)=%zu\n",
sizeof(short), sizeof(int), sizeof(long), sizeof(long long));
return 0;
}sizeof(short)=2 sizeof(int)=4 sizeof(long)=8 sizeof(long long)=8
Signed vs unsigned, recap
By default, integer types are signed, meaning they can represent both negative and positive values. Adding the unsigned keyword tells the compiler to use the same number of bits to represent only non-negative values, doubling the maximum positive value it can hold. The Signed & Unsigned page covers this distinction, and the undefined-behavior pitfalls around it, in much greater depth.
int a = -5; /* signed: negative values allowed */ unsigned int b = 5u; /* unsigned: only non-negative values */
The standard only guarantees minimums
Fixed-width types: <stdint.h>
When you need a guaranteed, exact bit width — for a binary file format, a network protocol, or bit-level hardware register access — the modern, portable answer is the <stdint.h> header (introduced in C99). It defines exact-width integer type aliases that are guaranteed to be precisely the size their name promises, on every conforming platform.
Type | Guaranteed size | Range (signed) / (unsigned) |
|---|---|---|
| 8 bits | -128 to 127 / 0 to 255 |
| 16 bits | -32,768 to 32,767 / 0 to 65,535 |
| 32 bits | ~-2.1B to 2.1B / 0 to ~4.3B |
| 64 bits | very large ranges, see |
#include <stdint.h>
#include <stdio.h>
int main(void) {
int32_t temperature = -15; /* exactly 32 bits, everywhere */
uint64_t big_counter = 18000000000ULL; /* exactly 64 bits, everywhere */
printf("temperature=%d big_counter=%llu\n",
temperature, (unsigned long long)big_counter);
return 0;
}The integer family, from smallest to largest guaranteed range, is: short, int, long, long long.
The C standard guarantees only minimum widths — never assume int is exactly 32 bits.
Use
sizeof(type)to check the actual size on your platform.Use
<stdint.h>types (int32_t,uint64_t, etc.) when an exact width is required for portability.