practicing C over the summer - c

I'm a student with a bit of experience in Java and C++ (one semester each)
Currently, I'm going through K&R and working on the exercises in the book. However, I was thinking of what I could work on over the summer since I'm almost done with K&R and I will have a lot of free time soon.
I really like building command line applications so I was thinking of getting involved with the coreutils project somehow. My question is, is it too early for me to be messing with coreutils? Should I be working on something a bit simpler perhaps? I'm a bit new with the Linux/Open source world if that matters but I'm really enjoying it.
I've done some project euler problems and I don't really like it that much.

Download the Nethack sources. Play it. If you ever get past that stage, then add some new and interesting monsters, weapons, traps and other objects.

https://openhatch.org/search/
http://sourceforge.net/people/
http://www.fsf.org/campaigns/priority-projects/
http://savannah.gnu.org/people/?type_id=1

You can do various other things with C:
Use various data structures like Link-list, tree, hash, heap
Try coding various algorithm implementation
Play with various string manipulation
Work with basic system and socket programing
List goes on..

There are (I'd argue) probably only a couple of places where C is still used extensively in preference to C++, so if you want to make a difference in the Open Source world I'd recommend thinking about working in one of the following areas:
Device drivers, and indeed most aspects of OS kernels.
Interfaces to scripting languages (Python, Perl, Lua etc.)
In both cases, C++ has no significant advantage, or some significant disadvantages, over C.
I agree absolutely with Mark's comment above that it is difficult to join a mature project. I have recently been trying to get a Haskell binding put together for SWIG, and it has proven to be pretty tricky - and I say that with over 20 years of C and about 15 of C++ behind me!
The problem is that mature codebases usually are not so clean, and this means that it can be difficult to understand how things hang together.
If you have the case, working on ARM device such as a Pandora or one of the other small embedded devices you can pick up is a lot of fun, and will teach quite a bit. In many cases what you are looking for is a device with a 'community' Linux port, and for many of these there are some quite basic components which are not yet working.
Good luck, and have fun!

I agree with Jeremy O'Donoghue's answer (since I am also a Mobile Device developer). Go install a 32-bit linux distro (if you don't already have), and start hacking Android Source Code.
There are many mailing-lists dedicated for the Android and you might try discuss some idea from there.
And there is also Google Summer of Code if you can make it

Related

How do I practice Unix programming in C?

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.
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.
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.
What are good Linux/Unix books for an advancing user?
What are some good resources for learning C beyond K&R
Resources for learning C program design
What’s a good way to start learning about Data Structures & Algorithms?
Algorithms in C
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.
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.
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.
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.
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.
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).

How to push further as a programmer? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Closed 1 year ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
For the last, hmm, 6 months I've been reading into Programming in C, I got myself K&Rv2, BEEJ's socket guide, Expert C programming, Linux Systems Programming, the ISO/IEC 9899:1999 specification (real, and not draft). After receiving them from Amazon, I got Linux installed, and got to it.
I'm done with K&R, about halfway through Expert C Programming, but still feel weak as a programmer, I'm sure it takes much more than 6 months of reading to become truly skilled, but my question is this:
I've done all the exercises in K&Rv2 (in chapter 1) and some in other chapters, most of which are generally really boring. How do I lift my skills, and become truly great? I've invested money, time and a general lifestyle for something I truly desire, but I'm not sure how exactly to achieve it.
Could someone explain to me, perhaps if I need to continuously code, what exactly I'm to code? I'm pretty sure, coding up hello world programs isn't going to teach me any more than I already know about anything.
A friend of mine said "read" (with emphasis on read) a man page a day, but reading is all I do, I want to do, but I'm not sure what! I'm interested in security, but I'm not sure as a novice what to code that would be considered enough.
From Abstruse Goose
Also, Teach Yourself Programming in Ten Years
What would really help you learn is to start a project. It could be anything, implementing a chat client/server, a unix shell, a simple program to store grocery lists, whatever. The point is by picking something that you are interested in and working to implement it, you will be surprised how much you learn along the way, and you won't want to quit because you are working on something meaningful to you.
Basically, you will only learn so much by reading. To gain true knowledge you will need to work through real problems.
most of which are generally really boring
Learn something you find interesting, then the rest will fall into place.
Peter Norvig has some ideas about that
Try to implement a few non-trivial algorithms. I do not know what examples are included in the books, but you might try to write
An algebratic calculator. Input "sin(2) + 5! * 3^(1/2)" and you get 208.755394335 as an output.
A syntax-highliting text editor from scratch.
Write a PNG (or any other image or sound format) encoder/decoder from scratch.
Write an image editor (for instance flood fill is not entirely trivial)
...
You say you're interested in security. Go look up some exploits and try to understand them. Better yet, try to find an exploit yourself, for a known (better: unknown) vulnerability.
Write an NNTP client, or an SMTP server, or client, and use it to send your mail. Many of these internet protocols are simple enough to not be very difficuly to implement (most of the text-based protocols), yet nuanced enough to be interesting, and they have the connection to the real world that makes it more satisfying than a "hello world" program.
Or how about writing a linux kernel module? They're not that hard to write, there's just a bit of a barrier to entry (lots to learn before you can have your "black triangle"). Make a character device that returns an endless stream of the last byte you wrote to it (call it /dev/fortytwo if you like). Then make sure it will work when two processes use it simultaneously.
Look for some project with crappy code but friendly community, and clean some of it up. GCC and the kernel would be bad choices here :)
"read" and practice what you read which is the best way.
Code Golf and Project Euler are good - but they are more about problem solving and maths than programming.
Find an Opensource project (probably not the Linux kernel) that you are interested in, download the source and try and use it. Ideally something that is a library rather than an application so you have to learn how to read it to use it with your own stuff.
Don't worry - It only takes about 10 years to become a good programmer.
Go to work.
Seriously, find a job for a beginner and let someone with a bigger knowledge guide You (if You have luck) or check the codebase for a useful hints (if You have smaller luck).
In other way, You can start a project for Yourself as some of folks suggested and improve Your knowledge as the opportunity arises.
However, I wouldn't mix both of these worlds - don't start by agreeing a deal for a money - You will probably be prone to under/over-estimating time cost, won't have a good knowledge of bigger solutions, etc. It's better to have someone to guide You or have more time to learn things.
Ah, and btw. - read books (CC2, some design patterns books, "Clean code" are a good place to start with and great reference-books for the whole career) and blogs (You'll know it when You see it).
You need to challenge yourself with a bigger, more complex project. Working through code snippets, as most book examples tend to, will not get you far past the chapter exercises.
You're working on being a book-smart developer. Do something real world and become street-smart!
I find practicing much more useful at learning concepts than reading about them. Often what I'll do is determine a problem I want to solve with software, then go about it by attempting the problem. I will utilize resources along the way, but its really more useful to try what you read, rather than read every book on the subject.
Also, Code Golf is a good way to find fun programs to attempt.
Code Hello World, then code Hello World distributed over a network, or in 3d, or using a database. Don't think things are too trivial until you've done them. Implement algorithms to make sure you know how. Do code you think is fun.
First, you need to write software in a group of at least two, so you can get feedback. If you are working alone, then find a way, either by using SO or another form, like Programmers to get feedback.
Next, find something that interests you, and the project ideas will follow. I work in a municipal environment, but what intrigues me most is the instrumentation for water. I like my other work, but a lot of interesting programming ideas come from working on the water metering and billing systems. Working on water programming problems keeps my mind sharp when other problems, like comparing health insurance enrollees, come around.
Whether you focus more on web or server back-end projects, keep your language knowledge current and small enough to know the language well. From my experience, if you know an Algol-based language well, like C, you can probably learn another similar language like C++, Java, or Perl. C is a wonderful language, but unless you plan on writing Linux kernel, specialized embedded, or Python extension code, I would suggest learning Scala or Clojure, and perhaps Ruby in addition to Javascript and PHP.
However, what would trump what language you learn is someone with an interesting project willing to hire you and your learning their implementation language well. That is if you like Language A, but someone is willing to hire you to work on their project implemented in Language B, then embrace the project, because your growth as a programmer will come from good contribution to the project rather than what language you know.
Finally, become a good problem solver, and those skills will extend beyond writing software. These days, if I am valuable at all, it is because I can work on a bunch of problems, not just programming.
Do it. There isn't a shortcut to being a "great" developer - like any other craft, it takes lots of time and practice and patience. Just do it.
If you're interested in security, try coding a web application with security in mind. If you create something like a forum you'll not only learn about a number of security concerns, but also how to use multiple technologies like databases, web servers, and a new language and potentially new style besides C. And then when you're done with your project, compare the code to other similar software. If you get stuck on your project you can also look at similar projects to see what they do. And it can be as simple or as complicated as you want it to be.
Web programming may be different from systems programming in a lot of ways, but both share many security concerns.
Learning to program is like learning to speak a foreign language. Initially it is very frustrating and often boring. It is only after you gain a degree of fluency in a given language that you find your productivity increases. Along the same vein, just learning the rules is not enough. As with language learning, if you don't use it, and use it often, it will be hard to retain and keep your interest up.
What works for one person doesn't always work for another. Code golf may work for you, or you may find it tedious for example. Personally I like doing something that has genuine value, but that is me. Experiment a little with different types of coding projects, perhaps code golf, perhaps open source projects, producing a game, etc. Sometimes just trying to figure out how to answer other people's questions helps. Eventually you'll find what works for you. Just remember, studying is not enough, you have to apply those studies.
Some project ideas:
Small database projects: contact list, DVD collection, etc. Emphasizes file I/O, searchable data structures, etc.
Simple calculator: Emphasizes interactive I/O, parsing, tree-like structures, etc.
Simple NNTP (Usenet) or chat client: Networking and protocols
You can only learn the language, when you are using it. Simple examples or exercises will never give you the deep insight into the language. I personally also found the exercises at the end of a chapter boring and unworldly, so I didn't do them. As other state find a project you are interested in. This can be anything, starting from a simple board game up to a video cutting system. If you found out what would be interesting for you, take a look on how you can accomplish it. You will need to use some helping libraries, for the UI and also for the backend. And then start to work!
(Of course the project should be doable for you, hence don't take an aim like 'writing a better word processor than Winword'.)
Another way is to dig for an OSS project that you are interested in and where you are missing some features. Implement those! The great benefit is that you get a source review that is probably tougher then from any teacher. Once you learned those coding styles, you probably already forgot about the language itself.
Start a project and finish it. Put it online, make it open source, get feedback.
Consider reading more content on the "concepts" of programming than purely syntax:
Don't Make Me Think by Steve Krug
Code Complete: A Practical Handbook of Software Construction
Join a mailing list/newsletter/magazine/podcasts for programmers in your area of expertise:
http://www.drdobbs.com/cpp/;jsessionid=XVZEO0SKOCRRBQE1GHPCKH4ATMY32JVN
Visit StackOverflow.com and try to solve issues periodically to give yourself a mental challenge and help others.
You might find reading Code Complete 2 helpful. It is a good book on programming practices.
.

Is C good for any projects beyond the command-line and learning?

This is not meant to be inflammatory or anything like that, but I am in the midst of learning C, and (think) I have a good handle on most of the basics. I've done all of the various book exercises: primes generators, Fibonacci generators, string manipulation, yadda yadda, but none of this is cool.
What is the "bridge" between command line programs and something -cool-? I've heard of various games being written in C, but how?
Forgive my exasperation, but it feels like I've been learning lots but can still only do relatively little. Thanks for any insight on what to do with C.
Relevant information: OS X leopard, PHP and web development experience (which is so great because projects are immediately in a context where you recognize how they can be powerful)
C is the concrete and the steel of modern tech
There was a time when almost everything was written in C, or in something much worse.
These days, many of the advanced languages and systems are actually implemented in C or C++, and then those things implement more systems. It is standing on the shoulders of giants, as the expression goes. Almost every OS kernel, browser, and heavy-duty-web-server is written in C/C++.
So sure, you don't see the steel in the high rise, you see the beautiful interior furnishings and the sleek glass windows. You don't want a steel or concrete desk, and if you did, it would be too expensive to build for you.
Back to your GUI question: your first C graphics program should probably use the original X Window System directly. Don't spend too much time there, but then move on to one of the more advanced Widget toolkits such as GTK+ or (the C++) Qt. Be sure to investigate your OS X system, as it has one of the most advanced of them all.
I try love to write things in Ruby these days, but I happen to know there are over 100,000 200,000 lines of C code implementing that cool Ruby language system. :-)
Summary
Ok, this post got really big, so here's a quick summary before you read it: to program GUIs, there are a number of good C/C++ libraries (for example, QT). What most people do, on Windows systems at least, is to use a .NET language (like C#) when they want GUIs, and C/C++ when they want more control/speed. It's also very common to use both in combination, i.e. make a GUI in C# and speed-critical parts in C.
I still encourage you to read the longer answer, it contains a lot more information on your options.
Longer answer
I'll start with the big question, then answer (as best I can) your specific question about creating a GUI. I think you're kind of suffering from the fact that C is used to teach programming, and it's much easier to do so only using command line programs (after all, they're much simpler to write). This doesn't mean that C can't do all of the stuff you want, like GUIs specifically. It does. I don't think there's any type of software that hasn't been done in C, usually before it was done in other languages.
All right, some answers:
Is C Useful?
C, and its very close relative C++, are responsible for a huge portion of the world's code. I don't know if more code is written in C than any other language, but I'm guessing it's not far off.
Most of the really important programs you use are actually written in C/C++. Just for one example, Windows.
Where is C used today?
C/C++ are still used a lot. They're especially useful for developing low-level stuff (i.e. stuff like Operating Systems, which need a lot of speed, a lot of ability to control exactly what your code does, etc.).
But don't think it's all low level for C programmers. Even today, with many other languages available (which are arguably much better, and certainly much easier to program), C is still used to create practically everything. GUI applications, which you specifically asked about, are very often made with C, even though nowadays, lots of people are switching to other languages. Note I say switching: C used to be the standard language for writing, well, everything, really.
How do I develop GUIs with C
Alright, you specifically wanted to know how to create a GUI with C (I'm hoping C++ is ok too).
First of all, it depends on a number of factors:
What Operating System are you writing for? (Windows, Mac, and Linux are the most common).
Do you want the GUI to work on other systems as well?
The most common case is writing software to work on Windows. In that case, the "natural" solution is to write things that work with the Win32 API. That's basically the library that "comes" with Windows, letting you do any GUI work you want to do.
The big problem with this is, it's kinda hard. As in, a lot hard. This is the reason most people don't do that kind of work anymore.
So what are your other options?
The most natural is going with what's called a .NET language. Those are a bunch of languages, together with libraries, that Microsoft created. They're probably the easiest way to get a GUI on Windows. The problem is, you can't really use them from C (since it's not a .NET language).
Assuming you want to stay in C/C++ land, you can use some kind of library which makes working with the Windows API easier (since it hides all the ugly details):
One of the most common is what's called MFC (Microsoft Foundation Classes), which are a bunch of C++ classes which make it "easier" to create Windows stuff. Unfortunately, this library is very old, and is really not that easy to use.
The other way to go if you want to program in C++ is to use some kind of third-party library. This is a library that someone other than Microsoft created, which makes it easier to create a GUI.
Another option is to create only the GUI part of your software in a .NET language, and use C/C++ for the other parts (or use the .NET language to do almost everything, and use C/C++ only when you really need it, for example when you need things to go really fast). This is a very popular option.
The advantage of a third party library is that, if you pick the right one, you can use the same code to create a GUI for all the Operating Systems at the same time.
I think the most famous of these libraries is QT, and also WxWidgets, but there are a bunch of other ones. I would personally pick QT since it seems to get the most fame, but I haven't worked with either.
Every major operating system has all of its low-level libraries implemented in C. Mac OS X is a Unix-like system under the hood, which is a wonderful world if you're a C programmer.
Check out The Art of Unix Programming for some great ideas.
As for GUI stuff, you'll probably want to use X11. There is plenty of good documentation out there -- most Unix programming stuff and most deep system-level stuff just assumes you're working in C, since that's what everybody uses for it.
Well, that depends. If you want to build desktop applications, a multiplatform GUI library whose main language is C is GTK+:
http://www.gtk.org/
For games, check out SDL:
http://www.libsdl.org/
Which provides you with thinks like direct input from keyboard, 2D graphics, some audio and even threads and stuff like that. It can also open an OpenGL context if you want to get into the 3D world (however it's hard to do it in raw OpenGl). Did I mention that SDL is multiplatform?
However the real strength of C is in systems programming. For desktop applications/games maybe you are best suited with C++. Now that you have command of C, learning the basic C++ should be easy ;).
Cool stuff do with C?
Operating Systems, device drivers, and python modules for starters.
Games typically will use C++ if they're C-Based, in my experience / what I've seen.
There are many libraries for C under Unix, such as X lib, which accesses X11.
If you wanted to get into robotics you may find C to be very useful, as you will have to write low-level code with very small memory footprints, so even C++ may not be the best choice.
C and C++ are very good at writing small, fast code, but OOP is not always the best choice, so at times you will find that C is a better choice, for example if you are writing a compiler or OS.
Sure there are some impressive programs made in C !
GNOME for example, arguably the most used desktop environment used in modern unix systems is written in C (the major parts at least) and is mostly based on GTK+ gui toolkit, itself done in C.
For game, OpenGL is a C api and is the standard for 3D graphic programming in multi-platform development (not uniquely microsoft platform), and Quake 3, which the engine, Id Tech 3, is available in GPL, is also writen in C. There also is many 2D games written using SDL library.
SDL is a good library for graphics and sound, and I've seen some cool stuff done with it. If you do it in C, it'll take longer to make, but from a performance point of view, it'll be much better.
If your idea of cool is GUI apps and you want to write native GUI apps on the Mac, you'll want to look at
Carbon. This is the official C API into the Mac GUI and OS. They keep threatening to kill it, but it survives.
Personally I think GUI apps are a very narrow definition of cool. What I think is cool is implementing parallelized math algorithms using opencl.
GTK-server is REALLY easy to get started with, in C or any other language. Just click that link.
For a "cool" application that goes beyond simple GUI's, check out the OpenCV computer vision library. It provides fast real-time image processing and face recognition.
Now you can access a webcam and start writing real-time computer vision games. For applications like these that are processor intensive, C is the ideal choice.
Last I checked more Open Source projects are started in C than in any other language.
The fact that C is used by so many large and successful projects doesn't particularly make it "good". The reason C is so commonly used is because of a few factors, it's been around a long time, it's fast, it lets you access both low level and high level interfaces as needed, and it's better than the other old languages (FORTRAN etc). The "cool" thing about C is that you can make it do absolutely anything: inject itself into the kernel and add some new features or bug fixes that you couldn't convince Microsoft to do, etc.
Yes, C can be and is easily used for things beyond the command line, but it's extremely dangerous due to pointers... Not to mention development in other more modern languages is faster (and safer) by magnitudes. I never use C unless it's the last resort, ie: need to implement something low level or needs that extra performance.
By the way, when I say C, I really mean C++. I'd never choose C over C++ unless I was forced to.

