Fog Creek Software
Discussion Board

What next after Kernighan & Ritchie?

Joel recommends running through The C Programming Language by K&R as a first step into the world of programming. 

Assuming someone more-or-less started from scratch, worked through that book, and "loved every minute of it", what would you recommend next?  What would your library for the strictly-book-taught programmer look like?  How would it progress?

Wednesday, January 14, 2004

You know when you go to Walmart and they give you a plastic bag and it has a warning on it, something akin to don't stick your head in here because you will sufficate?

This is what will happen to you when you become a programmer.

Good Luck.

Wednesday, January 14, 2004

Start leaning a C language OS API:

Programming Windows by Charles Petzold
Programming Applications for Microsoft Windows by Jeffrey Richter
Win 32 System Programming by Johnson M. Hart

The Unix Programming Environment by Kerningham and Pike
Advanced Programming in the Unix Environment by W. Richard Stevens

The Turning Book Worm
Wednesday, January 14, 2004

Wow, look at that enthusiasm :)

The suicidal urges notwithstanding, I'd suggest learning an OO language.

My normal suggestions to new programmers are to read the Design Patterns book for an understanding of OO design. I think that the material therein would be much more valuable and 'click' better if you already knew an OO language. I consider that book required reading for any programmer.

I, personally, would recommend you learn Java next. I can't recommend a good language book on Java, because I've not read one. I think Java has some features that make it a good start for experimenting with OO programming.

I suggest you pick a project and jump into it. If you're into games, many commercial games have partial or full source available for you to hack on. This is where I started :). This'll be C or C++ work probably, though.

If you want to do applications, I think Java, and Swing are good places to start.

I think it's worth considering that the books I find most valuable are not language books. Sure, a good reference is useful (especially with C++), but if you've book-taught yourself C, you'll probably pick up the language fast. The design principles are what are difficult for me, and I think, most.

Anyway, good books include, in no particular order: Anything by Martin Fowler, anything by Scott Meyers, the Pragmatic Programmer. Knuth's books are informative, if you actully need to know anything about algorithms and analysis thereof.

In general the Addison-Wesly Professional series seems very good, at least as far as what I've seen of it.

Of course, a whole lot of this is OO stuff, because OO is used a lot nowadays, so it may seem a bit opaque, or at least rather abstract if you're coming from a purely procedural C background.

Mike Swieton
Wednesday, January 14, 2004

If you want to go the C++ or Java route, I particularly like Bruce Eckel's stuff - Thinking in C++ and Thinking in Java. Thinking in Java at least is available free on the web, but it's worth it in convienence for the dead tree edition.

Chris Tavares
Wednesday, January 14, 2004

I have slight disagreement with the K&R recommendation.

By far the most readable of the introductory books for the C language were by Stephen G. Kochan.

His website is

I've recommended his books to many beginners, and seasoned programmers in other languages, and never had a bad result.

Thursday, January 15, 2004

Wanabe wrote, "What would your library for the strictly-book-taught programmer look like?  How would it progress?"

Are you strictly a hobbyist or do you hope to someday make a living as a computer programmer?

The most important thing you should know and remember is that there are many different types of programmers in this world.

Most so called professional programmers that I know spend a lot of their time learning as much as they can about database application programming simply because this skill tends to pay their bills. Learning as much as you can about object-oriented software development, Windows desktop (GUI) development, web development, etc. MIGHT be very important things for you to learn as well.

Again, before anyone can recommend books they found to be useful you have to tell us what your goals are.

One Programmer's Opinion
Thursday, January 15, 2004

The next book I'd read is "Writing Solid Code", which is all about how to not shoot yourself in the foot with C.  If you're going to use C, get in good habits right now while you're still young and malleable.  :)

Eric Lippert
Thursday, January 15, 2004

shut yourself into a cupboard for 3 weeks with the lights off and teach yourself to type by feel.

perfect practice for being a programmer.

old before my time
Thursday, January 15, 2004

