49

After five years of professional Java (and to a lesser extent, Python) programming and slowly feeling my computer science education slip away, I decided I wanted to broaden my horizons / general usefulness to the world and do something that feels more (to me) like I really have an influence over the machine. I chose to learn C and Unix programming since I feel like that is where many of the most interesting problems are.

My end goal is to be able to do this professionally, if for no other reason than the fact that I have to spend 40-50 hours per week on work that pays the bills, so it may as well also be the type of coding I want to get better at. Of course, you don't get hired to do things you haven't done before, so for now I am ramping up on my own.

To this end, I started with K&R, which was a great resource in part due to the exercises spread throughout each chapter. After that I moved on to Computer Systems: A Programmer's Perspective, followed by ten chapters of Advanced Programming in the Unix Environment. When I am done with this book, I will read Unix Network Programming.

What I'm missing in the Stevens books is the lack of programming problems; they mainly document functionality and provide examples, with a few end-of-chapter questions following. I feel that I would benefit much more from being challenged to use the knowledge in each chapter a la K&R. I could write some test program for each function, but this is a less desirable method as (1) I would probably be less motivated than if I were rising to some external challenge, and (2) I will naturally only think to use the function in the ways that have already occurred to me.

So, I'd like to get some recommendations on how to practice. Obviously, my first choice would be to find some resource that has Unix programming challenges. I have also considered finding and attempting to contribute to some open source C project, but this is a bit daunting as there would be some overhead in learning to use the software, then learning the codebase. The only open-source C project I can think of that I use regularly is Python, and I'm not sure how easy that would be to get started on.

That said, I'm open to all kinds of suggestions as there are likely things I haven't even thought of.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
danben
  • 80,905
  • 18
  • 123
  • 145
  • 5
    I'd just like to say I love seeing posts like this, where you're not simply saying "How do I learn C, but haven't done anything at all on my own." Kudos. Upvote. – samoz Jun 01 '10 at 13:46
  • 3
    First, read this: http://stackoverflow.com/search?q=code+kata. Second, update your question so it's not already answered. Or, possibly, close this question because it's a duplicate of one or more of those. – S.Lott Jun 01 '10 at 13:48
  • 3
    I disagree with S.Lott, he's not looking for a beginner introduction like most other questions are. His background is different and merits a different topic and responses. – samoz Jun 01 '10 at 13:50
  • @S.Lott: I read through those questions but don't see anything relevant to what I am asking. If you want to suggest a specific question as a duplicate I am open to closing this one, but keep in mind that I am looking for a specific thing to practice and not general programming. – danben Jun 01 '10 at 14:34
  • @danben: If you read those, please include the reference and specific reasons why your question is actually different. It appears identical to me. Since only you can clarify what's different, please clarify what's different. @samoz: since it's not your question, you can't really know what's being asked, can you? – S.Lott Jun 02 '10 at 13:08
  • @S.Lott - I think the burden of proof is currently on you to pick a question you think is a duplicate. Right now you are telling me to go find a question that you might think is a duplicate (from the subset of questions tagged "code-kata") and then tell you why it's different. Also, your comment to @samoz makes no sense as well - anyone who reads the question knows what is being asked. – danben Jun 02 '10 at 14:35
  • @danben: "anyone" may know. I can't figure it out. You can continue to refuse to clarify. That's your right. It's odd to ask for help and then refuse to clarify the exact help you want. If you're not going to clarify the question so you get **good** help, that seems like a waste of your time. – S.Lott Jun 02 '10 at 14:40
  • @S. Lott - I am happy to clarify anything about the question, but you have not asked anything about the question itself. You did ask me to explain how this question is different from another question, but you did not tell me which question that was, so I cannot answer. I am unable to find a duplicate. If you can, please vote to close. If I agree that it is a duplicate I will add a second close vote. – danben Jun 02 '10 at 14:58
  • @danben: Please think of this from someone else's point of view. I gave you a long list of potential duplicates. They are -- to me -- all identical to your question. You, however, have knowledge that will clearly differentiate your question from the questions in the list I gave you. They are **all** duplicates to my eye. You must explain precisely how your question is **not** a duplicate, since only **you** know what you're asking. You're simply repeating all the code-kata questions. Prove that you're not. Please. – S.Lott Jun 02 '10 at 15:30
  • @S.Lott - those questions are themselves mainly different from each other, but one reason I have not been able to find a duplicate in that list is that none of them addresses a way to practice Unix programming. Now, perhaps you took that to mean "any sort of programming done on a Unix platform, including implementing data structures and the like", but in my question I mentioned specifically that I would like to practice the material in the Stevens books (which cover system and network programming) the same way I was already able to practice general C programming via the exercises in K&R. – danben Jun 02 '10 at 16:10
  • @danben: Please update the question with your clarifications and comments. The point I'm trying to make is that **other people** will read this question. If it's not clear to folks, they will post duplicates rather than read (and upvote) your question. Please clarify the question by actually updating the question so that it's really clear (1) what you want and (2) why it isn't already answered by the other code-kata questions. – S.Lott Jun 02 '10 at 17:17
  • 4
    I thought the question was pretty straightforward... "I've read the books, but would like some practical problems and practice." This isn't Code Kata, because he's asking specifically about Unix programming, which covers things such as threading, pipes, etc; Code Kata covers supermarket pricing as an example. Code Kata is useful when learning a new language and is generally platform agnostic, but he wants specific projects to improve his Unix skills and understand UNIX internals. – samoz Jul 27 '10 at 14:38

