Ask HN: Should I learn C?

55 points by lukeqsee ↗ HN
I'm a recent high school grad going into college as a comp sci major. I have 2 years experience in Python and JS.

Would it be worth my time to learn C (C++ possibly?)? (Or maybe you have another language that would be more profitable now.) I'm aware I will have to learn at least C for college, but is it something I should learn now?

I'm looking for your opinion because a lot of you have either gone through a comp sci degree or have done some programming in C.

Thanks HN!

97 comments

[ 3.0 ms ] story [ 164 ms ] thread
Yes, you should learn C. And enough assembly language to understand aspects of how C works, like what a "stack frame" is.

Now is a great time to start. Go find K&R, fire up Linux and write and compile "hello, world". Then keep going until you experience your first segmentation fault. ;)

(Do not study C++ at this point. Study C. These things turn out to be very very different.)

> Then keep going until you experience your first segmentation fault.

Or your first cryptic compiler error. I'm pretty sure mine was "numeric constant contains digits beyond the radix".

A good book that goes over both C and assembly is "Hacking: The Art of Exploitation". The first 100 pages alone will give you a solid understanding of what is happening behind the code.
I can't recommend that book for learning C and assembly. Its coverage is amateurish and unprofessional, which are indicative of or at least encourage fuzzy thinking. You can read it for a time-efficient overview, but please don't go thinking you know C or assembly if that's all you've read.
For clarification, the recommendation was not for learning C and assembly, but rather to get a good feel for what is happening at a lower level ie. stack frames, stack pointers, etc.
At my university we have a course that goes over all the levels of abstraction between the hardware and systems-level UNIX programming. I never took the class, but I followed the course book on my own and it proved to be one of the most enlightening self-learning experiences I've had with programming. The book is Computer Systems: A Programmer's Perspective, and I highly recommend it.

I've found that even though I now spend most of my time programming in higher level languages, my understanding of C and assembly, compilers and debuggers, the virtual memory model and system memory hierarchy, and CPU architecture are still very valuable in helping me reason about my code and how it interacts with the rest of the system. I also still have developers at work on the C development team occasionally come ask me code questions, and often the answers to their questions come down to understanding one of the above better. If you can master multiple levels of abstraction you will be a much more effective developer.

ISBN for anyone interested: 978-0130340740
For learning C I strongly recommend C: A Reference Manual (Harbison and Steele), not K&R. Read K&R for context, sure, but Harbison and Steele is more up-to-date and comprehensive while still a concise language reference. That book can basically answer almost any question about the language standard that isn't compiler-specific.

http://www.amazon.com/Reference-Manual-Samuel-P-Harbison/dp/...

Read both, and then C Interfaces & Implementations by Hanson. Best advanced C book, ever!
since I had to look it up, maybe others don't know:

K&R refers to: The C Programming Language by Brian W. Kernighan and Dennis M. Ritchie

http://www.amazon.com/exec/obidos/ASIN/0131103628/thedinosau...

I feel compelled to add that I tried to learn C from a half dozen other books over several years (starting in childhood, so it was probably a bit early), but it never made any sense until I worked through K&R. Suddenly, C seemed like a beautiful and simple language (which it is). There are many subtleties, particularly in the macro system, that are not covered at all by K&R, but it is, by far, the best choice for learning C.

In other words: Don't waste your time trying to learn from anything other than K&R, at first. It's just the most concise text available...C is a concise language, and it is not well-served by big fat books.

You, and it seems most others here are suggesting that you learn C by doing some systems programming; I was thinking of dabbling in C, but maybe starting out by doing something with AVR/arduino or something like that.... Is the C your write for embedded stuff fundamentally different from the C you write for linux? I would eventually like to know how to write a php module or something like that, is starting by hacking on linux or some other os a better start?
I think the real value of C is how it deals with lower-level stuff- embedded systems, drivers, kernels, etc. Writing something like a PHP module would make more sense in another language (and then wrapping it in C if you need to).
I'm sorry but I think this is bad advice.

I'm not against learning C in general. I think everyone should. But his question isn't should he learn C ever it's should he learn it in his spare time between High School and College

The best thing I did for myself during college was to program on my own time in languages that people use out in the world. Learning C, Assembly, Data Structures and all the rest is great but when you get out into the world it helps to have been programming in Python or Ruby for 4 years and be experienced in that.

