🧮 Foundations — Before C
Text: ASCII, Unicode & UTF-8
▶ Open the interactive lesson — free, no signupThat garbled text you've surely seen — an apostrophe showing up as ’, an emoji reduced to ??? — happens when two programs disagree about which numbers stand for which letters. After this lesson you'll know exactly how plain English, accents, and emoji travel as bytes, and you'll be armed against a trap that bites almost every new C programmer: one byte is not one character.
Computers only store numbers — so what is the letter 'A'? It's just the number 65, by agreement. That agreement is called a character encoding, and it's the bridge between bytes and human text.
ASCII: the original deal (1963)
ASCII assigns 0–127 to English letters, digits, punctuation, and control codes. The layout is delightfully hackable:
'0'–'9'are 48–57 →digit - '0'converts a digit character to its value'A'–'Z'are 65–90,'a'–'z'are 97–122 → exactly 32 apart, one bit!c | 0x20lowercases a letter- 0–31 are control codes:
'\n'= 10 (newline),'\t'= 9 (tab),'\0'= 0 (the string terminator — hugely important in C)
#include <stdio.h>
int main(void) {
char c = 'A';
printf("'%c' is %d\n", c, c); /* chars ARE numbers */
printf("'%c' + 1 = '%c'\n", c, c + 1);
printf("'7' - '0' = %d\n", '7' - '0'); /* digit trick */
printf("'Q' | 0x20 = '%c'\n", 'Q' | 0x20); /* lowercase bit */
return 0;
}$ gcc ascii.c -o ascii && ./ascii 'A' is 65 'A' + 1 = 'B' '7' - '0' = 7 'Q' | 0x20 = 'q'
🧠 Checkpoint: In C, what does '5' - '0' evaluate to?
- 5
- 53
- '5'
- undefined
Show answer
5 — '5' is ASCII 53 and '0' is 48; 53 − 48 = 5. This subtraction trick converts any digit character to its numeric value.
Unicode: one number for every character ever
ASCII has no é, no 中, no 🎉. Unicode fixes this by assigning a code point to every character in every language — over 150,000 so far, written like U+1F600. But code points are abstract numbers; we still need to store them as bytes. Enter UTF-8, the encoding that won the internet:
- Code points 0–127 (plain ASCII) → 1 byte, identical to ASCII. Every ASCII file is already valid UTF-8!
- Latin accents, Greek, Cyrillic → 2 bytes · CJK characters → 3 bytes · emoji → 4 bytes
Type below and watch each character become bytes:
▶ This spot has an interactive enc widget — open the interactive lesson to play with it.
🧠 Checkpoint: How many bytes does the emoji 🙂 take in UTF-8?
- 1
- 2
- 3
- 4
Show answer
4 — Emoji live at high code points (U+1F642), which need the 4-byte UTF-8 pattern 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx.
For C programmers: a char is one byte, not one character. strlen("héllo") returns 6, not 5, because é takes two bytes in UTF-8. Keep "bytes" and "characters" separate in your head forever.
🧠 Checkpoint: Why is UTF-8 backwards-compatible with ASCII?
- It isn’t
- Bytes 0–127 encode exactly the ASCII characters
- It stores a translation table first
- ASCII files get converted on load
Show answer
Bytes 0–127 encode exactly the ASCII characters — UTF-8 was designed (on a placemat, by Ken Thompson & Rob Pike — the same folks behind Unix and UTF-8’s sibling Plan 9) so single bytes 0–127 mean the same as ASCII.