8 Answers8

29

Reinvent a lot of the core Unix utilities. Most of these were (and still are) written in C, so they are a good way to start off learning. Depending on your skill, pick harder or easier utilities to copy.

Try writing your own malloc. You'll learn a lot about Unix and a lot of C programming as well.

Google for computer science operating system courses and do the projects there. Many schools have these projects on public websites so you could get everything you need. Here is a link to Purdue's site. Give the shell project a shot; it was difficult, but really educational.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
samoz
  • 56,849
  • 55
  • 141
  • 195
  • I second this, I have done similar things to teach myself new skills. Personal experience was reimplementing a kernel driver for a simple hardware device in Linux. – andy Jun 01 '10 at 14:15
  • +1, writing a set of core utilities would be an excellent challenge that would quickly bear practical fruit. – Tim Post Jun 01 '10 at 14:31
  • I like this answer very much; in particular, the idea to find OS projects on course websites. I hadn't thought of that. – danben Jun 01 '10 at 14:35
  • 2
    one of my favorite projects when I was starting out was to reimplement `tar`. It's amazing how many different areas of C programming that cuts across. – rmeador Jun 01 '10 at 15:03
  • @rmeador Very cool idea! How did yours turn out compared to the original? – samoz Jun 01 '10 at 20:13
  • mine wasn't as full-featured as the original, and the file formats weren't compatible, but it did most of the same stuff. It also remains to this day as the most complex thing I have written, compiled, and run without errors/bugs. I wrote all the core file packing/unpacking/listing code in one go without even test-compiling. It was probably only a couple hundred lines though. – rmeador Jun 01 '10 at 20:46
  • +1 for a wonderful suggestion. Implementing malloc, even a malloc as simple as the one in K&R book, has benefit me A LOT. – user172818 Jun 01 '10 at 23:04
5

Here are a few stackoverflow postings discussing C/Unix programming books. Their main claim to fame is extensive fan-out to other resources.

Practice some of the idioms (understand the ins and outs of pointers etc) and pick projects that help with that. The third item in the list has an answer (disclaimer, I wrote it) with a bunch of high-level C idioms where an idiomatic C program would differ from Java.

Learning XLib or Win32 GUI programming with C is probably less useful as almost anything is better than C for GUI programming and wrapping a core C engine with another language is generally much easier - unless you're really concerned with speed. As a starting point, concentrate on 'systems' programming applications, which is where you are most likely to get real mileage from C. Learn how the C interface of one of the scripting languages like Tcl or Python works.

Writing some bit-twiddly and pointer heavy code (e.g. picking apart network packets or interpreting a protocol), or server-side items using sockets will take you right into C's core competencies. If you've got some of the WRS books, try making pthreads work (IIRC UNP2 has a big section about pThreads). For a contrast, write something that uses non-blocking I/O. This stuff is C's home turf and you'll get a good working knowledge of C by doing this. Troll through the RFCs for some ideas of network protocols to implement.

Community
  • 1
  • 1
ConcernedOfTunbridgeWells
  • 64,444
  • 15
  • 143
  • 197
  • Thanks for the answer! The links aren't very useful, because: (1) is geared toward Linux users rather than developers, (2 and 3) are about learning advanced C, which I do need to do but don't need to ask about on SO, and (4 and 5) are about data structures and algorithms which I have a solid background in. However, I think your suggestions for projects are very good - perhaps learning the Python API will be the way to go after all. – danben Jun 01 '10 at 14:49
1

Are you open to book suggestions? Although it is a bit dated (where "a bit" perhaps is a huge understatement), Maurice Bach's "The Design of the Unix Operating System" is a great book. It belongs next to K&R on your bookshelf.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
1

You might try working your way through all the examples in the book Software Tools (Amazon). Much of it is pretty pedestrian (right-justify text, de-tabify, etc.), but it's a great introduction to the Unix philosophy and basic C programming.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
1

This is pretty interesting. As we know that Unix is designed by using the C language, it may not difficult to learn. If you are using the Windows OS, you can use a "Windows services for Unix" application to practice your programs. If you are using Unix, then we can use editors like vi.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ramesh.kbvr
  • 763
  • 6
  • 15
  • 31
0

The best way to consolidate your learnings it to practise. So just choose a kind of application that interest you and start developing it (for example, a network client/server simple application).

Try to test most of the Unix APIs (files, sockets, etc.) to see how they work. You could for example get an Unix programming book, follow its chapters and test on your application everything you read, by creating your own functions. On that way, you can start to develop your own function library to be used in further projects.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jorg B Jorge
  • 1,109
  • 9
  • 17
0

Write a webserver.

  • Make it multi-threaded.

  • Have it support a new scripting language you develop (a la PHP, etc.)

  • Allow uploads from authenticated users.

  • Write a plugin for your favorite tool (i.e. integrate with SVN to give a webview).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Willi Ballenthin
  • 6,444
  • 6
  • 38
  • 52
0

I would recommend one thing highly.

Try and re-write all usual Linux command lines tools like ls, mkdir, cd etc.

You'll gain a lot of knowlege about programming and Linux both at the same time.

Pick the commands from the easiest, say "time" and work all the way up to the more complicated ones.

Stark07
  • 468
  • 8
  • 17