So I say "No". Learn C in school but in your free time I suggest you learn Python (Here's a great starter book I used when I taught a class on it: http://www.amazon.com/Python-Programming-Absolute-Beginner-3...)

I already am fluent in Python. I've used it in real world stuff for 2 years. I also am in the midst of learning Ruby (with _Why's guide).
Even though C is used more and more rarely outside of systems programming, I definitely recommend learning it. Learning about pointer arithmetic, memory management, etc... will give you a depth of understanding in other programming languages that other students will be sorely lacking the first few years of college. Other than a little OS-hacking on the side, I've never used it for a project, but understanding how C works has helped me debug much more effectively in several other languages.
It's also very useful for extending other languages by binding a library.
agreed ... since you seem to be proficient in Python, one potential exercise is to write a C extension to the Python interpreter or C library modules for high performance
This also has the extended benefit of learning more about how Python is implemented, which always helps!
Can you extend on this a bit.
It is used a lot for embedded systems programming.
I, like many here, would strongly recommend learning C. I don't know if I'd call it "profitable" to do so at the moment, assuming you mean profitable in the money sense.

C is a good language to learn, and a lot of interesting, well-paying jobs use C, and a lot of interesting open-source projects use C -- but if you just want to make steady cash, you can do so much easier with Java or PHP.

That said, if you go about your programming self-education correctly, you won't have a problem using Java or PHP (well, you won't have a problem in the sense that it won't be difficult for you to design programs in those languages).

It's good to have a handle on how the architecture of your machine works. C gets you much closer to that, and you will learn about a lot of things that are hidden from you in HLLs like Python, but that are still relevant to non-trivial programs.

So yeah. Learn C if you're passionate about comp-sci, or software engineering. If you're learning programming only for a career, it may not be as beneficial for you. Learning C before college is definitely a good thing.

Also, if you learn C, the last chapter of SICP is much easier to do, and you should go through SICP at some point ;)

Don't touch C++ until you need to touch C++. You'll know when that time is, if ever.

I don't know if I'd call it "profitable" to do so at the moment, assuming you mean profitable in the money sense.

I was meaning the in overall sense; "profitable" as in good for me. Sorry for the misunderstanding.

Ahh, in that case learning C is a veritable goldmine!

Edit: Also, if you use linux and end up going down the rabbit hole a bit, C is a prerequisite.

Being good at C can be very profitable in a money sense of the word too. Bloomberg is one example that hires a lot of C hackers and pays them obscure amounts of money (very very long hours though)
True, but it generally takes quite a bit of time to get to the point where you're "money profitable" with C compared to higher-level languages that are in popular use.
I wouldn't call their salaries obscene when you consider the cost of living around NYC. But they are great if you are single and don't mind living in a tiny apartment.
There's a still a lot of C questions in interviews, plus usually bonus points for knowing it - it can definitely be literally profitable even if you never use it for anything substantial.
A lot of people take the route of not learning C. If you do web development and your team finds something hard or impossible to do, watch their reaction when you say "I'll just write a C extension."

The stack-frame comment is spot-freaking-on. Knowing this level of detail will make you a way better programmer in every other language because you won't make stupid memory hogging decisions or mistakes. You also understand the complexity of doing things one way and the tradeoffs of another.

I best learnt C by re-writing large portions of the Pintos operating system. It's an academic OS and will be interesting to look at the source. Systems programming is where C packs the most punch, but all of those concepts can be re-applied in user land for some amazing effects.

this makes me wonder if DHH (David Heinemeier Hansson) knows or has ever learned C.
(comment deleted)
It's better if you dont ask!

I don't believe that Linus ever asked (someone else) if he should learn C. Or that Damien Katz (couchdb creator) ever asked if he should learn Erlang. Or if Brad Fitzpatrick (Livejournal & Danga) ever asked if he should learn Perl!

Just learn what you (from looking around) believe will make you a better or smarter, what is even more important use what you learn. Don't just learn to learn!

"A penny saved is a penny earned." Just as a minute saved is a minute gained. I asked to save myself time. Hindsight is 20/20, and a whole lot of people on here have hindsight.
You are wrong. Penny saved is the subject of income tax :)
Maybe they did. It's not like you'd know.
Yes! Learn C!! But learn it with a view towards using it to inform your use of other languages. The low-level aspects (pointers, memory management, working with .DLL or object libraries) are things that most languages, however fluent or high-level, use under the hood.

Spolsky and Atwood argued this out in Stackoverflow Podcast #2. http://blog.stackoverflow.com/2008/04/podcast-2/

Just get a comfort level with it (C), and move on. It will pay dividends.

