views:

2765

answers:

21

I've tried a couple of times to teach myself to program in C using books, but haven't had the patience to progress through all the mundane examples. I have experience of programming in Java, and I'm a good PHP developer, so I find Hello World and generic programs-to-read-from-STDIN aren't really very informative.

I imagine that a better way to learn C might be the hands-on approach - choose an open source project and dig through the source code; have a stab at fixing a bug (even if you're not confident enough to submit the patch back to the maintainer). Many projects out there seem too complex to use as a learning environment though, or use large libraries that muddy the waters when trying to learn how the program works.

What open source projects are good places for novice C developers to learn the language?

Can anyone suggest a better approach to learning C (and explain why it's better)? If you think that reading a book and trying examples is the best approach, why do you think so? Writing your own code is obviously a good way to learn, but only once you've enough knowledge to tackle non-trivial problems, so how do you reach that point?

Learning a new programming language should be fun, not a hard slog through boring examples, so what approach would/did you take to stay interested when learning C-specific ways to do something you've done countless times before in other languages?

+1  A: 

That's essentially how I learned to program so many years ago: I typed in program listings in BASIC from Apple ][ magazines. Once I had the program saved, I could then make small changes and see what happened.

This is probably still a good way to start today, except you don't have to do the detailed typing part. Download something that interests you, and set up your build environment so that it builds cleanly (if what you've chosen doesn't build, either find out why or just choose another project). Make some small changes and run your modified code. Start with simple changes like say putting your name in the help screen.

Good luck!

Greg Hewgill
+4  A: 

PCRE might be interesting to look at: beyond trivial tasks (and useful!), not too complex, still readable, with some interesting trick.

Code of the Lua programming language is interesting, although in the terse style of classical Unix programs... It is a very good example of carefully hand crafted code aiming at high portability (sticking to strict Ansi C).

PhiLho
+2  A: 

Well... there's Linux. And if that isn't exciting enough for you, source is available for both Doom and Quake.

Shog9
Linux is really hideous in some parts.. I lived in net/sched and the wifi drivers for my masters', and I can't recommend it. But the *real* reason not to learn C here is that debugging is *EXTREMELY HARD*.
Anders Eurenius
Debugging? Here i thought he was looking for something to print out on fanfold and read by the fire with a big mug of mulled cider...
Shog9
debugging kernel code may lead to throwing the laptop into the fire...
tloach
+14  A: 

Load up a programming environment and start using the language to solve some problems. You will only learn so much from reading code. To start thinking in the language you need to start trying to solve problems with it.

Tall Jeff
Indeed. My question was about finding a project to work on so that I can start "using the language to solve some problems". Implementing trivial problems doesn't really teach anything. Your advice is sound, but doesn't really answer my question.
Richard Turner
What problem is interesting to you? - I personally like to write programs to programmatically solve common board games or puzzles. A Sudoku puzzle solver, Computer Solitare or Checkers or Scrabble player, etc.
Tall Jeff
A: 

A better approach to learning C is to write your own programs from scratch, in conjunction with tutorials or books.

+10  A: 

I think that your approach is generally good if you have the instinct for it; I learned how to program from examining existing code.

I would personally pick a program that does something you are well familiar with, for example, a game of tic-tac-toe or something that calculates odds for a poker hand. It's easier to understand a program when you understand the domain and the expected outcomes of changing things.

Several caveats that I can think of:

  • There is a common misconception that open source code is necessarily good because everyone can eyeball it. The truth is that in less selective or collaborative open source projects one can simply write bad code that works and put it online. You can find a lot of that on sourceforge. Be careful!

  • Programs rely on a lot of API calls that may not be that important for you too early. Look at the start of the source file. If there are too many includes, might be a bad choice early on.

  • If you're looking at programs that have multiple files, make sure you understand C's separate compilation model.

  • If you are looking at a large program, try to understand its architecture before you examine specific methods. There is usually some document that explains how everything works together.

  • Though you should be able to use command line compilers, if you want to understand the code you may want to use an interactive debugger to step through the code and inspect variables. Visual C++ and Eclipse CPP support are both good choices.

  • Some code is hand-optimized, uses "showoff-tricks", etc. Learn to read through it.

Uri
+1  A: 

As tedious as it might sound. The only way to get good at programming is to start with the basics and keep typing until you can do the advanced in your sleep.

Mike Brown
+1  A: 

I know how you feel. I need to learn Java and I feel impatient reading books about it. But think about it this way: if you (we) don't tediously read through the books now to learn it, you'll only end up tediously beating your head against the wall trying to debug simple problems when you start seriously using the language. It's like anything else. You can take the cost up front when it's relatively low or put it off until later when more cost has accrued on it, like when your time is shorter and more valuable.

Matt Gregory
+4  A: 

You could try the Project Euler website: http://projecteuler.net/

It has 200+ short sharp math problems that lend themseleves to be solved using programming. The length of time it takes your programs to solve the problem is supposed to be < 2 minutes, so for some questions there is a challenge to optimise your algorithm to be sub 2 mins.

Will help you teach yourself in any language.

Seanchán
+3  A: 

I'd recommend getting a good, recommended textbook. Really, a lot of code you'll see looking at open source projects will be

  • crap (ok, it tends to work, which is where the bar is set, but it isn't good study material.)
  • irrelevant. (the good old "textbook example" is precisely that for a reason.)

Also, I definitely feel that "knowing", mastering C means more than to able to use it for the most mundane tasks. (Ok, show of hands: How many of you knew that malloc is guaranteed to return an address divisible by four?) I might not even have used the bitfield feature as often as once a year, but I don't think it would be right to say you know the language if you don't know them.

Another very important thing is to learn the debugging tools. Fortunately, C has a large set of very nice tools:

You'll definitely want to tool up to code C effectively. You'll want to know what's fast and what's slow. There is no way to catch, and, oh, yes: You're the memory management.

Anders Eurenius
A: 

Read, and work through, the Lions's book Commentary on Unix

Rob Wells
Lion's book documents Version 6 Unix. The style of C you'd learn from that predates the standard by more than a decade. I would not - could not - recommend it as a starting point for learning modern C.
Jonathan Leffler
+4  A: 

The Git source code is pretty nice, and nearly all written in C. Some incidental utilities are written in Perl or Python. You can use Git to go back to Git's early simple incarnations, then gradually add patches from the project history to see how things progressed. Bonus: you learn Git.

jfm3
+7  A: 

I'm not sure which books you've been working from, but it doesn't sound like K&R, which is really the first and only place anyone with any previous coding experience should head to learn C.

It's only 250 pages long and you won't have any problems with the first few chapters. A more succinct, clear, and well written guide to any language has yet to be produced. I also agree that the only way to really learn the language though is with the book in one hand and coding a project with the other.

Once you've got the basics under your fingers I'd suggest picking up a copy of "Writing Solid Code" from Microsoft Press. It's a bit dated now in places but much of the advice it gives about not falling into the usual C traps (and C, because it assumes that the coder knows what they're doing has more than most languages) will save you hours in debugging time later if you adopt the techniques advocated there at an early stage.

Finally you should examine why you want to learn C. I think it's a thoroughly good idea, but unless you are heading to C++ and lowish level coding later be aware that it serves the same purpose as a language student learning latin - not essential by any means and rarely used by the majority of coders now in anger - but still the best way to grok your craft.

Cruachan
A: 

I always find graphical things somewhat more interesting to play around.

Personally, I would suggest downloading Qt and starting to have a look at that. You'll be swimming in C++ or JavaScript, so maybe it's not the recipe for learning C. Then again, exactly why do you need to learn C? Take a nice framework and learn the language it utilizes.

akauppi
A: 

I do not think that anyone can provide a perfect answer to your question. If you want to learn by working on an open source project, then one of the most important things is that it is a project that truly interests you. Otherwise, you're going to become disinterested just as quick as you do with books that you have tried reading.

Once you find an application that you really like, you will find yourself much more motivated to learn how it works and to make contributions.

Russell Bryant
+1  A: 

I've found the MAME source code to be an excellent example

BenB
+2  A: 

On the topic of books (and as an alternative opinion to that of Cruachan), I always found "C: A reference manual" by Harbison and Steele a better reference than K&R (herecy, I know, but give it a look.)

Peter Howe
+1  A: 

As a suggestion for a better approach to learning C. Implement a series of small interesting projects, each time doing something that poses a different challenge. Begin with simple problems/puzzles and work up from there. Some examples:
an equation plotter,
open a file, read from standard input, write to standard output, modify the file and save it to disk,
Conway's Game of Life,
a rotating three-dimensional cube.

As Aeon says in answer to the recommended projects for beginning programmers question "The most important thing is that it's a project you're excited about. It should be something you come home from work and spend time hacking on instead of watching the latest episode of Lost. It should be something you're hacking on until you realize you need to go to bed because you have to get up in 5 hours."

If the problem/puzzle interests you enough and keeps you thinking about how to solve it as well as finding out and learning how to do so then you'll be gaining the knowledge you'll need to be able, at some point, to tackle the source code of an open source project.

Rob Kam
+1  A: 

I agree with Uri. A Tic-Tac-Teoe game is a good way to start. It is more involved than a HelloWorld and may be just the right thing to get started with.

This may be at a slight tangent to your original question, but I would also like to recommend Blogging as a good way of learning. Blog as you learn. You can write about what you learned, problems you faced, and how you overcame them. Write as if you are teaching someone. Usually this process alone (writing and teaching) helps you think at a deeper level.

Your blog posts will serve as review notes which you can go back to later. As a good side effect they may also help someone else who plans to learn C.

Parag
+2  A: 

Check out Linus Torvalds' Time tracker It's simple enough and could be a good start.

Also Hacking second ed. has some great deal of explanation how C works.

Dmitriy Kopylenko
+3  A: 

There is a book called Code Reading by D. Spinellis dedicated in learning from reading the source code of Open Source projects. It is not restricted to C, but it has good coverage of it. Most of the context is language independent.

I would say it's difficult for a complete novice programmer to learn a language from reading open source. As the book advocates though, it is essential for any programmer to read the work of others in order to increase the quality of his/her work.

kgiannakakis