I've read The C Programming Language where do I go from here?

I've read 'The C Programming Language', what should I be doing now? Is there anything important in C that's missed out in the book? Specifically interested in the Linux side of development, so is there anything important I should learn about C in Linux? (I already know some of the basics).
I'm sorry if this question seems a bit general, but i'm a little lost as to what to learn next.
Do the book exercises!
Reading it is too little.
I'd start off by actually programming something next. Project Euler has good problems to solve that will help you get a better understanding of the language. From there you can move in to Linux-specific C programming, but definitely get your feet grounded in the C basics first.
The W. Richard Stevens books are the next place to go to, if you're interested in Linux development (they're about general UNIX-alike development, but it's all pretty much applicable to Linux).
Start with Advanced Programming In The UNIX Environment.
Many answers mention actually programming, and I would start by that if you haven't.
I would also recommend reading quality code. Read, say, bzip2's implementation. Do not worry about not understanding everything on the first pass. There are plenty of little things, idioms, ... than one can pick up even without having read about the algorithm that is being implemented beforehand (the algorithm is interesting too, by the way).
If you are interested in program verification, take a look at ACSL, a specification language to write (and verify) contracts for C functions.
Knowing C is cool. How about learning a different aspect than just the language/syntax?
Two things that strike me are:
Socket programming. Write a basic chat client/server. Or a small file-transfer program
Multi-programming. Either with processes (fork(), etc - and this would fit nicely with sockets) or
pthreads. Learn multi-threaded programming, and what makes them different vs processes to get things done in parallel.
Both of these (sockets, multi-programming) are idea for a single project. You could write a networking program (like a shell), and then modify it to handle multiple connections - making use of processes/threads.
If You want deep dive into Linux hacking read already mentioned "Advanced Programming In The UNIX Environment". But IMO this book required some experience before reading it.
I suggest some books about programming tools (used in Linux but not only) like svn, diff, packaging system:
Professional Linux Programming - good book step by step tutorial about creating video rental service using only Open Source tools. Unfortunately it's not only about C and required some knowledge of other languages.
Linux for Programmers and Users - lot of informations for Linux programmers and users
The Linux Programmer's Toolbox - vary good book about Linux tools for programmers.
The Art of UNIX Programming IMO every programmer should read this book, there is a little source code, a a lot of philosophy (some one may don't like it) but most important is it show beautifully of
Unix design, and show how to follow it in your own programs.
Data Crunching: Solve Everyday Problems Using Java, Python, and More Data Crunching: Solve Everyday Problems Using Java, Python, and More] - book not about C nor Linux but it's help to solve data processing task smartly.
Expert C Programming: Deep C Secrets
What's the use in learning things if you're not going to use it. Make a program.
Then when you find you don't know how to do something, look it up or ask here.
The best way to learn is to do.
Understanding Unix/Linux Programming
This book is really good. It basically covers all the OS specific stuff (specific to Unix and Linux) that isn't covered by the C specification.
This book covers things like signals, threads, inter process communication, network programming, and a bunch of other stuff.
In addition to doing the exercises in K&R, I'd start by duplicating a bunch of commonly used linux commands. This is helpful for 2 main reasons.
There are Linux/Unix commands of all levels of complexity. You can start with the easy ones and move on as your skill increases.
You can compare your program's output and running time with the real one to check correctness and efficiency.
Every time I learn a new programming language I duplicate a few linux commands to solidify my ability to solve actual problems in that language.
Reading about programming is a helpful way to get started, but what you read won't really start to come together in that "Aha!" moment until you start to do some programming. Find a task that you need to that could be solved by writing a program (even if that task has already been solved many times) and write a program to do it. The program doesn't have to be composed of pretty or efficient code and the result doesn't have to be attractive. The more you do some programming, the better you'll get and the better your programs will be.