I really only have experience with web development with Rails and in PHP. I also have done a little Java at school. I am considering diving into iPhone development and learning Objective C. Would I get at least some of the benefits of learning C that you all have described in this thread from Objective C? From what I understand you even have to learn some raw C to work with Objective C.
Objective-C is just a layer on top of C (and inlcudes a C interface to the runtime as well). Knowledge of pointers and memory management is required in Objective-C. Objective-C methods _are_ C functions. I would imagine it would be hard to be effective at Objective-C without a working knowledge of C.
The answer is "yes, some". You will have to deal with pointers and memory allocation, though I believe the newest ObjC runtime has a garbage collector so your exposure might be limited... if you're lucky. ;) And you'll get a general exposure to C syntax, the compilation cycle, et cetera.

From a strictly pedagogic perspective, it would also be good to spend some time studying vanilla C and the POSIX APIs. When we say the phrase "learning C" in a thread like this one, we tend to actually mean "learning to work at a lower level of abstraction, closer to the OS, to assembly language, or even to the hardware itself". And I believe that most of iPhone development consists of telling Cocoa to do things, and Cocoa is presumably not a very low level API -- thank god.

However, any C is better than no C, and iPhone development is fun and useful, so if it inspires you, go for it.

Absolutely, yes.

+ From the point of view of Python or Java (say), it's close enough to assembly language to let you understand how things might work;

+ If you need speed or control over hardware, sometimes it's your best route to extend whatever you're working in;

+ In many jobs you'll be the only one who has the knowledge to do unusual things, hence you'll be more valuable;

+ It gives you another point of view when designing systems;

+ You say you'll need it for college - learn it now;

+ A spread of languages is critical if you want to master programming.

You can carve out a perfectly good programming career without knowing C, but it's always of benefit and value to get a wide range of skills. Some recommend:

+ Pure OOP: perhaps smalltalk or Self

+ Pure Functional: perhaps Haskell (non-strict) or ML (strict)

+ Pure Imperative: perhaps C

+ Pure Logic: perhaps Prolog

Other hybrid languages are useful and perhaps more productive, but it's the ideas that really matter while you're still learning.

I'd just add that c teaches you about pointers and how objects are stored in memory which is useful in whatever language you end up using.
Good post. Not sure C qualifies as "pure imperative" - it has expressions and functions after all. I'd think a true pure imperative language would have to be either assembly without macros or something like Forth (where IIRC each "word" is a self-contained command that performs an action on the stack etc.)
I'm not sure about aiming for "pure" languages. Lisp is functional enough that one can learn pure functional programming using it, if he tries. And Ruby is OO enough that one isn't missing much, isn't it?

Nothing wrong with the pure languages as options, just I think impure languages can fit the categories too.

I would recommend Ruby, too. Even though I don't write large programs or webapps in Ruby, I use it to write the occasional script to glue different things together.

I think that there's probably more (practical) benefit to be had with Ruby than Smalltalk or Self.

