CS50 Week 2 Explained: Arrays, Strings and Ciphers
Week 2 opens up two things. First, what make is really doing when it "compiles". Second, how the computer stores a list of things instead of one value at a time. By the end you'll see that text is just an array of characters, and you'll use that to build ciphers.

Jump to the key moments
- 0:43Reading levels
- 5:49Debugging
- 26:09debug50
- 39:36Compiling
- 1:12:40Arrays
- 1:29:56Strings
- 1:47:57String length
- 2:06:55Command-line arguments
- 2:14:43Exit status
- 2:20:22Cryptography
Compiling is four steps, not one
"Compiling" is shorthand for a pipeline. Preprocessing pastes in the header files you #included. Compiling turns C into assembly language. Assembling turns assembly into machine code. Linking joins your machine code with the libraries you used, such as CS50's. You rarely have to think about it, but it explains error messages like "undefined reference", which is the linker saying it can't find a function you called.
Debugging, three ways
- printf debugging: print the values of your variables at key points and compare what you see with what you expected.
- A debugger (
debug50in CS50's environment): pause the program at a line and step through it, watching every variable change. It's worth learning now, because it pays off every week after this. - Rubber duck debugging: explain your code, line by line, to an object on your desk. Saying it out loud forces you to notice the step you've been assuming.
Arrays
An array is a row of values of the same type, stored side by side in memory and numbered from 0. Instead of score1, score2 and score3, you have one scores array and you write scores[i] inside a loop. That's the design lesson: arrays plus loops remove repetition.
A string is an array of characters
This is the key idea of the week. The word "HI!" is stored as the characters H, I and ! side by side, followed by a special NUL character (\0, all bits zero) that marks where the string ends. That's how a function like strlen knows a string's length: it counts until it hits the NUL. Because characters are numbers underneath (Week 0's ASCII), you can do arithmetic on them. Uppercase and lowercase letters are always a fixed distance apart, which is why the ctype.h helpers like toupper and isalpha exist.
Command-line arguments and exit status
A program can take input as it starts, like ./caesar 13. In C, main receives argc (how many words were typed, including the program's own name) and argv (an array of those words, as strings). A program also reports how it went when it finishes: return 0 from main means success, and anything else means something went wrong. The problem sets expect you to return 1 when the input is bad.
Problem Set 2: what it asks
- Scrabble: score two players' words using letter values and announce the winner.
- Readability: estimate the school grade a text is written for, using the Coleman-Liau index. You count letters, words and sentences.
- One of Caesar, which shifts every letter by a key you pass on the command line, or Substitution, which swaps every letter using a 26-letter key and must reject bad keys.
Where people get stuck
- Readability: the formula wants averages per 100 words, not raw counts. Check which of your values are integers, because integer division (from Week 1) will quietly give you the wrong answer. Test with the sample texts in the spec and compare grades.
- Caesar wrap-around: Z shifted by 1 should become A. Convert a letter to its position in the alphabet (0 to 25), shift it, wrap it with the remainder operator, then convert it back. Keep upper and lower case separate, and leave punctuation alone.
- Substitution's key checks: the key has to be exactly 26 characters, all letters, with no letter repeated. Handle each check separately and test each one.
- Forgetting the NUL: if you loop over a string using a fixed number instead of its real length, you'll read past the end.
Check yourself
How many bytes does the string "CS50" take up in memory?
Five: four characters plus the NUL terminator.
What are argc and argv when you run ./caesar 3?
argc is 2. argv[0] is "./caesar" and argv[1] is "3", a string you still have to convert to a number.
What does "undefined reference to a function" usually mean?
The linker couldn't find the function's code. Usually you've misspelled the name, or you're not linking the library it lives in.
Why does your program return 1 instead of 0 when the key is invalid?
A non-zero exit status tells whoever ran the program, whether that's a person, a script or check50, that it failed.
Curious how AI reads text? Micro LLM shows a small language model learning from its training text, step by step.
Open Micro LLM →