Learn C the Hard Way: A Clear & Direct Introduction to Modern C Programming by Zed Shaw
My rating: 3 of 5 stars
It is time to review another book I just finished, but as you will find out, I wasn’t as pleased with this one as with the previous books I read. As always, it is a direct copy of my review found on Goodreads. Please enjoy.
The main reason I picked up this book was because I wanted some background knowledge about C after going through Stroustrup’s C++ introductory piece Programming and Principles, which I hoped would reveal (some of) the reasons behind the design choices made while creating C++. Also, the table of contents of this book was promising, as it seemed to fill in some gaps quite well that were left by Stroustrup’s book, like macros, build systems, unit testing, etc. So I went and bought the book and started to read it with quite the enthusiasm, but this enthusiasm was unfortunately eroded away step by step as I was going through it. I must stress here, that I really wanted to like this book, but I can’t say that I feel that way any more.
The book starts pretty promisingly, as it introduces you to some of the basic C syntax, and then it gradually builds on previous chapters with some rather good and challenging extra exercises. But as you are progressing through chapters, the quality seems to deteriorate. The first problem comes with misaligned (if compared to the text) or completely missing line numbers for code, which issue persists throughout the entirety of the book. Later, “misaligned chapters” and “misaligned exercises” appear as well. Sometimes I was really wondering if some of the chapters (and/or exercises) were in the right position, or if they were needed at all. Code quality also seemed problematic a few times, especially after reading R.C. Martin’s Clean Code and R. Osherove’s The Art of Unit testing. I was also wondering about the choice of topics and the amount of explanations presented from time to time, but that, I know, is highly subjective.
So let’s go into some specifics. The line number issue is pretty straightforward, so I’ll just skip that and continue with “misaligned chapters and exercises”. At the end of each chapter there are some exercises that are meant to make the information mentioned in the chapter sink in better, and a lot of them does a pretty good job at that at first, but later some exercises start to require of you to use and do things that will only be explained in the next chapter. Here one could really wonder which of the two is unnecessary, as if you manage to figure out the solution, then why do you need the next chapter, but if you have a chapter for it later, why require something like that beforehand?In an other instance, some highly interrelated topics (types of data structures) are fragmented because of some wedged in chapters.
Code quality also seemed to be an issue sometimes, as it went against what is considered to be good coding practice nowadays, at least according to the rather logical views of Uncle Bob. He clearly stated, that code must be as easily readable and comprehensible as possible, but this rule seems to be violated frequently in this book. Some examples include ambiguous variable naming, incomprehensible name abbreviations, being “too smart” about code (which is shorter to type, yes, but longer to understand), inconspicuous declarations (midfile single line macro definition hidden between large functions), etc. Some other type of code problems seemed to arise in makefiles and unit tests as well, like questionable variable assignment types (= vs :=) in the former, and interdependent unit tests (order of execution dependency) in the latter.
As mentioned before, I also had some issues with the topics themselves and the amount of explanations used. The title of this book says “Learn C the hard way”, but interestingly enough only some part of the book deals with C itself, which I actually liked at first, but only at first. Initially, after getting through some necessary language basics, the book starts to introduce you to debuggers, makefiles, bash scripting, directory structures for development, programmer mindsets, unit testing etc., which I think is great, since you have to know what to do with your code after you wrote it.
But the problem with these are, is that the amount of explanation provided seems to be too short for most of the topics and the complete lack of figures in the book doesn’t help either. Breaking the presented code down line by line will make one understand what the presented code does, yes, but it will not teach you how to write something, especially if design choices are not discussed at all. A good example of this is makefiles. There are two chapters about it, but apart from knowing what the presented makefiles do, I honestly couldn’t figure out why the makefiles were written the way they were, because no background information was provided at all. And this is just one example, but the same could go for algorithms, data structures, unit testing, etc.
So the general consensus seems to be, that the author basically cherry picked certain parts from larger topics that made it possible to be able to progress from topic to topic, and then put these parts in the book with only short explanations that never go outside the boundaries of the presented code. And this is where I think it mostly fails as a teaching book. I literally had to spend at least half the time reading external resources to get enough background information about all the stuff. A few helper figures could’ve helped here immensely, just as every other resource I found used them (for a good reason).
What is even more puzzling, is why only certain data structures and algorithms were discussed and why many others were simply mentioned in a few words (directed to wikipedia basically) or omitted entirely. It must be stressed here, that a considerable amount of the book deals with these things, but what is presented here, is highly selective. So are these chapters needed at all in this fashion? Could these pages have been filled with better content (like having more on makefiles, translation units, gdb, gcc flags, etc.)?
Considering, that this book was meant to teach people, I think conveying information as smoothly as possible should be priority #1. I honestly think that the basic concept around which the book was made is really good, namely trying to be a hands on manual for people who want to program using C, but the implementation unfortunately is not really good. If one has to constantly read immense amounts of outside resources, then what is this book trying to achieve really?
To whom would one recommend this book and for what reason? Is it a hands on manual for C programming? Not really. Is it a data structure book? No. Will you learn some neat compilation tricks? Nope. Some nice debugging wizardry maybe? Nay. Maybe know about a nice set of recommended libraries you can use? Negative. So as you can see, I have a really hard time recommending this to anyone, as I just can’t figure out what the major discussion topic is. If I was really forced to say something anyway, I’d say it is some C with some makefiles with some unit testing with some data structures with some algorithms with some programming advises with some explanations.
So all in all, even if you buy this book, you most certainly will not loose anything by going through it, but I can think of better resources (which are also free in many cases) to gain knowledge about the topics presented in the book.
Thanks for reading.