There are numerous types of programmers.  If you want
to do web stuff, Java and/or C# is good, and you'll need
to pick whether you want to focus on Windows or Linux
(if Linux, Java is better).  Also, be warned that there is
an alphabet soup of acronyms standing variously for
different API's, protocols, formats, and scripting languages
that need to be mastered to be gainfully employed in this
field, and the soup is stirred every few weeks.

If you want to do embedded or device programming
(which is what I do nowadays), get Really Good at C
(not C++), learn at least one assembly language, and
learn about programming in resource-constrained

Knowing OO methodologies and design patterns is good,
and help even in non-OO languages like C and assembler,
but don't be overly religious about them unless you want to
be a consultant :)

Thursday, January 15, 2004

One slightly off-topic remark. The question was posed hypothetically. If you're *not* actually in that situation -- if you haven't gone through K&R yet -- then I'd suggest that you begin your study of programming with a language that takes care of more of the fiddly bits for you. Python is my favourite for this purpose. You'll need to learn C, or something like it, later, but I'm not convinced it's the best way to start. Anyway, in what follows I'll accept your premise: you've read through K&R, loved every minute, and want to know what to do next. If K&R was your first programming book and you loved every minute, then (as it's pretty dense) it's a fair guess that you're significantly smarter than the average programmer, and I'll make that assumption in my recommendations.

Good next steps:

1. Write some code. Pick something that interests you and that doesn't need anything beyond K&R (i.e., no fancy graphics, audio, etc). Learn by doing. Keep on doing this.

2. *Read* some code. Unfortunately, most of the code that's available for reading is pretty bad, and some of the good stuff is rather old-fashioned. (What constitutes good code is a little different now that it's usually not necessary to squeeze every last cycle out of your run time and every last byte out of your memory use.) There are a few book-length "literate programs" out there, interspersing code and explanation. Knuth's "TeX: the program" and "Metafont: the program" are classics but perfect examples of what I said about old-fashioned-ness. Knuth's a genius, but you don't necessarily want to learn to write code just like his :-). A more recent book-length literate program that might be worth a look is "A retargetable C compiler" by Fraser and Henson. You'll find it heavy going, though probably not nearly so heavy as Knuth; but it's pretty nice code, written in C, and well explained. And it does something more than averagely interesting. On a smaller scale, there are tons of open-source software projects out there. These have the advantage that you can actually get involved in writing the code, too. Unfortunately, as I said, most of it isn't all that great code. Still, you can learn from bad code too, and if you pick a project that's produced something useful then the code can't (by definition, almost) be *all* bad.

3. Learn some more languages. Preferably ones that are quite different from C. "A programming language that doesn't change the way you think is not worth learning", as Alan Perlis once said. Someone suggested Java; that might be a good bet if you're wanting to become as employable as possible as soon as possible (C# might be about as good from that perspective, and is a similar language in many ways). But Java is a little too similar to C; you'll learn new stuff, but not as much as you might from learning something more different. Consider learning a dynamically typed language like Python, a functional language like Haskell, a language with somewhat different syntax like Smalltalk or some variety of Lisp, or something really far out like Prolog or Forth or J. (My personal favourite language, which happens to be quite different from C, is Common Lisp.) If anyone tells you you should learn C++ next because it's easy to learn if you know some C, never listen to their advice ever again. You may want, or need, to learn C++ at some point, but leave it until you are expert in C and have some exposure to nicer object-oriented languages. (And when you do learn it, bear in mind that it's *not* best thought of as a slight variation on C.)

I can't agree with the suggestion to get to grips with an OS API next, especially in the kind of depth you'll get from Petzold or Stevens. That should come later. (And Windows, at least, is not generally best written for using C these days.)

Book recommendations:

"The Pragmatic Programmer" is very good. If you read it next after K&R, then you'll want to come back to it later when you have more experience.

Steve McConnell's "Code Complete" isn't bad. The title is misleading; it should be "Introductory programming using C-like languages" or something of the kind. But there's a lot in there that you'll probably find useful.

