Personally, I found the best way was on a Linux system with two books: the Deitels' C: How to program which is a book about programming that happens to use C, and Matthew & Stone's Beginning Linux Programming which is a terrible book about programming but a very good book about programming in the linux environment, from command line utilities to KDE.
I'm assuming, of course, that you don't have a lot of programming experience. I like the Deitel book because it balances discussion of C syntax and good practice with discussion of thins like linked lists and binary trees, and when/why you should use them. Also, the exercises are varied and interesting.
The Linux book, by contrast, introduces the environment and popular Linux libraries very well, but inexplicably assumes that your primary goal in life is to implement an inventory control system, which is about the last thing I'd use C for.
Thanks for the suggestions. I use Ruby for whatever I need, but I don't really understand all the lower level concepts. I read an article today on HN entitled "Why git is so fast (or why Java is not as fast as C" and it inspired me to find out why C is so important. I thought the best way to do that was learn about it. Bringing me to my question.
Start reading code. Every day, every free moment. Find an app in Linux which you enjoy using or think would be hard to write. Read it from main() to exit().
Choose something relatively self contained so you don't spend all your time trying to understand the libraries. Once you understand the language and its idioms then you can worry about the libraries you need.
read code.
if you don't understand a function, read it's man page.
if you don't understand a type declaration, use the cdecl command (http://linux.die.net/man/1/cdecl) - you may need to install it first.
write code.
make mistakes, read the docs, fix mistakes.
If you already know one procedural programming language, picking up another isn't that hard. Don't worry about the hardcore internals - you'll pick that up over time. Read books like the "Practice of Programming" and "The Elements of Programming Style".
FWIW, when I taught network programming many years ago, I asked my students to write an SMTP or HTTP client in C. It's fairly simple to do, so think of it as an exercise.
Back in 1980 K&R didn't really work well for me beyond the most basic things, the Lions' Commentary on UNIX 6th Edition, with Source Code did the trick, and it will teach you some basic operating system and UNIX things that are still quite useful. A classic, it's a copy of V6 UNIX with (the first really widely distributed one) including a few device drivers with lots of excellent commentary. See http://en.wikipedia.org/wiki/Lions%27_Commentary_on_UNIX_6th... for online copies.
If you like Guy Steele style language reference manuals (e.g. Scheme, Common Lisp, Java) you'll like this; they wrote it for the CMU compiler spinoff Tartan Labs so there would be a rigorous reference.
A little dated, yes, although I guess dosbox and turbo c would help with running the examples. But still one of the best beginner C tutorials ever. His explanation of pointers alone is worth the read.
"The C Programming Language", commonly referred to as just "K&R", is probably one of the best introductions to a programming language ever written. It's short, clear, and concise — even today, 31 years after its first publication, it should be your first stop: http://en.wikipedia.org/wiki/The_C_Programming_Language_(boo...
As previous commenters have said, don't worry about the details early on. Advanced pointer arithmetic tricks and the like are to C what zany metaprogramming tricks are to Ruby: dangerous, and almost always a bad idea — except in those few cases where they're exactly what you need. For your first pass, you can ignore anything that's not obvious. You probably won't need it anyway, and you'll pick the truly important things up with time…
Code on UNIX, preferably Linux, using CLang and a simple text editor to start. The Windows APIs are just plain confusing for beginners, and OS X adds some wrinkles to the compilation process that it's better not to worry about in the beginning. Linux isn't as austere as some of the BSDs, but that makes it an easier platform to learn on. Similarly, while GCC is more common than CLang, CLang has a bunch of features — actually useful error messages, for example — that make it much much easier to deal with. Fancy IDEs like XCode and Eclipse have their place, but are more complicated than they should be for "hello, world"-type exploration. All you really want is syntax highlighting…
Since it sounds like you're coming from Ruby, check out the FFI project: http://github.com/ffi/ffi FFI makes it reasonably easy to call C from Ruby, meaning you can build scaffolding in a language you're comfortable with while you focus on particular bits of C code. Similarly, it's not worth trying to learn the arcana of the C tool stack — make, autotools, etc — all at once, especially if you already know Rake.
Read other people's code. It's probably better to stick to smaller projects at first, especially reasonably modern ones which haven't gone too far off the deep end with the optimization. I don't have any great pointers here, unfortunately — the only thing that comes to mind is that (C) Python has some really nice, well-commented code and .txt files in its source tree, and that MRI Ruby is horrible. The libev API also strikes me as a good example at the moment — but that's probably at least partially because I've been staring at it so much recently…
Once you're feeling reasonably literate, the next step is to read some algorithms and data structures books. It's both a strength and a weakness of C that you essentially always end up implementing your own; even if you don't end up writing a lot of C code, getting a solid footing (or refresher course) in these will help make you a better programmer. After that, you can probably read code with the best of them. If you're still looking for more, I'd suggest maybe "UNIX Network Programming" by Stevens, Fenner, and Rudoff (a good introduction to the sockets API); or "Modern Operating Systems" by Tanenbaum … really, it just depends on what you're interested in.
Good advice, including using clang instead of gcc.
To amplify on my advice WRT to K&R, if you bounce when you hit the arrays and pointers chapter, try another resource (maybe ask someone for help), that chapter just didn't work for me.
13 comments
[ 3.7 ms ] story [ 42.5 ms ] threadI'm assuming, of course, that you don't have a lot of programming experience. I like the Deitel book because it balances discussion of C syntax and good practice with discussion of thins like linked lists and binary trees, and when/why you should use them. Also, the exercises are varied and interesting.
The Linux book, by contrast, introduces the environment and popular Linux libraries very well, but inexplicably assumes that your primary goal in life is to implement an inventory control system, which is about the last thing I'd use C for.
Choose something relatively self contained so you don't spend all your time trying to understand the libraries. Once you understand the language and its idioms then you can worry about the libraries you need.
If you already know one procedural programming language, picking up another isn't that hard. Don't worry about the hardcore internals - you'll pick that up over time. Read books like the "Practice of Programming" and "The Elements of Programming Style".
The best reference manual is C: A Reference Manual by Harbison and Steele, http://www.amazon.com/Reference-Manual-Samuel-P-Harbison/dp/...
If you like Guy Steele style language reference manuals (e.g. Scheme, Common Lisp, Java) you'll like this; they wrote it for the CMU compiler spinoff Tartan Labs so there would be a rigorous reference.
Bluesmoon's suggested books are also excellent.
A little dated, yes, although I guess dosbox and turbo c would help with running the examples. But still one of the best beginner C tutorials ever. His explanation of pointers alone is worth the read.
As previous commenters have said, don't worry about the details early on. Advanced pointer arithmetic tricks and the like are to C what zany metaprogramming tricks are to Ruby: dangerous, and almost always a bad idea — except in those few cases where they're exactly what you need. For your first pass, you can ignore anything that's not obvious. You probably won't need it anyway, and you'll pick the truly important things up with time…
Code on UNIX, preferably Linux, using CLang and a simple text editor to start. The Windows APIs are just plain confusing for beginners, and OS X adds some wrinkles to the compilation process that it's better not to worry about in the beginning. Linux isn't as austere as some of the BSDs, but that makes it an easier platform to learn on. Similarly, while GCC is more common than CLang, CLang has a bunch of features — actually useful error messages, for example — that make it much much easier to deal with. Fancy IDEs like XCode and Eclipse have their place, but are more complicated than they should be for "hello, world"-type exploration. All you really want is syntax highlighting…
Since it sounds like you're coming from Ruby, check out the FFI project: http://github.com/ffi/ffi FFI makes it reasonably easy to call C from Ruby, meaning you can build scaffolding in a language you're comfortable with while you focus on particular bits of C code. Similarly, it's not worth trying to learn the arcana of the C tool stack — make, autotools, etc — all at once, especially if you already know Rake.
Read other people's code. It's probably better to stick to smaller projects at first, especially reasonably modern ones which haven't gone too far off the deep end with the optimization. I don't have any great pointers here, unfortunately — the only thing that comes to mind is that (C) Python has some really nice, well-commented code and .txt files in its source tree, and that MRI Ruby is horrible. The libev API also strikes me as a good example at the moment — but that's probably at least partially because I've been staring at it so much recently…
Once you're feeling reasonably literate, the next step is to read some algorithms and data structures books. It's both a strength and a weakness of C that you essentially always end up implementing your own; even if you don't end up writing a lot of C code, getting a solid footing (or refresher course) in these will help make you a better programmer. After that, you can probably read code with the best of them. If you're still looking for more, I'd suggest maybe "UNIX Network Programming" by Stevens, Fenner, and Rudoff (a good introduction to the sockets API); or "Modern Operating Systems" by Tanenbaum … really, it just depends on what you're interested in.
-sq
To amplify on my advice WRT to K&R, if you bounce when you hit the arrays and pointers chapter, try another resource (maybe ask someone for help), that chapter just didn't work for me.
Then again, pointers and recursion are the two basic hard concepts one needs to learn at this level (see Joel Spolsky on The Perils of Javaschools: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchool...)
Good luck!
Carl is seriously awesome.
http://publications.gbdirect.co.uk/c_book/