Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am a professional developer who generally uses high level, memory managed languages. However, I am growing more and more ashamed at my incompetence at low level languages like C, which I haven't used since my Systems courses in college.

I want to relearn some of the more distinct parts of the C language, but I don't have a large amount of time to devote to hobby work. What are some small projects that would highlight the low level aspects of the language to help me rekindle my knowledge?

share

migration rejected from stackoverflow.com Jun 17 at 9:22

This question came from our site for professional and enthusiast programmers. Votes, comments, and answers are locked due to the question being closed here, but it may be eligible for editing and reopening on the site where it originated.

closed as off topic by Anna Lear Dec 17 '11 at 4:27

Questions on Programmers Stack Exchange are expected to relate to software development within the scope defined by the community. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about reopening questions here.If this question can be reworded to fit the rules in the help center, please edit the question.

3  
On the same boat here; working through code in C Interfaces and Implementations book. –  binil Mar 27 '11 at 7:41
show 1 more comment

26 Answers

Project Euler is good for learning CS math, but there's other things that might be a little more immediately practicable. Here are the most useful assignments I recall from undergrad:

  • Implement all your favorite data structures: linked list, binary search tree, binary heap, chained hash, quadratic probing hash, etc. Build a string->string dictionary as an RB tree, a treap, and a hash.
  • Write a memory allocator. Get eg a big 16mb chunk from the operating system, then write your own versions of malloc() and free() that work entirely inside that. Make sure it can handle allocations of arbitrary sizes -- not just char and int, but strings and structs. Boundary tag allocation is probably easiest. For bonus points, use this malloc() for the assignments above, to make sure it really works.
  • Count the number of occurrences of each word in the collected works of William Shakespeare. Provide functions to print these sorted in alphabetical order or by count.
  • Here is libtiff. Write a program that shrinks an input image to half its size.
  • Write your own toy filesystem. Get a big 1gb file from the OS, pretend that is a blank disk and that you are the operating system, and then write your own fopen(), fwrite(), etc.

Each of these was a one week homework assignment, iirc, with the exception of the filesystem which was a little more work.

share
4  
Only one worth adding would be something along the lines of implementing a basic TCP stack over UDP. Since you did not hit anything networking. –  Chris Mar 27 '11 at 22:35
show 2 more comments

Buy the K&R book, do the exercises. You'll (re)learn all you need about C, and a lot about CS too. Skip to the later chapters for parsing and Unixy goodness.

share
show 2 more comments

Try http://projecteuler.net, they have many nice problems.

You could also try playing with bits: http://graphics.stanford.edu/~seander/bithacks.html.

You could also implement a image or data (de)compression algorithm. It's fun, there is lot of bit twidling, pointers, trees, recursion, mathematics and place for optimizations.

share
2  
Algorithms, but that's not really what he's looking for here. OP wants low-level stuff in C. Algorithms can be learned in any language. –  Christian Mann Oct 28 '10 at 4:55
show 1 more comment

Which high-level languages do you use? One way I've got back into C hackery after a prolonged absence is by working on a couple of C extensions for Ruby. This has the combined benefits of solving a real-world problem for me, so I've got decent motivation to actually finish the damn things, and plunging me neck-deep in real-world code, rather than rarefied ideal-case situations which don't expose you to problems you'll run into as soon as you apply your learnings.

The Ruby interpreter is quite a fun project to work on, actually - there's a surprising amount of both low-level and linguistic hackery that goes on in there.

Keep a copy of K&R by your side, but find something real to work on.

share
2  
Can't upvote enough, this is what should have been the accepted answer! –  Andrey Tarantsov Mar 27 '11 at 9:38
1  
I agree... Find something that's really slow in your current systems, implement it as a C module. –  red-dirt Mar 27 '11 at 10:45
show 1 more comment

In terms of simple "learn the mechanics" projects, try making a linked list. It teaches you about layered pointers and manual memory management (when you have to delete the thing).

share
show 1 more comment

I recommend working with microcontrollers. Their limited resources force you to work mindfully with C at a low level. This is even a very relevant application of C.

A TI MSP430 is a great way to get started for less than $5. This is an amazing hobby.

share
show 3 more comments