"Programming pearls" (not under any circumstances to be confused with "Programming Perl") is a very nice book, perfectly accessible to someone freshly graduated from K&R.

Knuth is wonderful but only if you're something of a mathematician and have a liking for details. It's a bit out of date in places, too. If you want a good book on algorithms then I'd recommend Cormen/Leiserson/Rivest. (I think the second edition has a fourth author, but I forget who.) One volume rather than three, bang up to date, reasonably priced, clearly explained. It's a bit mathsy, but in a book about algorithms that's a *good* thing.

At some point you should read Meyer's "Object-oriented software construction". (Don't confuse him with Scott Meyers, who writes good books about C++.) I would recommend waiting until you have some more experience; in any case, be aware that some of the things he puts forward as fundamental principles are better described as his prejudices. On the whole, he has a pretty good set of prejudices.

"Design patterns" (mentioned by an earlier poster) is good, but it's another one to read quite a bit later.

If you're intending to make a career of software development then you'll need to have some understanding of software project management. "The mythical man-month", although it was written 25 years ago or thereabouts, is still well worth reading. Later on, Steve McConnell's "Rapid development" contains a lot about handling schedules. It's not what you'd call exciting reading, though, and it's another one to read later rather than now. (And, like his "Code complete", it has a slightly misleading name.)

A controversial classic: "Structure and interpretation of computer programs" by Abelson and Sussman. Some people report that this book blew their mind. Some people find it unreadably dense. All its examples use the Scheme language (which is very unlike C), but it's not primarily a book *about* Scheme. In view of my advice to learn a bunch of other languages, you'll guess that I don't view this as a problem.

If you try that last one and like (or, at least, can tolerate) the language then you should *definitely* read Peter Norvig's "Paradigms of artificial intelligence programming", even if you're not all that interested in artificial intelligence. It's all in Common Lisp, whose syntax some people find unbearable, but there's a whole lot of beautiful code in there, besides much else that's good. It's one of the best programming books ever written.

Gareth McCaughan
Thursday, January 15, 2004

I would highly recommend "The Practice of Programming", by Kernighan & Pike.  Good book no matter what area of programming you intent to study.

Thursday, January 15, 2004

For Gosh's sake, yes, learn C and learn about the fiddly bits.  It will help you later.

After that, I'd suggest sampling a bunch of languages to see what you like:

C++ or Java (For OO)
Perl (For Power)
Visual Basic or Delphi (For Visual Power)
SQL (The business world is driven by databases)
HTML, Javascript, and web-stuff

---> Then you should knowwhat you 'like', then start growing in that direction.  By a professional magazine for that language, buy and intro book on that langauge, go to you local college, and take a couple SOFTWARE ENGINEERING courses at night.


You'll need to learn about project management, specifications, testing, source code control, release management, estimates --- things that technology and 'true CS' courses just don't have.

As an alternative to taking SE courses (some schools don't offer them), you could read pragmatic unit testing, pragmatic version control, and the pragmatic programmer, along with a couple of XP books.

good luck!

Matt H.
Thursday, January 15, 2004

After K&R you should read Software Tools in C, by Kernighan.

Simon Lucy
Thursday, January 15, 2004

I just want to second what Gareth McCaughan says.

I've read all the books he suggests bar the last AI one,  and they'd be exactly the kind of thing I would recommend.  He saved me the typing!

David B. Wildgoose
Thursday, January 15, 2004

Expert C Programming (the ugly fish book) by Peter Van Der Linden.

Thursday, January 15, 2004

I will take for granted that you are not desperate to get a programming job in 3 months or less (in which case, just learn Java and join the ranks of worthless chimps) but rather that you would like to spend some time and effort becoming a superb programmer and a respectable human.  :-)

I very nearly skipped Gareth McCaughan's post when I read the remark about ignoring the fiddly bits.  I'm glad I read on anyway, because, Wannabe, you should make sure to grab his post and print it out.  He's given you a superb pile of recommendations.  But if you hope to be a great programmer, you'll be best served by laying a little groundwork *before* you dive into Gareth's post.

