1. In Which I Join The Choir

You should definitely learn C:

* You'll learn the memory hierarchy, which is probably the most important thing to know about performant software.

* You'll get 100x better at debugging --- both because you'll have practice, and because most of the tools you use to debug C code work for higher-level languages (gdb is still a better Ruby debugger than Ruby's own debugger).

* You'll be able to bridge Python (or Perl) to almost any library or framework you ever need.

2. In Which I Express Reservations

Don't learn assembly. In my (C and assembly-heavy) career, I've found it works in exactly the opposite direction: you won't really understand assembly until you understand C code. There are mainstream architectures (SPARC and MIPS) that are literally designed as drivers for C compilers.

You'll eventually want to be conversant in assembly so that you can debug faster (when it comes to the runtime, the C language is a flimsy abstraction indeed). But you should let your needs and interests drag you into the machine, just like you should probably learn "Stairway" and "Smoke On The Water" before mastering barre chords and sight reading --- you can have a pretty excellent punk band without ever knowing how to read music.

3. There Are Books

Everyone is going to have an opinion about K&R. What I think you need to know is, it's short and it's dry. I re-read it 6 years into my career and I was surprised at how rich it was; there's a lot of design and data structures material, beyond the core language.

There's a C book that changed my life. It's David Hanson's "C Interfaces And Implementations" (CII). I will now make a case for why it's the first and only book you'll need. You're coming to C from a high-level language. That language is giving you a couple key things you don't realize you depend on:

* Garbage collection

* Lists and hash tables

* Resizeable strings

Almost every major C project contains a site-specific reimplementation of these concepts. CII gives you one --- an internally consistent one, relatively well implemented, and extremely well documented. In doing so, it also teaches you the single most important thing about writing good C programs, which is how to build abstractions around your gnarly code.

The difference between people who know C as a language and people who can actually deliver software in it is resizeable containers (linked lists, dynamic memory allocation, high-level strings, doesn't really matter what the specific is).

The other book you want is "Advanced Programming In The Unix Environment" (or its moral equivalent, "Win32 Programming").

CII is "how". APUE is "what".

Finally, I like (for new programmers) "The Practice Of Programming".

4. What I Did To Get Started

I "knew" C for a while (maybe since I was 13) before I actually started coding in it. Two things got me unstuck.

First, I picked a couple basic Unix APIs and wrote little toy programs around them. If I remember correctly, the first thing I wrote was "who", from "getpwnam(3)", which forced me to do some basic strings and structure pointers.

Second, I wrote network code from a socket tutorial. Sockets are a great thing to get started on; just write a scraper for a service you like, and there's a zillion little problems you'll have to solve that are the same problems you solve in every other program you write.