+1 learn different paradigms. Besides reading language tutorials, read some PLT (prog lang theory on Lambda the ultimate, and these survey type things. (And you'l frequently see ruby, python, erlang folks say "We have to drop down in C to get plausible performance" or "this algo was already thoroughly tested in C or java". You kinda have to know C and java to get s##t done.

http://mvanier.livejournal.com/998.html

http://matt.might.net/articles/best-programming-languages/

http://www.info.ucl.ac.be/~pvr/VanRoyChapter.pdf

http://www.info.ucl.ac.be/~pvr/paradigmsDIAGRAMeng101.pdf

http://www.slideshare.net/brweber2/functional-concepts-for-o...

-----------------

Oh, SICP and books like PL pragmatics

http://www.amazon.com/Programming-Language-Pragmatics-Michae...

----------------

and i love "Traps/pitfalls" from 1989!)

http://www.amazon.com/C-Traps-Pitfalls-Andrew-Koenig/dp/0201...

C is lingua franca of programming languages. Even if you don't find yourself programming with it, it will still be useful.
You won't learn anything unless you need it, and it depends on your interests whether you need C in your programmings.

Other than that, I can't speak for anyone but myself.

For me, C has taught me so much since I was 14 that I couldn't possibly be where I am if I hadn't spent years writing C and I couldn't possibly recommend anyone not to learn it. But it's a different world for everyone and I can't say it's a bad thing if you don't know C. It would be a bad thing in my line of business but not everyone does the same things I do.

One thing about C is that it's a nice forced marriage with the von Neumann machines we're using these days. If you really want to know C, you really want to know the current hardware architecture as well. It will change but it won't do that at least in the next couple of decades.

On the other hand, mastering high-level languages first and dropping down when necessary might be a wise choice, if you only know you can do it. Like I said, architectures and paradigms will change in the future, and higher-level languages can embody abstractions that are very hard if impossible to contain in a von Neumann machine and it is the revolution of some new architecture when C will eventually be obsoleted.

An irony is that von Neumann architecture - specifically, code and data in the same memory space - is not modeled by the C language in its most distinguishing sense, and would arguably be better modeled by a language with first class functions. First class functions - the notion of creating new code, and passing it around as if it were data - capture this essence, that the data and code lie in the same memory space, and that both are potentially mutable.
No, you should learn Java instead. The leap from Python to C would be atrocious, but the leap from Python to Java would be feasible. (And if, after feeling comfortable with Java, the leap from Java to C becomes reasonable too).

You'd want to learn C to get a feeling for how the computer works at the core, but more important than that you should be seeking a rock-solid foundation in proper coding methods and structures that has potential off-branches into your courses and your career.

From Java, you could pursue Android development or even Objective-C for iOS development. From C, that transition would be frustrating to say the least.

(Other points behind pursuing Java is you'd find it quicker to start testing on your local box without needing to seek help, it'd give you great insight into what an IDE is and why it is your best friend, and there are more community projects surrounding Java than C that you could start to participate in when you're ready.)

In the end, any language you want to learn would be a good language to learn (even Fortran), but you should go after a language that you can go from 0-to-novice on your own in a short time where you'll end having built a nice repertoire, and I think Java would best suit that need for you.

C yes, C++ no.

Make sure you're using a C compiler, not a C++ compiler

Here is why not C++: http://news.ycombinator.com/item?id=1463592 and why not java

Edit: Was there something wrong with my comment? Or were you downvoting merely because you disagree?

Those are not reason on not to use C++, but reason on why some people shouldn't be using C++ in the first place. Yes you can do it in python unless you want speed, if I am to interface my python code with C or C++ why can't I write them in C++ in the first place? Also if I were to interface any scripting language code with C I would probably go with Lua.
I'd say "It doesn't work well in most shops" is a damn good reason to not use something.

In general, very little of the program needs to be written in C to get great performance gains.

Additionally, python is vastly different from LUA. Lua is still a scripting language, ruby and python have moved past that.

For someone at age 18 or so, I'd say C is a much much better level of complexity to be tackling that C++

Absolutely yes.

There's no downside in learning C, and there's not much fluff in the language core to complicate things, or slow things down.

I'd suggest you get a copy of K&R: The C Programming Language and just work through the text and examples. You might also want to pick an existing C-based project and work on bugs in it, maintenance programming being one of the best ways to get to grips with using the key tools, gcc and gdb.

This way you'll get a feel for the language, and also for what you'll need to debug and fix code.

One downside to learning C is that you will have to resist the temptation to use C on projects where much safer and more productive languages are feasible. Being able to use it speaks well of you, but actually using it is rarely a good decision these days.
I get your point, but there's a lot of pretty solid apps running just fine on iOS that are primarily written in (objective-)C.
Yes. You won't really know python or javascript until you learn C. You may gain some empirical knowledge about how various parts of those languages operate, but without knowing C, you won't understand the "why". If you understand the "why", you'll occasionally be able to intuitively see solutions that would never have occurred to you otherwise. Those are the sorts of key problems that can make all the difference in the success of the project and of your career.

Any language you learn will make learning additional languages easier and faster. But, the boost you get from learning C is arguably greater than for other languages. It's also the single most powerful backup language you can know.

I would suggest Python and C, in that order. Python will let you quickly have fun building large applications, and it will teach you object oriented programming. Once you know what a loop is, though, go by "Advanced Programming in the Unix Environment" and a decent C book and trip out on that for a year or so to really understand how computers work.

I don't write C for a living at all, but it is great to know how everything is working under the hood, and APUE will teach you that.

To be honest, I wouldn't bother with Java. I think in ten years Java will look like Ada does now: we will all be asking ourselves "What were we thinking?"

I also wouldn't bother working on anything but Unix, but that is just bias...

You should absolutely learn C - you don't need to be an expert, but you should fully grasp the use of pointers and memory allocation, and how the compiler really works (intermediate stages and all that).

This, for the same reason you should learn some provisional level of assembler on an older 8 or 16 bit processor with a simple instruction set (intel 8080 or 8086, and then maybe something RISC just for kicks). You don't need to be an expert, just dabble enough that you "get" how it works.

Also learn how to implemenet a few other progrmaming patterns in C - you can do OO in C, you can do functional in C, you can do concurrent in C. You likely won't have to in real life, but understanding those concepts at the level of C will really help you understand the benefits of higher level languages.

I'd say the same for any of the Lisps - learn one, even if you'll never use it - the insights it gives you are worth it and will make your other code better.

I wouldn't recommend learning assembly on the 8080 or 8086. These systems are register-poor, which makes programming on them frustrating. Instead, try ARM or perhaps MIPS. If you learn ARM, you'll probably end up programming at a higher level on it in the future.

On second thought, learn assembly language for a platform you can run it on. If you only have x86, learn 8086.

My answer to the question "Should I learn <programming language x>?" is almost always "yes". Even if you never need to use it, it's always good to have a different way of looking at things.

One thing you might want to look at is cython[1]. It allows you to write C extensions in a Python-like language. Could be useful as a "bridge".

[1] http://cython.org/

Yes, learn C. I've tried to avoid it for years, but it's actually a beautiful and simple language. It's very powerful and low-level, which means that it's easy to create ugly programs, but that's another problem.

If you ever have to do low-level programming or Mac/iOS development it will definitely be of great use.

In my opinion, instead of asking and spending time reading the comments of everyone saying why you should learn C, you should have actually learned C. It's a great language and learning it will surely help you in your career.

Think of it this way: Why not learning it?

I asked this question for two reasons:

1) I had already started learning C. It is low-level, and I was getting disinterested. I wanted to know if it'd really be worth the work to learn it. (The answer is absolutely.)

2) So that other people, when wondering if they should learn C, would have a great list of hacker recommendations. (That has happened.)