Don't skip the fiddly bits!  Master the fiddly bits.

Fiddly bit 1:  Programmers who don't deeply understand the computer itself will always be second-rate.  Your understanding of the computer will inform and moderate your prejudices as you progress through the programming canon.  Learn how computers work.  Understand processors, memory, and the like.  Java, Perl, Python, LISP, modern C++, Ruby, and C# will all be fine languages to learn in due course.  You'll definitely want to learn about data structures and algorithm analysis *before* diving into all sorts of languages.  But first understand the computer.  Learn an assembly language (and through that, a machine language) at least at a rudimentary level.  Understand the processor.  No need to become an expert assembly programmer, unless it thrills you.  Just get a solid sense for instruction sets and memory manipulation at that level.  If you're learning on an Intel PC, as most folks do these days, then find a copy Murray and Shoemaker's The IBM PC from the Inside Out.  I don't know if it's still in print.  I don't know if there's anything like it for the Mac.

Fiddly bit 2:  Aside from C, which is in some sense not much above assembly language, most languages will manage memory for you.  This is really nice for large-scale programming, letting you focus on the application problem.  Still, if you ever want to work in systems programming, you'll be managing memory yourself, so you ought to get a solid grounding in it.  Dream in pointers before you enjoy the Kool-Aid of garbage collection.  Love the stack.  Again, knowing about this fiddly bit of memory management will also solidly inform your later learning.

Then dive into Gareth's post. Maybe also visit a university library and randomly pull really old issues of Software Practice and Experience, Communications of the ACM, Dr. Dobbs, and other things you find on those same shelves.  I always find univerity libraries inspiring.

A few things you'll eventually want to learn, but not just yet...
Do not approach Object Orientation until you understand non-OO programming.  OO is a rich and thick school of thought, and a seductive way of programming that you might never stray from once learned.
Do not begin with Windows GUI programming.  It's ugly and messy, though very practical job-wise.
Do not believe people who say the Unix OS is elegant.  It's merely old, though eventually necessary.

Do not just emulate what you see in open source.  It's mostly crap.
Do not just emulate what you see in books.  It's oversimplified to elucidate a specific point.

Understand that many, many programming authors have not been paid to deliver real software in a very long time, if ever at all.  Learn from them, read all you can get your hands on, their work is indispensable, but know that you'll only become a great programmer by programming incessantly, and your programming will inform your reading.

Have fun!  Software is one of the richest areas of creative endeavor I've found.

Thursday, January 15, 2004

Just a word about those fiddly bits :-). I'm not saying that they aren't important. To be a good programmer, you need to be able to cope with them. I'm saying that the particular fiddly bits that C makes you pay attention to and some other languages don't are ones that a new programmer would do well to avoid having to worry about until they've got a good solid conceptual foundation laid. Once you've got that foundation: yes, yes, yes, learn the fiddly bits. Not just the fiddly bits C forces you to think about, but others too: how a typical modern machine's memory hierarchy looks, why pipeline stalls are bad, how floating-point operations really behave, and so on.

I understand that some people prefer to master the low-level fiddly bits first. That's not a silly point of view, but it isn't mine either. I think it's better to get the hang of thinking algorithmically and writing clean code first, and only then worry about all the tricksy details that make it harder to see what's going on.

Gareth McCaughan
Thursday, January 15, 2004

One of the "fiddly bits" that most higher level languages mask are pointers.

The concept of pointers/references are perhaps the most important thing a good programmer has to deal. Understanding the difference between "this is a reference/pointer to that", "this is a copy of that" and even "this is that" is very important and useful is almost all languages.

I second about studying algorithms -- you don't have to delve deep if this is just a hobby, but at least understanding O-notation (so you can choose between two libraries/functions) and the operation of some basic data structures gives a very good base for all the rest.