I was read some books in C an here is book i thinks useful for you:

  1. For basic C: The C Programming Language by Brian W. Kernighan, Dennis M. Ritchie alt text

  2. For helpful issue and tips: C Traps and Pitfalls by Andrew Koenig

alt text

Note: eBook version of 2 book available on the internet

share
2  
Expert C programming is good for the dustier's corner, and has some pretty good reviews -- amazon.com/Expert-Programming-Peter-van-Linden/dp/0131774298/… –  Rob Mar 27 '11 at 7:56
add comment
  • Do you like playing with hardware? Buy an Arduino and think of your own project(s). It will be much more fun than reimplementing library procedures and macros. Note that the language is not pure C, but based on a C/C++ syntax.
  • Start solving problems that look interesting to you. There are tones of such problems available. IMHO the ACM ICPC volumes are both interesting and challenging.
share
add comment

I would say take any problem you encounter at work and try to use lower level language to solve it. For example, if you have to parse a XML file at work using Java, then at home you can try rewrite the parser in C/C++.

share
add comment

Try to make a peer to peer software... We had this as an assignement, it's fun and you'll learn tons of things with it.

share
add comment

You can try to reimplement some functions from the core C library:

string.h

memchr, memcmp, memcpy, memmove, memset, strcat, strncat, strchr, strcmp, strncmp, strcoll, strcpy, strncpy, strcspn, strerror, strlen, strpbrk, strrchr, strspn, strstr, strtok, strxfrm

stdlib.h

abs, div, labs, ldiv, atof, atoi, atol, strtod, strol, bsearch, qsort

time.h

asctime, difftime

More advanced task would be to reimplement printf.

share
add comment

I'm in a similar situation and mindset.

Things like the problems in books and Project Euler on my afternoon days off or at night sometimes just don't cut it in terms of grabbing my interest. So, I started saving links to coding puzzles for just this purpose. Here is my short list so far:

(Sorry, I can't post more than 2 links without 10 reputation.)

Facebook Puzzles

Dropbox Puzzles

Reddit Puzzle: http://blog.reddit.com/2010/08/reddit-is-hiring.html

I have not looked into this yet, but UVA Online Judge has problems and I have heard as a recommended source for something like this: http://uva.onlinejudge.org/

I started the Facebook Puzzles, they are interesting and enjoyable.

My one other thought was to take old Atari games, learn some SDL (or maybe not) along the way, and re-write them in C as a learning experience. They were originally written in assembly I believe, had limited memory, limited graphics, and thus writing them in C is fairly high level I would think and not be too large for some.

You could try something like Top Coder too. A little competition is a good way to learn real quick.

share
add comment

This might be a little more application-oriented than you're hoping for, but if you want to brush up on various systems programming topics while you're at it, try writing a (really) simple in-memory data store of some sort. Depending on the details you choose, you'll find yourself covering data structures, various networking related topics (including either event loops or threads and some protocol design/parsing). You could also use an existing event loop library, which will still acquaint you with the basics of event loops, but also get you experience with build systems, etc.

Edit: If you're new to C and some of the topics involved, keep in mind this could easily take you a few weeks or more working in your spare time - re-reading your question, that might not be what you're after.

share
add comment

K&R will teach you the language but to write a real large system in C you probably want a higher-level approach to it. Large parts of GNOME are written in such a way. GLib and GTK+ are great codebases to look at to understand how "modern" C looks. Some codebases that don't use GLib but still use encapsulated abstract data types, OO style, etc. are D-Bus and Cairo. Disclaimer: I wrote D-Bus and bits of GLib and GTK.

To make C sane (and in my opinion, better than C++ in at least some ways) you have to still think high level even though the language lacks direct support for it. Much as in JavaScript, where the language itself doesn't necessarily force how classes and inheritance work, but for sanity you need to grab one of the utility files such as prototype.js or underscore.js that add more structure. Or at least roll your own.

Some people think since there's no class keyword or no private keyword they can just write a rat's nest, and say things like "OO is not possible in C." This confuses syntax with ways of thinking about problems. C may require you to build your own syntax and conventions, but it still lets you think about problems how you want. And libraries such as GLib are FAR more pragmatic than say libstdc++, which doesn't address a bunch of real world needs such as working with Unicode.

share
add comment

I recommend that you try to write a line-oriented text-editor akin to the old MS-DOS "EDLIN" program.

See http://en.wikipedia.org/wiki/Edlin for a description of EDLIN.

I would hope that this exercise would entail usage of data-structures ( such as linked-lists ), command parsing, and dynamic memory management.

share
add comment

Write a raytracer. Might be a bit time-intensive, but you can choose which more advanced techniques to implement on your leisure, plus the results are eye candy if you put some work into it.

share
add comment

It highly depends on what you are interested in, the language itself or system programming.

If you are interested in the language itself, @nguyendat's two recommendations are pretty good. There is also a book talking about pointers in C, which is something you probably don't need to worry about in "high level, memory managed languages".

On the other hand, if you are interested in system programming (e.g., to understand how to talk with the OS directly), there are tons of books and projects. I would recommend Unix Programming Environment, Advanced Programming in the UNIX Environment and UNIX Systems Programming: Communication, Concurrency and Threads. If you look for small projects on this subject, you can take a look some system programming courses in universities. They usually have good projects in reasonable size.

share
add comment

Try some of the problems on Sphere Online Judge.

There are quite a few problems where performance of string manipulation is important, for which you can try to come up with fast solutions using pointers instead of the less suitable string operations available to you in higher level languages.

(In general solving spoj problems is a fun way to experiment with any unfamiliar language)

share
add comment

Try writing a small lambda calculus evaluator. Initially just malloc all you memory, and don't free anything. Later, try writing your own memorypool with a small (mark-and-sweep) garbage collector.

share
show 1 more comment

How 'bout:

  1. Choose a sort strategy and then alphabetically sort an array of char * by the variable-length C string that each array member points to; do something sensible with duplicate strings and with NULL array members; return the length of the sorted array:

    int sort( char **array, int array_len );

  2. Binary search that same array; return the char * to the string that was found, else NULL if no such string:

    char * search( char **array, char *search_for_me );

-- pete

share
add comment

Forget all the books and stuff.. Start writing any trivial C code. Understanding C code does not take long, although some parts are tricky at first.

What is more important is after you write a short program, objdump or disasm it and see how the C code corresponds to assembly. Doing this is not only fun but it opens your eyes to see how things really work. You will learn the true difference between pointers and arrays, and your eyes will now be open to all the modifications that occur when going from a high-level to a low-level language.

Here is a fun project to start. If you need help contact me at jdefr89 [at] gmail. Write a program that modifies the entry address of a linux ELF executable. Start this by first reading about file formats (you can google the ELF specification), then man elf and man readelf.

Dig in and DO NOT be scared about jumping in over your head.. Don't think this type of thing is out of your current reach, you learn far more when you struggle to get things to work and understand rather than taking it to easy on yourself.

share
add comment

My only C/++ side project right now is an SNES emulator. I'm really far behind it working, but just opening up a ROM file, reading the headers (some of which are plain text and can prove you are reading it correctly), and disassembling the code in the rom are great exercises. I'm not very far on the project but I'm not going to stop until I get something displayed on the screen.

share
add comment

Solve programming competition problems. You will also sharpen your algorithms skills.

Check these out:

Also check out topcoder.

share
add comment

Skim the Linux source code, the FreeBSD source code, the OpenBSD source code, or the LibUSB source code.

Find something that grabs your "Hey, I can do better than that! reflex." DO better than that!

(LibUSB needs the ability to talk to devices, like My HP All-In-One, that used an outgrowth of the Parallel Port standards that were ported to USB.)

-Bob

share
add comment

I wouldn't recommend you to do algorithmic problems in c, nowadays everyone uses C++ for that because of the STL. I do recommend you start some nontrivial program and don't use anything but basic syscalls (I think you should read UNIX system programming, by Haviland et al).

You'll naturally need to implement some datab structures, and will need to start managing memory.

One of the best challenges is to run your program through valgrind and make it run without any warnings nor memory leaks. It is more difficult that it seems! And it is lots of fun!

share
2  
This is not a flamewar. We are not trying to convince him that C++ is better than C or the other way around. He is asking about C for a reason. –  faif Mar 28 '11 at 12:44
add comment

When I was really young I learned c programming on an amiga. I did 4 projects 1. Address book. No gui just text. Link lists. Learned memory and sorting 2. Fractals. Learned math mostly but good test for ADT. 3. Solitaire game. Again no gui just text. 4. Also did a black jack game.

share
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.