Memory is just bytes
Your computer's RAM is a long array of bytes. Each byte has an address, starting at 0. That's it. The hardware doesn't know what a "string" is. It doesn't know what a "float" is. It only knows bytes.
Types exist in the compiler's world, not the machine's world.
When you write int x = 42;, the compiler reserves 4 bytes at some address
and stores the binary representation of 42 there. When you read x,
the compiler generates instructions that read 4 bytes from that address and interpret
them as a signed integer. The bytes don't know what they represent. The type decides.
The primitive types
On a 64-bit system (which is what you're almost certainly running), the sizes are fixed. Memorize these. You'll use them every time you think about memory.
int is 4 bytes on
every platform you'll realistically use, but the C standard only guarantees it's
at least 16 bits. If you need exact sizes, use <stdint.h>:
int32_t, uint64_t, etc.
How integers are stored
An int is 4 bytes. The value 42 in binary is 0b00101010.
Spread across 4 bytes in little-endian order (least significant byte first โ what x86 uses):
How floats are stored
Floats use an entirely different encoding than integers. A 32-bit float
splits its 4 bytes into three fields:
For 3.14f: the sign is 0, the exponent encodes 2ยน = 2,
and the mantissa encodes the fractional part of 1.57 (since 3.14 = 1.57 ร 2ยน).
The raw hex stored in memory is 0x4048F5C3.
The problem: most decimal fractions have no exact binary representation.
0.1 in decimal is 0.0001100110011โฆ repeating in binary โ like
1/3 repeating in decimal. The float stores the closest 23-bit approximation.
That approximation error is why 0.1f + 0.2f is not exactly 0.3f.
0.1f + 0.2f == 0.3f is false on every platform.
Compare with a tolerance: fabsf(a - b) < 1e-6f.
The right epsilon depends on the magnitude of your values โ a global
constant tolerance breaks on very large or very small numbers.
double unless you have a reason not to.
A double has 52 mantissa bits vs 23 for float โ roughly
15โ16 significant decimal digits vs 7. The cost is 8 bytes instead of 4.
On modern CPUs, double arithmetic is not slower than float.
Use float for large arrays where memory and bandwidth matter (e.g., GPU work).
There's much more to floating-point: special values (Inf, NaN,
-0.0), machine epsilon, catastrophic cancellation, and the rules for
when the compiler is allowed to reorder float operations.
That all belongs in its own lesson โ see
Floating-point numbers (lesson 12).
Signed vs unsigned
Every integer type has a signed and unsigned variant. The same 4 bytes mean different things:
The visualization
The interactive below shows how different types lay out in memory โ byte by byte. Click any byte to see what it represents and where it sits.
Types don't change the bytes โ they change how you read them.