If you’re like me, you’ve never studied computer science, or anything even related to technology. You’ve never worked with computers, you’ve barely, if ever, produced a single line of code professionally; you’ve just always been interested – in your free time, as a hobby.
Today, if you’re anything like me, you feel pretty confident in the skills you’ve built up: you can spin up a website in no time, you know your way around a Unix-like operating system, you write clever shell scripts to make your life easier. You run GNU/Linux as your main OS, or perhaps even a variant of BSD.
Yet there is one mountain that you haven’t ever been able to climb. The big one. The capital letter. C.
To people like me, C feels almost mythical: a language that offers unparalleled power for the cost of unparalleled danger. Of course, C isn’t actually mythical; it’s been mythologized – and for people who are forced to learn C anyway at university, this isn’t a problem, but people without any formal education often never get the chance to learn, that after all, C is just another programming language, one that you don’t need any magic method or special knowledge to learn.
Many who give advice on how to best learn C are people who’ve already learned it and have long experience with it. Almost without exception, they tend to recommend reading The C Programming Language by K&R.
I, in constrast, am writing this as I’m just starting to get into C for real, meaning I have begun to feel reasonably comfortable with it and have started to use it as a go-to language for certain tasks. I haven’t read K&R, and if you and I are the same type of person, I wouldn’t recommend you do either.
At least not the whole thing right now. Think about how you learned the other languages you know. What was the first thing you did? To pick up a book? No! You tried to use it. Now think about at which point you felt that you were starting to actually learn the language. For me, it was always when I started using it to write small, useful programs, often ones that I could’ve written in another language, or perhaps ones that I already had written in another language.
None of that changed for C. I’m learning it exactly like I’ve learned all other programming languages. The only thing that has changed is where I look for information. Don’t worry, Stack Overflow is still one of my most important resources, but I complement it with my operating system’s man pages.
Whenever I find an answer to my question on the internet, I check out the man page for every function that I need to call. This makes sure that I never miss anything important, like checking errors or freeing allocated memory. Other times, I’m not confused about specific functions, but about larger concepts. In these cases, I do find it useful to look up the topic in K&R – it’s not a bad book, it’s just that it’s hard to learn something by merely reading and doing irrelevant exercises.
The point of this text is to emphasize that people learn differently, especially if they have different levels of education. While university-educated programmers might learn best from a book, self-taught programmers most likely don’t. This is something to keep in mind when giving advice to people who are learning a programming language or, indeed, when learning one yourself.
There is a difference between programming and driving. Driving, at its heart, is an unconscious activity – you don’t have to think when you’re changing gears; you just do it, even while talking to someone on the phone or listing to the radio – and once you really learn a bad practice, like holding down the clutch pedal into an intersection, it’s very hard to unlearn, because your driving isn’t conscious.
Programming, however, is conscious. It’s an activity in which you have to think in order to act. Unlearning bad practice in programming takes no energy at all apart from that spent being told that the practice is bad and coming to understand and remember it. Once you’ve done that, it’s almost impossible to make the same mistake again.
That’s why you shouldn’t be afraid of learning “along the way”, “as you go” or “in an ad-hoc manner” because “you might learn bad practice”. If you learn the wrong thing, you can learn the right thing later. After all, you’re not a professional programmer. It doesn’t matter very much if you make a mistake; your job doesn’t depend on it.