What type of programs are best written in C [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Joel and company expound on the virtues of learning C and how the best way to learn a language is to actually write programs using that use it. To that effect, which types of applications are most suitable to the C programming language?
Edit:
I am looking for what C is good at. This likely does not coincide with the best way of learning C.
Code where you need absolute control over memory management. Code where you need to be utterly in control of speed versus memory trade-offs. Very low-level file manipulation (such as access to the raw devices).
Examples include OS kernel, and embedded apps.
In the late 1980s, I was head of the maintenance team on a C system that was more than a million lines of code. It did database access (Oracle), X Windows graphics, interprocess communications, all sorts of good stuff. It ran on VMS and several varieties of Unix. But if I were to recreate that system today, I sure wouldn't use C, I'd use Java. Others would probably use C#.
Low level functions such as OS kernel and drivers. For those, C is unbeatable.
You can use C to write anything. It is a very general purpose language. After doing so for a little while you will understand why there are other "higher level" languages available.
"Learn C", by all means, but don't don't stick with it for too long. Other languages are far more productive.
I think the gist of the people who say you need to learn C is so that you understand the relationship between high level code and the machine internals and what exaclty happens with bits, bytes, program execution, etc.
Learn that, and then move on.
Those 100 lines of python code that were accounting for 80% of your execution time.
Small apps that don't have a UI, especially when you're trying to learn.
Edit: After thinking a little more on this, I'd add the following: if you already know a higher-level language and you're trying to learn more about C, a good route may be to not create a whole new C app, but instead create a C DLL and add functions to it that you can call from the higher language. In this way you can replace simple functions that your high language already has to ensure that you C function does what it should (gives you pre-built testing), lets you code mostly in what you're familiar with, uses the language in a problem you're already familiar with, and teaches you about interop.
Anything where you think of using assembly.
Number crunching (for example, libraries to be used at a higher level from some other language like Python).
Embedded systems programming.
A lot of people are saying OS kernel and device drivers which are, of course, good applications for C. But C is also useful for writing any performance critical applications that need to use every bit of performance the hardware is capable of.
I'm thinking of applications like database management systems (mySQL, Oracle, SQL Server), web servers (apache, IIS), or even we browsers (look at the way chrome was written).
You can do so many optimizations in C that are just impossible in languages that run in virtual machines like Java or .NET. For instance, databases and servers support many simultaneous users and need to scale very well. A database may need to share data structures between multiple users (threads/processes), but do so in a way that efficiently uses CPU caches. In C, you can use an operating system call to determine the size of the cache, and then align a data structure appropriately to the cache line so that the line does not "ping pong" between caches when multiple threads access adjacent, but unrelated data (so called "false sharing). This is one example. There are many others.
A bootloader. Some assembly also required, which is actually very nice..
Where you feel the need for 100% control over your program.
This is often the case in lower layer OS stuff like device drivers,
or real embedded devices based on MCU:s etc etc (all this and other is already mentioned above)
But please note that C is a mature language that has been around for many years
and will be around for many more years,
it has many really good debugging tools and still a huge number off developers that use it.
(It probably has lost a lot to more trendy languages, but it is still huge)
All its strengths and weaknesses are well know, the language will probably not change any more.
So there are not much room for surprises...
This also means that it would probably be a good choice if you have a application with a long expected life cycle.
/Johan
Anything where you need a minimum of "magic" and need the computer to do exactly what you tell it to, no more and no less. Anything where you don't trust the "magic" of garbage collection to handle your memory because it might not be as efficient as what you can hand-code. Anything where you don't trust the "magic" of built-in arrays, strings, etc. not to waste too much space. Anything where you want to be able to reason about exactly what ASM instructions the compiler will emit for a given piece of code.
In other words, not too much in the real world. Most things would benefit more from higher level abstraction than from this kind of control. However, OS code, device drivers, and a few things that have to be near optimal in both space and speed might make sense to write in C. Higher level languages can do pretty well competing with C on speed, but not necessarily on space.
Embedded stuff, where memory-usage and cpu-speed matters.
The interrupt handler part of an OS (and maybe two or three more functions in it).
Even if some of you will now start to bash heavily on me now:
I dont think that any decent app should be written in C - it is way too error prone.
(and yes, I do know what I am talking about, having written an awful lot of code in C myself (OSes, compilers, VMs, network protocols, RT-control stuff etc.).
Using a high level language makes you so much more productive. Speed is typically gained by keeping the 10-90 rule in mind: 90% of CPU time is spent in 10% of your code (which you should optimize first).
Also, using the right algorithm might give more performance than optimizing bits in C. And doing things right in C is so much more trouble.
PS: I do really mean what I wrote in the second sentence above; you can write a complete high performance OS in a high level language like Lisp or Smalltalk, with only a few minor parts in C. Think how the 70's Lisp machines would fly on todays hardware...
Garbage collectors!
Also, simply programs whose primary job is to make operating-system calls. For example, I need to write a short C program called timeout that
Takes a command line as argument, with a number of seconds for that command to run
Forks two child processes, one to run the command and one to sleep for N seconds
When the first of the child processes exits, kills the other, then exits
The effect will be to run a command with a limit on wall-clock time.
I and others on this forum have tried several different solutions using shells and/or perl. All are convoluted and none quite do the right thing. In C the solution will be easy, because all the OS facilities are right where you can get at them.
A few kinds that I can think of:
Systems programming that directly uses Unix/Linux or Win32 system calls
Performance-critical code that doesn't have much string manipulation in it (e.g., number crunching)
Embedded programming or other applications that are severely resource-constrained
Basically, C gives you portable, efficient access to the native capabilities of the machine; everything else is your responsibility. In particular, string manipulation in C is tedious, error-prone, and generally nasty; the most effective way to do extensive string operations with C may be to use it to implement a language that handles strings better...
examples are: embedded apps, kernel code, drivers, raw sockets.
However if you find yourself more productive in C then go ahead and build whatever you wish. Use the language as a tool to get your problem solved.
c compiler
Researches in maths and physics. There are probably two alternatives: C and C++, but such features of the latter as encapsulation and inheritance are not very useful there. One could prefer to use C++ "as a better C" or just stay with C.
Well most people are suggesting system programming related things like OS Kernels , Device Drivers etc. These are difficult and Time consuming. Maybe the most fun thing to with C is console programming. Have you heard of the HAM SDK? It is a complete software development kit for the Nintendo GBA , and making games for it is fun. There is also the CC65 Compiler which supports NES Programming (Althought Not Completely). You can also make good Emulators. Trust Me , C is pretty helpful. I was originally a Python fan, and hated C because it was complex. But after yuoget used to it, you can do anything with C. Now I use CPython to embed Python in my C Programs(if needed) and code mostly in C.
C is also great for portability , There is a C Compiler for like every OS and Almost Every Console And Mobile Device. Ive even seen one that supports some calculators!
Well, if you want to learn C and have some fun at the same time, might I suggest obtaining NXC and a Lego Mindstorms set? NXC is a C compiler for the Lego Mindstorms.
Another advantage of this approach is that you can compare the effort to program the Mindstorms "brick" with C and then try LEJOS and see how it goes with Java.
All great fun.
Implicit in your question is the assumption that a 'high-level' language like Python or Perl (or Java or ...) is fast enough, small enough, ... enough for most applications. This is of course true for most apps and some choice X of language. Given that, your language of choice almost certainly has a foreign function interface (FFI). Since you're looking to learn C, create a module in the FFI built in C.
For example, let's assume that your tool of choice is Python. Reimplement a subset of Numpy in C. Since C is a pretty fast language, and has, in C99, a clear numeric library interface, you'll get the opportunity to experience the power of C in an appropriate setting.
ISAPI filters for Internet Information Server.
Before actually write C code, i would suggest first read good C code.
Choose subject you want to concentrate on, basically any application can be written in C, but i assume GUI application will be not your first choice, and find few open source projects to look into.
Not any open source project is best code to look. I assume that after you will select a subject there is a place for another question, ask for best open source project in the field.
Play with it, understand how it's working modify some functionality...
Best way to learn is learn from somebody good.
Photoshop plugin filters. Lots and lots of interesting graphical manipulation you can do with those and you'll need pure C to do it in.
For instance that's a gateway to fractal generation, fourier transforms, fuzzy algorithms etc etc. Really anything that can manipulate image/color data and give interesting results
Don't treat C as a beefed up assembler. I've done some serious app's in it when it was the natural language (e.g., the target machine was a Solaris box with X11).
Write something with some meat on it. Write a client server chess program, where the AI is on a server and the UI is displaying in X11; once you've done that you will really know C.
I wonder why nobody stated the obvious:
Web applications.
Any place where the underlying libraries are entirely in C is a good candidate for staying in C - openGL, Lua extensions, PHP extensions, old-school windows.h, etc.
I prefer C for anything like parsing, code generation - anything that doesn't need a lot of data structure (read OOP). It's library footprint is very light, because class libraries are non-existent. I realize I'm unusual in this, but just as lots of things are "considered harmful", I try to have/use as little data structure as possible.
Following on from what someone else said. C seems a good language to implement the language in which you write the rest of your software.
And (mutatis mutandis) the virtual machine which runs the rest of your software.
I'd say that with the minuscule runtime environment and it's self-contained nature, you might start by creating some CLI utilities such as grep or tail (or half the commands in Unix). Anything that uses only STDOUT, STDIN and file manipulation is a good candidate.
This isn't exactly answering your question because I wouldn't actually CHOOSE to use C in such an app, but I hope it's answering the question you meant to ask--"what would be a good type of app to use learn C on?"
C isn't actually that bad a language--it's pretty easily to understand your code at an assembly language level which is quite useful, and the language constructs are few, leaving a very sparse language.
To answer your actual question, the very best use of C is the one for which it was created--porting itself (and UNIX) to other CPU architectures. This explains the lack of language features very well; it also explains the existence of Pointers which are really just a construct to make the compiler work less--any code created with pointers could be created without it (just as well optimized), but it becomes much harder to create a compiler to do so.
digital signal processing, all Pure Data extensions are written in C, this can be done in other languages also but has had good success in C

Resources