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.
.
Related
I'm a web developer mostly working in Ruby and C#..
I wanna learn a low level language so i dont look like an ass infront of my (computer science expert) boss.
Ive heard a lot of purist buzz about how assembly language is the only way to learn how computers actually work, but on the other hand C would probably be more useful as a language rather than just for theory.
So my question is..
Would Learning C teach me enough computer science theory / low level programming to not look like a common dandy (complete tool)?
Thanks!
Daniel
Thanks guys!
Some really great answers,
I think i'll learn C just to get a grasp of memory management, but i think your right and i'll be better off studying more of the languages i use!
First learn the actual theory. Learning C's syntax means nothing if you can't do anything meaningful with it. After you have a solid grasp of how algorithms and data structures work, this knowledge will be appliable in most languages you'll probably use.
If you're planning to work in C# and Ruby, I don't see the point in learning assembler just for the sake of doing so.
You'll be fine learning just C since it's C.
You can do "real programming" in any language, as long as you do it right.
Would Learning C teach me enough
computer science theory / low level
programming to not look like a common
dandy (complete tool)?
You're using C# which can perform unmanaged pointer manipulation, not too far off what you can achieve in C++ land. For instance, games can be successfully programmed in C#, although most games will be C++.
Assembler is basically moving bits of memory around and sometimes doing a bad job of it too if you don't know what you're doing. C++/C compilers create quite good assembly code underneath, so why would you do it yourself unless you had to write low-level driver software. The only bit of assembler in our 2,000,000 lines of mixed C++/C# code is to detect VMWare.
I don't think in this modern age and given your description of your job there is much call for you to know about how many registers you can use on your processor. By all means learn C++, but as mentioned before, learning syntax is not the same as learning how to apply it.
At a minimum learn and understand patterns (Gang of four), OO design, understand the implications and benefits of different testing methodologies and the impact of all this on business costs.
Learning C will get you all the information you need and be able to accomplish things in a reasonable time.
I suggest you do a few meaningful projects in C, then one or two in an Assembler dialect, maybe for a Microcontroller or specializing in SSE/MMX.
In the end it all comes down to opcodes, registers, and addressing modes, of which C teaches you absolutely nothing. However, assemblers are tightly coupled to their platforms; learning how to write assembler on x86 won't help you much when you work on a Sparc or PA-RISC box.
C really isn't going to teach you much that other languages won't in terms of theory. The thing about C is that it doesn't provide many tools or abstractions beyond naked pointers and byte streams. You have to roll all your own containers (lists, stacks, queues, etc.), and if you want them to be generic, you have to figure out how to separate the code that needs to be type aware (assignments and comparisons) from the general algorithm. You have to manage your own memory. Text processing is a pain in the ass (C doesn't even provide a dedicated string type).
Is that something that would be useful to know for your day-to-day work, or to impress your boss? Maybe. I'm not sure how you would apply that knowledge in your C# or Ruby code, which operates in a virtual machine (as opposed to native binaries generated from C).
You want to impress your boss with Computer Science knowledge, read up on Turing machines and Markov algorithms.
I don't think knowledge of Assembler would make you a better Ruby / C# programmer.
You can go as low level as writing to a disk using a magnetized needle, but if your programs aren't working or are insecure, you wouldn't have gained anything by it.
Learning the syntax of a "new" language won't assist you in gaining more knowledge of the depth of programming.
Real programming is not about a particular low level programming languge. To understand how a computer works it would be not bad to know some CPU instructions and how the hardware processes them.
To become a good programmer it is absolutely not necessary to know how the hardware works, except you want to program hardware.
I wouldn't worry about looking like a fool in front of that boss if that's the criteria your boss has for not being a fool.
C and Assembler isn't the best languages if you want to learn computer science. As you know Ruby and C# I guess you know some object orientation.
"Real programming" works the same in every language and that's what you should really worry about. That being said, working up something in C is a very useful exercise/
Learning C won't necessarily teach you too much about how computers work, but it is a good access door to that, considering that it is still the language of choice for system programming.
Learning ASM is of course useful as well, but it's probably uncalled for if you want to apply it to your job. It might teach you a few useful concepts though, or at least help you get a better understanding of how CLR works (or in general, how bytecode compilation and bytecode-compiled code do their stuff). Maybe you could try learning ASM for an older/simpler platform; there's still a heavy Atari 2600 scene around, and due to the platform's inherent limitations, some of the hacks they do to squeeze some extra functions in a game are quite awesome. The modern x86_64 architecture is pretty complex and somewhat hairy, although that's more of a personal opinion than an actual fact. Learning to use a microcontroller might also get the job done, but be warned that many (most?) use a Harvard architecture (i.e. separate program and data memory) which is different from that of a typical general-purpose CPU.
ask your boss first, than do exactly what he tells you, finally ask again for feedback and review of the exercises you will do. act accordingly. repeat until he says "you now know more than me".
this is the more efficient way of exploiting the expertise of a real expert you have the luck to have, and will leave extremely positive impression forever.
it will be as difficult as learning C or assembler alone in your spare time.
I wanna learn a low level language so i dont look like an ass infront of my (computer science expert) boss.
This is like so true in many aspects, I learned c++, and haskell for similar reasons, I have no regrets since they taught me many things, but I do understand the peer pressure.
This is a 6 years old question, and it is interesting to see that no one mentioned a good textbook on programming that covers the fundamentals of computer science.
If you want to learn "real programming", just try to tackle
"Structure and Interpretation of Computer Programs"
by MIT Press in your free time. It should cover most if not all of your curiosity with respect to programming whatever your level is.
There is also "The Art of Computer Programming" by Donald Knuth. Knuth is especially well versed in machine languages and other low level stuff.
Beware though both of these works are very dense.
Here is my two cents on how to approach them. First of all, they are not "tutorials" that sugar coat your way towards a skill, they introduce a scientific discipline in an appropriate manner, so the mind set of "what am I going to do with this? How can I use this ?" should be replaced by "how does this work ? What does this do ? Why does it do it this way ?".
Try to do the exercises included in the books, but don't push yourself too hard. If you can't do it, it is okay, pass to the next one.
However if you are not doing any of the exercises given in a section, you should take your time with the chapter, and revise it so that you can at least do couple of the exercises included for the section.
Just keep this up, and you would caught up with your boss/peer in no time. Some chapters/exercises might even be a subject of conversation if you feel like it. He might even like the fact that you are acquiring new skills, or not, don't take my word for it, I do programming not to deal with people.
Well, "Real Programming" doesn't refer to a specific language, or low level languages. In my mind, "real Programming" is the process of analyzing a task, deciding the best way to solve it, and putting that method into a set of simple steps, and then revising and editing as necessary until you have achieved your goal. From that, the language doesn't really matter, it's all in the thought process. Furthermore, there is nothing wrong with high level languages, I use python all the time and love it. However, learning low level languages can really help develop your understanding programs and computers in general. would suggest c, because it is where c# and c++ stem from, and would provide a bases for understanding both those languages.
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).
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
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.
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