If you are getting disinterested, do some project that C would be good at, like graphics, or a hardware driver, or an OS kernel.
Theoretical aspects:

I assume that you want to be a good hacker. A good hacker has a healthy mix of knowledge that will allow him to start work quickly on almost anything. Without a solid grounding in C, (and a perspective of JS and Python), there are a whole class of things that you won't be comfortable working with unless you have some lower level experience.

With your current knowledge, how easy would it be for you to start hacking on an IP stack? Not that you would ever need to, but with a good knowledge of C such a thing becomes natural to you. All of those RFCs begin to make much more sense.

Another big benefit to C is how simple it is. You begin to see how possible it would be to create a simple C compiler, and this is a good spot for this intuition. It has a simple syntax, is somewhat feature-poor, and is very close to the hardware.

Plus, you'd be able to hack on CPython if you want ;)

Practical aspects:

Your knowledge seems to say that you are headed for web development, which I applaud, because all things exciting are happening on the web.

Web development is changing. It used to be that web developers were laughed at, considered to be inferior to other programmers. It has been a few years since I've seen that opinion, and I think it has been thoroughly shown to be wrong.

Web development has become, essentially, a two part system where the pretty web front end sits as an interface to a super hardcore back end. Web companies now face scaling issues that are relatively new to web development. While you may never program in C, having a strong foundation on what the underlying issues are.

Either way you look at it, learn C is to get a better understanding of technology. It will certainly do that for you very well.

Short answer: yes.

Long answer maybe you also want to learn some assembler to see how the machine really work (I would recommend programming a simple microcontroller or the lego NXT things).

If you manage to learn C. It will be easier later to learn an object oriented language later. (Java, C# or C++)

The problem (and the frustrating thing) will be that you first probably wont achieve much by using pure c. Therefore you can also start with toolkits like processing.org which can teach you basics about algorithmic thinking.

Ah just saw that you did Python and JS first. So yes I suggest learning C or C++ (maybe C first, because it's easier)
Absolutely! By learning to deal with pointer manipulation and memory allocation, you can learn what it is, why it is necessary and how to recognize when it is broken. One of the problems with garbage collection is that it suffers from a memory management problem at a higher level of abstraction. There was an entry in an autonomous vehicle competition a few years ago that stalled. Physical objects in the environment were represented internally as objects in the code. When the vehicle passed them, they were moved to a collection of objects that had already been identified but were out of the field of view. That collection grew unbounded even with garbage collection because every one of those objects was still referenced.
There is no wasted knowledge, C is a primitive language, but could teach you things that many other languages cannot.

Consider proper memory management, et al. There are other languages that implement similar features that C does, but ANSI C is a macro-assembler in the truest sense of the word.

Pick up a copy of "The C Programming Language, by Kernighan and Ritchie" and do the exercises.

Good luck.