Thursday, January 15, 2004

Most people seem to cope fine with pointers so long as they stay that way and they don't have to do anything with them.  Its when you start dereferencing, managing pointers to pointers etc, etc that you see their eyes glaze over.

Simon Lucy
Thursday, January 15, 2004

Understanding pointers means three different things. First, understanding object identity. You'll get that even in a very high-level language where such words as "pointer" are never uttered. (Random example: start up Python; say a=[1,2], then b=[a,a,a], then a[0]=99; look at b.) It's still a bit of a "fiddly bit" but I agree that it's an essential one that you can't really understand programming without. But you don't need to program in C in order to run up against it.

Second, explicit pointer types. In C you have separate types T and T*, whereas in higher-level languages you typically have (for any given type) either something-like-T or something-like-T* but not both. There *is* important insight to be had from contemplating that, but I don't see that it's necessary to do it with one's first language.

Third, understanding pointer arithmetic. This is moderately cool stuff and you'll be a better programmer if you do it well, but it's not *fundamental* in the same way as object identity is. I don't think a new programmer will be damaged by ignoring it for a while.

(For C++ programmers, there's a fourth issue, related to the first two but distinct from them: getting to grips with the conflation of variables and objects that afflicts C++. You need to get the hang of that very thoroughly if you use C++, but it's about the only language that behaves that way. I don't think anyone has been proposing that new programmers need to spend time on it, and I'm mentioning it only for completeness.)

Gareth McCaughan
Thursday, January 15, 2004

> Second, explicit pointer types.

This is the point I see with more importance. I would agree with your comment about first language, but by the tone of the OP, I think he would benefit from having this kind of insight from the start.

> First, understanding object identity.

I put this second, because I think this is a good point for having explicit pointer types first, having implicit references (as your Python example) can be a little confusing. At least with an explicit syntax for pointers you know where this could happen and where not.

Thursday, January 15, 2004

I agree with Gareth McCaughan that their is room to argue about where to begin a programmer education.

Learning is always best when starting from the basics.  I think it really comes down to which you consider to be most basic to computer programming.  Is it the computer or the human scale view of program structure and data organization?  If we trust the history of the field and the order it developed, I think that question becomes slightly less debatable.

One of the dangers of starting programmers on a language with automatic memory management, is that once you get comfortable with thinking in those terms, it can be frustrating to give up long enough to learn how computers actually work.  I think few actually ever do so.  It's rather hard to avoid learning the higher-level topics eventually,  so we need not fear that.  I've meet many people who posess a raw aptitude for programming, who never actually learned the fundamentals, and that lack harms them greatly.

Thursday, January 15, 2004

My absolutely biggest tip is: Be a nerd. Have fun. You have the Internet! The web is filled with free software and its code. Have fun!

Learning programming from a book is just like ... well, you'll want a lot of books too, just let your interests guide you to which ones.

If you absolutely want some guidance where to go next, here's some ideas: network programming! drivers for an old unsupported printer/modem/something! compilers! viruses! 3d space flight!

Jonas B.
Thursday, January 15, 2004

Read C*O*D*E by Charles Petzold

Understanding thy enemy (the computer) allow you to slay them.


Buy it:

Petzold website:

As one of my friend, a high-ranking SysAdmin at an international telephone company recently coming out of bankrupcy, said:

"This is the MOST PERFECT Computer Engineering Intro Book."

I would take it a step further:  "This is the MOST PERFECT Computer Intro Book for those who want to make a career out of computer development and engineering."

I loaned the book to him, and he refused to give it back, the bastard. ;-)  So I bought another copy.  One other thing -- He used to tinker with assembly on the Apple IIgs and earlier, and this book still taught him quite a few new things.

Thursday, January 15, 2004

"How to Think Like a Computer Scientist":

Everyone (all living humans) should know a strongly typed, dynamically typed language like python. Then again, I may be severely biased.

fool for python
Sunday, January 18, 2004

*  Recent Topics

*  Fog Creek Home