Numbers are just bits
A byte is 8 bits, and each bit is 0 or 1. Read as a plain binary number, 8 bits can hold 2 to the power 8 = 256 different patterns, so an unsigned char stores 0 to 255.
00000000 = 0
00000101 = 5 (4 + 1)
11111111 = 255 (128+64+32+16+8+4+2+1)
So what happens if you add 1 to 255? There is no ninth bit to carry into. For unsigned types, C defines the answer: the value wraps around modulo 256, so you get 0. Like a car odometer rolling over.
unsigned char u = 255;
u = u + 1; // u is now 0
(Pedantic detail: u + 1 is actually computed as an int, giving 256, and storing 256 back into an unsigned char keeps only the low 8 bits. Same result, and it is fully defined.)
Signed types are different. Overflowing a signed int is undefined behaviour: the standard makes no promise at all, and optimising compilers really do assume it never happens. Many machines will happen to wrap to a negative number, but you must not rely on it. Use unsigned types when you want wrap-around.
Binary gets long fast, so programmers write bytes in hexadecimal: base 16, digits 0-9 then a-f. One hex digit is exactly 4 bits, so one byte is always two hex digits. 255 is ff, 16 is 10. Print hex with %x, and an unsigned value with %u.
Try it yourself
Edit it. Break it. Run it again.#include <stdio.h>
int main(void) {
unsigned char u = 250;
for (int i = 0; i < 8; i++) {
printf("%u (hex %x)\n", u, u);
u = u + 1;
}
printf("255 in hex is %x, 4096 in hex is %x\n", 255, 4096);
return 0;
}
Your turn
Type it yourself. That is the whole trick.1Odometer rollover
Start an unsigned char called fuel at 250. Add 10 to it, then print it with %u. Predict the answer before you run it. The output should be: 4
#include <stdio.h>
int main(void) {
unsigned char fuel = 250;
// add 10, then print
printf("%u\n", fuel);
return 0;
}
2Speak hex
Print the numbers 10, 15, 16 and 255, each on its own line, as decimal = hex, like this:
10 = a15 = f16 = 10255 = ff
Use a format code for the hex part rather than typing it.
#include <stdio.h>
int main(void) {
printf("%d = %d\n", 10, 10);
return 0;
}