Why every programmer should learn C
- select the contributor at the end of the page -
Before we begin, let me defend the somewhat outrageous title of this article with an analogy: You can make your own bread with a prepackaged mix, a bread machine and some electricity—or, you can assemble the raw ingredients, a mixing bowl, a stout spoon, a dough blade, fire up the oven and get some cardio through kneading. If it’s just fresh bread you’re after, the machine gets you there.
But if you want to understand the underlying process and have the most options when it comes to the final product, you need to put in the effort of the manual method. This is a lot like tackling the C programming language: You have to dig down into the flour and get your hands dusty, but you end up understanding the process at an intimate level.
However, the programmer I’m addressing here is someone who wants to understand programming at a deeper level just for programming’s sake. This is someone who naturally has a desire to become that polyglot programmer.
Originally, I wanted to title this article “Why Every Programmer Should Learn C First,” but I backed away from that. Sure, there are advantages to learning C first; you won’t get seduced by a language like Python and never come back. In fact, if I were teaching high school students, I would almost certainly teach them a higher level language like Python first. Then I would take my best students and teach them C second. If I were teaching a class of electrical engineers, I would probably just start with C. Let’s face it, if they learned Maxwell’s equations, a little pointer indirection isn’t going to induce a lot of angst.
However, I do think there are advantages to learning C first over C++ or Java. When you work in languages like Java, C# and even Python, you immediately start moving away from learning the fundamentals of a programming language and you start learning associated libraries and frameworks. But with C you get a few library calls, you stay focused on the semantics of the language longer, and C often forces you to think harder and deeper about what’s happening under the hood.
C is a middle level language. When people talk about it you’ll hear phrases like “coding to the metal,” or “coding close to the wire.” C is the language of compilers, interpreters, editors, operating systems and embedded programming. When you learn to program in C you almost have to gain an understanding of how programs execute. You know what things like register, stack, heap and memory mapped IO mean. You start to think how much better life would have been if you had been born with sixteen fingers.
Simplicity and speed
C is simple, elegant and wicked fast; it’s compact and efficient. Because C has raw pointers, bitwise operators, and the keywords: extern, volatile, static, and register—meaning you’ll understand more about writing efficient code than you can glean from any higher level language. The only thing that will teach you these things any better is a low level language, and with modern processors I wouldn’t wish assembler on anyone.
C also happens to be demanding, fastidious, finicky and sometimes downright cryptic. You can easily write hard-to-read, difficult to maintain code in C. But, and this is a key point, you don’t have to. Learning to write maintainable code in C will require (and hopefully instill) coding discipline. In most languages fixing syntax errors can border on the trivial. For instance, Ada’s compiler error messages are so good it might as well have just fixed the code for you. Finding and correcting a missing or additional semicolon in C can sometimes be an epic undertaking.
C is not an object oriented language so you don’t get distracted by things like inheritance and polymorphism. I’m not saying these aren’t important concepts, it’s just that you can simplify things a bit by learning straight procedural programming first. In fact, once you've learned C, and written a couple of embedded programs on some single board computers, learning C++ is a natural next step. You will need to get someone to pry your fingers off the macros and preprocessor directives but other than that it will be straightforward. I would be tempted to teach C with a C++ compiler, and just highlight the few differences that weren’t backwards compatible with a strict C compiler.
My final argument for learning C is tied to doing embedded programming. As a programmer I always get a sense of satisfaction when I deliver any working piece of code. Making a computer do what you want can be satisfying. But when I integrate my embedded code with some custom hardware that makes things happen outside of the computer—from moving a robotic arm to generating a precisely timed waveform—I get an incomparable thrill. That thrill only happens because I learned C. Of course, I ended up doing most of my embedded coding in C++ but I still felt that learning C first made it all possible. If you want a fast pleasant way to learn C, Pluralsight has you covered, check out Kenny Kerr’s The C Programming Language in Action.