tags:

views:

11447

answers:

76
+115  Q: 

Should I learn C?

+1  A: 

as the person who originally asked the question about learning C++, I say yes.

contagious
+11  A: 

A major motivation for learning C, in my opinion, is if you don't have a really solid understanding of how code interacts with memory. Java and C# are so abstract and almost magical in their management of memory, that it's easy to be an expert in either, without ever really knowing what's happening under the covers.

I'd say learning C is overkill just to understand memory as there are plenty of great articles out there, but it's something that you ought to be able to pick up very quickly given your experience.

Karl Seguin
Agreed! And among all languages without automatic garbage collection (Pascal, Fortran etc), C is the most flexible -- it has pointers and allows you to do whatever you'd do in assembly in a direct and clear way.
Jay
+26  A: 

I think you should know enough C++ to be able to understand the Java runtime (both the native class library code, and possibly HotSpot itself if you run into its bugs). Also, if you're using CPython, then enough C to be able to peek into its internals as necessary, and similar comment about whatever Scheme interpreter you use.

This relates to what Joel said about leaky abstractions, and I agree with him: all meaningful abstractions are leaky, and when they do leak, you need to be able to know what's beyond the abstraction. Eric Sink has an article about abstractions too.

Knowing C is also very useful if you want to write foreign function interfaces (FFIs) for your respective languages, because most FFIs accommodate C to some degree (and if you're using Boost.Python, then C++ too). Knowing how to write FFIs are useful if you need one language to be able to use functionality in another language.

So, you may not immediately need to know C, but I believe that in the longer term, knowing C will add to your toolkit, and allow you to solve a greater set of programming problems, such as by writing new extension modules when you run into the limits of your programming platform.

Chris Jester-Young
+11  A: 

I think one of the most important things about having a C background is understanding basic data structures, like how a true array is implemented differently than a list, map, etc. I think it would be a major help to read up on how to implement a linked list and why you would, versus just declaring or allocating an array.

As far as learning all the syntax and standard libraries, I'm much more ambivalent. I just like to have a basic idea of what Python is doing when I ask for one data structure over another.

saint_groceon
+113  A: 

My answer is "yes, but don't feel pressured to do so". I think learning C could be considered almost a historical experience, as it is the origin of most modern syntax. Besides, you'd be hard pressed to find a programming book better than The C Programming Language - it's just so brief and readable.

All that said, it is certainly not essential. If you want to, try it. If not, don't.

Bernard
Historical? C is one of the most powerful beautiful languages created. I use C day-in-day out for projects that need to be fast, lean and clean. IMHO many of today's technical problems arise from people not keeping-it-clean and simple. If I didn't have C, my programming life would suffer. Never-mind the fact that much of today's critical software (Kernels, Embedded systems, drivers) are written in C.
Aiden Bell
I meant historical as to someone who had spent their programming life with Java/C#/whatever with C-like syntax. C is good for some people. I'm not making a judgement call on the relevance (or lack thereof) of C.
Bernard
You can usually tell that a programmer works mostly on desktop applications or enterprisey systems if they say that C is "legacy" or make similar remarks. There's much more software out there than what you'll find running on your desktop (or on your server). Almost all of it is written in C.
Dan Moulding
C is not legacy. You can do almost every thing through a C program in most of the cases. Try it. It will increase your knowledge of how a compiler or a programming language works.
Enjoy coding
@Dan: I'm running Debian. Most of the desktop software I use _is_ written in C. =pI do want to point out that at no point in my response did I call C 'legacy'.
Bernard
I agree about the "historical experience". It seems to me it would be akin to a native English (or Romance language) speaker, learning Latin. It could certainly improve your native tongue, will allow you to read "the classics", and may even inspire you to write classics of your own.
George Jempty
C is god of Programming language. It is the Origin, without origin nothing could exists.
Ram
I'm not quite sure what you mean by that, Ram. It's certainly not the first language and directly responsible for the look and feel of a lot of modern languages. But if C hadn't existed, it would've been some other language that did the inspiring.
Bernard
@Bernard, Ram: No, C really is the language of the Gods.
Matt Joiner
@Matt Joiner: Amen.
Bernard
+1  A: 

I guess it depends

Personally, I spent a bit of time learning C and got a lot of benefit from it (but it was the first language I really learnt after college). I've since done a good bit of C++ and some Java and I found knowing C helped me for both of those languages.

If you are only going to code, as you say, "enterprisey" systems, then you'll probably never need to use the more esoteric elements of c (and there is absolutely nothing wrong with that).

If you have a bit of spare time, pick an area that C is particularly strong in (anything that requires lots of speed and tight control over memory, image/video processing for example) and try coding in it to get the benefits of C knowledge.

And yes, when you want that linked list, you are going to have to write it yourself - using structs and pointers!!!!

Lehane
+46  A: 

Well I think you shouldn't learn C, who needs it, right?
Its not like mathematicians learn any old math, right?
And its not like physicists learn old theories, right?
And its not like professionals of any other field learn anything more than a decade old, right?

Oh, wait...

Peter Coulton
+1 for pedagogical sarcasm
willc2
I second this oppinon
sum1stolemyname
this is so 1==1 (true)
Necronet
+93  A: 

C is valuable to understand the following:

  • Pointers and addresses
  • C-style strings (null terminated)
  • Dynamic arrays (malloc( n * sizeof(int) )
  • Memory management & the pain associated with it (malloc/free)
  • Bitwise manipulations, issues like big/litte endian byte order
  • OS primitives & signals
  • Common problems: Segmentation faults, core dumps, following NULL pointers

Learning about these topics is different from building a full OS or compiler (which is what C is "good for"), since it's overkill in most cases. You could start with a simple program to allocate an array and walk through memory. Then make a linked list and follow it along. Use a good debugger like GDB so you can step through your program and see what's going on. C can be painful otherwise.

It's valuable to see how these concepts work under the hood, but they usually aren't necessary on a day-to-day level.

kurious
Aren't some of these concepts actually specific to C? Pointers, C-style strings, following NULL pointers... . So while it's true that C teaches you about them, it's a tautology.
sleske
Agreed -- things like C-style strings are specific. But many of the other concepts have analogues in other languages. Following NULL pointers can happen in other languages (pass something by reference, reference is null), pointers/references in general appear all over OO languages (pass by value, pass by reference), bitwise manipulations is a data-level thing (independent of language, but used all over C), memory management happens when you want to give hints to the GC in your destructors, etc.
kurious
+1  A: 

Like Jeff I never learnt C or C++. I ended up in programming by a sort of accident and learnt vb 6 followed by C#.

It was only until I joined a larger company working on big projects that I found I had missed out on some core principles that on my own smaller projects I never worried about.

Looking back over those years I would have benefited from learning C at the start but I have now learnt many of the skills over the years and I feel I would only gain a small advantage by learning it now.

I guess all in all it depends on your situation but I believe how things work under the hood even in a world of managed code is very important not to cause your self headaches down the line. For example if you no nothing about memory management and your calling unmanaged code, when to use a hashtable over an array, why and when use structures instead of classes etc.

John
+55  A: 

"Should I learn C?" is poised to become Stack Overflow's version of "Should I use vi or emacs?" :)

In the Pragmatic Programmer, Hunt and Thomas offer a bunch of tips for becoming a better programmer. One of the most important tips is:

"Invest Regularly in Your Knowledge Portfolio; Make learning a habit."

Regardless of whether or not you will ever use C (or Scala, or Lisp, or Modula 2, etc.), there is no harm in learning something new. In fact, learning a new language will force you to look at problems from a different perspective, offering insight into different (and sometimes superior) solutions, regardless of implementation language.

If you're interested in learning something new, and consequently improving your skill as a programmer, you should definitely learn C, or Scala, or Lisp... You get the idea.

Matt
I second this. Learn everything you can, even if you have no reason to do so.
Jeff Hubbard
seconded whole heartedly
Kris
thirded^Wfourthed
mlp
Exactly. When you're a Formula 1 driver, you don't just drive F1 cars. You drive rally cars, go karts, family sedans and even boats. Sure, they might be completely unrelated, but each provides a different way of doing the same thing, and you can only get better because of it.
Dominic Bou-Samra
+6  A: 

Yes, you should learn C. Just like all Americans should learn a language other than English. :)

I agree with what other people said in that it's good to learn how memory allocation works, how to actually and efficiently implement data structures, do bitwise operations, how to — for example — implement a memory efficient XML parser that can handle a 2 gigabyte document being fed to it.

You may never need to use it directly, just like you may never need to use those 6 years of French, but at the very least the ancillary knowledge you gain in learning it unquestionably makes you a better programmer. All else being equal, you should learn it just for the sake of learning new things... and Python and Lisp and Ruby and Erlang too. Of course, here in the real world there are obviously limiting factors like there being only 24 hours in a day, and you have to sleep sometime.

C looks good on a resumé and if you can do interview programming problems in C that is a huge strength. I give points for that, even if the position we're hiring for would be in higher-level languages like C#, Java, or Python. In some ways it's an "old boys" club, but in others it means that I could trust you to find and fix a memory usage problem in our Python app.

Joe Shaw
+1  A: 

Learning C will help in the future as far as your understanding of low level concepts goes, but you really need to ask yourself if you actually need to know about them.

If you planning on writing a compiler, or one day turning to assembler, then yes, learn C. On the other hand, if hardcore memory management (that isn't really that complicated), pointer arithmetic and a deep understanding of hardware isn't something that is essential to you or your career, skip it.

I need to use C++ for various tasks, so I have to learn that language. I have never once needed to use Haskell, so I'm not going to learn that language. Of course, it would be nice to learn every language under the sun, but remembering the awesome article by Norvig, you need to ask yourself if you could put enough hours in to learning C to become useful at it.

PaulH
+1  A: 

This may not apply to C - perhaps it represents some magical exception - but in general I've found that there is learning something, and learning something. As in, you can read about it, try it out, and hopefully understand it, but that isn't the same as using it to make something for real. Personally I have no interest in learning C or these low-level things. I studied Von Neuman architectures and even some assembler at uni nearly 20 years ago, and I've never been able to understand the relevance of that stuff to userland world of application development that's been my career for the last 10 years. Maybe it's just me.

Flubba
+1  A: 

As several others have mentioned, learing C will teach you about pointers, memory management, dynamic arrays, and other low-level features that more modern languages handle for you. I learned C in college, but have not used it professionally; however, I think I've benefitted from having seen what's going on under the hood.

That said, I wonder if it's possible to get a peek under the hood without learning the entire C syntax. Other than learning an assembly language, I can't think of another way off the top of my head, but somebody else might have some ideas.

Bruce Alderman
+1  A: 

C is a small language which won't take you long to learn, especially with your programming background. It's also a great route into many powerful scripting languages, such as AWK, as a lot of the syntax is shared.

As Kernigan and Ritchie say in the preface to "The C Programming Language":

"C wears well as one's experience with it grows"

David
+1  A: 

I say yes. James Delvin of Coding the Wheel writes an excellent post: http://www.codingthewheel.com/archives/learning-to-drive-a-stick-shift. If you understand the low level stuff, you can better understand what Java does for you.

Ed
+23  A: 

The two most interesting courses I did at university was "functional programming in Scheme" and "Micro Controller System Design". I would definitely recommend learning some of these “historical” languages. Even if you don’t use it in your everyday work it is fun and rewarding to learn how things really work. Also, many of the ideas and concepts from functional programming are now moving into mainstream programming languages like C# and Java. Also the “The C Programming Language” and “The Structure and Interpretation of Computer Programs” (Scheme) is two amazing books “everyone” should read.

Learning C will also enable you to explore more exotic platforms like the Nintendo DS/Wii, the Sony PSP, or writing micro controller code. It will also give you a good foundation to learn Objective C if you want to get into programming for the Mac or the iPhone. Adding a link to my final project in the micro controller course – Super Mario Pong on the STK1000 developer kit.

Edit [Justin Standard]

Great Answer, Jonas. I think this is a much more practical example of why to learn C and what it can be used for than some of the others.

Jonas Follesø
+2  A: 

If you're interest in learning C is to understand how things work.. I'd suggest hitting an even lower level: Assembler.

Keep in mind Assembler is no easy task. Nothing is done for you. Nothing is assumed. There are some decent IDE's (for windows and unix - I know of none for mac). I think one of the best ideas learning Assembler will teach you is efficiency. Something modern languages forgot.

Stephen Cox
A: 

To C or not to C, that is your question... or is it?

What is your motivation to learn C? Are your bored, looking for something new to do? Do you think it will improve your employability? Need more ammo for "programming language X kicks your programming language Y" arguments? Why C, why not learn Ajax, or some technology that could apply to your current 'enterprisey" work situation?

Maybe, instead of questing forth on why to learn C, decide What.
Design an application and then go about learning how to make it.

Tyronomo
+2  A: 

If there is any chance you want to play around with GNU/Linux, at some point it will be nice to know C at least as much as to understand compiler warnings.

If you know C, there are quite a lot of free software projects using it - this could be a good way to practice. Working on a real project is also good motivation to keep on learning.

Marie Fischer
+2  A: 

I've been programming for about 25 years now and when ever I am asked if I know C I respond - "I'm planning to learn C once I've mastered Assembler" ;) personally I have found my grounding in Assembler has been more than sufficent in allowing me to understand how things work - perhaps more so than those who learn C and not Assembler.

Martin
+1  A: 

Yes.

You'll learn about memory management, and that is good.

Terrapin
A: 

Marie brings up a good point in that C is quite a widespread language. If you are tossing up between C and assembly, I would say go for C because it could have some practical application. Not to say assembly wouldn't, just that C would be more useful on balance.

Bernard
+2  A: 

Is it better to learn C or Assembler? If Assembler, which one?

I'd say it's "better" to learn C, but it definitely is worth being familiar with assembly. The instruction set doesn't make much difference. At university I did some programming for Motorola 68000 processor. It is easy enough, and you also can get it run on Easy68k simulator.

Similarly with C. You don't have to become pro in that language, but it might be very useful to know some of it.

Armandas
+1  A: 

I think learning C is important for understanding memory management and pointers. I also think it is good to be exposed to assembler so that you have a better understanding of how the computer actually moves, stores, and processes data.

bruceatk
+2  A: 

I think you should learn C. I'm currently taking a course in C\C++ and Unix Programming this semester and learning C does feel rather liberating. The amount of time it takes just to cover the basics of the language isn't that long for anyone with any previous programming experience. The amount of work is well worth the reward.

I'd also suggest doing an Assembly language like the previously mentioned 68K. If you cover the assemly language first it will make learning C easier.

Nexus
+1  A: 

I would say no, but become familiar with the strengths and weakness of the language. Remember that programmers have a theoretical "toolbox" that they go to every time they need to solve a problem. Choose the best tool for the job based on your experience and knowledge of the tools at your disposal.

If you're writing a rich internet application, C is not the choice to use. If you're writing an application for a legacy machine with a finite amount of memory and needs to run as fast as possible, then C is probably the best tool for the job.

1kevgriff
+6  A: 

I cannot decide for you, but I can give you what learning C and Assembler would help you so.

C:
C programming is used today, in low level systems programming such a writing drivers, compilers, system utilities, operating systems, etc. Although, it also finds some application in other places, in general people are moving away from it to learn 'new' stuff and 'new way' of doing things.

However, in my opinion, learning C helps you understand the intricacies of memory management, data structures and helps you get in touch with a different way of doing things (which is quite a bit differnt from the object oriented way). It is very good language to learn about algorithm efficiency and hardware programming.

Since C is an old language, it has quite a number of offshoots which a similar like Pro*C, System C and others. Also as Jonas mentioned, C is also widely used across various platforms and systems like mobile phones (BREW), Nintendo DS, etc.

If you are interested in hardware side of things and GPU technology, you will also be able to better appreciate and understand the Nvidia CUDA platform.

Maybe if you get good enough, you might even want to participate in Obfuscated C programming contests :)

Assembler:
Assembler is a completely different beast altogether. Assembly languages help you fine tune and control how exactly you want to run each step of your program or application. Assemblers can help you understand how things work on a instruction set level, provide you with an a intricate knowledge of CPU instruction sets and CPU timing cycles. Its fun, but it is very easy to get lost when the code gets long enough, because of all the Jumps, and Long Jumps (similar to GOTO) scattered in the code.

I remember writing a utility similar to the modern CPU-Z, using MASM (Microsoft Assembler). A good place to start would be to look at Intel Assembler or MASM32 assembler.

Pascal
+6  A: 

Regarding the "C vs. assembler" question, I have a few off-the-top-of-my-head thoughts:

  • "Assembler" is a little ambiguous, as there is a different assembly language for each type of processor. There are common principles, but choosing which one to learn will have a big effect on how useful and/or painful the exercise is. Some assembly languages, like VAX or M68000, were designed to be easy to write. 80x86 is not, so that should not be the first one you try to tackle.

  • I learned a couple of assembly languages (6502 and M68K) before learning C. I think that helped a lot with learning C, as C can be seen as a "portable assembly language." If you already know how to manipulate bits and bytes and memory addresses, then C makes a lot of sense.

  • I'd recommend learning C first, then only learn assembly language if you are still interested in going deeper.

  • While some people like to lump C and C++ together, they are really different languages that support different styles of programming. If you want to learn C, then learn C. If you start with C++, then you may miss out on what is important to learn from C.

Kristopher Johnson
+19  A: 

Regarding C vs. Assembler: I'd still pick C because:

  • It is more portable than an assembly language
  • It's much more readable than an assembly language
  • The C Programming Language_ is perhaps the best concise introduction to any language
  • There is a much larger code base of C out there to download and study, if you really want to see what the language can do.

And even though it provides a certain level of abstraction, C is still close enough to the machine that it will make you think about what is happening inside the box. And that mentality will help you program better in whatever language you ultimately use.

Bruce Alderman
I dispute that C has a larger code base than assembly. Any compiled program can be disassembled into an assembly program fairly easy, regardless of the original language. By contrast, it's much harder to decompile to C or another high-level language. Any C program is technically an assembly program.
Chris Lutz
@Chris: This might be technically correct, but it is semantically meaningless. Assembler is mnemonics for machine code, and since, by its very definition, machine code is what is executed, _every_ programming language will be translated (compiled or interpreted) to machine code - which is but another for of assembler.
sbi
+1  A: 

C was the first language I learned. I rarely use it, but it's great to know even just to put other, more abstract languages like C# and Java in context.

It's also immensely satisfying to develop in C. It is tricky, sure, but the sense of accomplishment after completing even trivial tasks is unbeatable.

conmulligan
+1  A: 

I think C is worth learning, especially in combination with basic system architecture topics. The sys arch book I used in school was this one:
Computer Organization and Design

Part of learning system architecture will likely involve learning assembly and the basics of what makes up an ISA and how the instructions in the set are executed on a processor.

I believe that knowing C and how the machine works at this level will make anyone a better programmer.

Other than purely pedagogical motivations, there are other benefits to knowing C:

  • C compilers are available on almost every platform, from game consoles to desktop systems to the Mars Rover. Chances are, if it is a programmable digital computer, a C compiler exists for it.
  • C is one of the main languages for linux development (both kernel and application level)
  • C can be used to extend interpreters for other languages (Python, Ruby, Perl, etc)
  • C allows you to write code to take advantage of emerging hardware designs (think GPUs and CUDA)

Plus, I think learning C will be fun for most people.

Doug
A: 

In my experience, learning C is valuable in understanding how the bits move around all the way up and down the technology stack, particularly if you're a hardware guy like Jeff:

  • A little physics will teach you how semiconductors work, most notably transistors;
  • Put a few transistors together to create logic gates (AND, OR, NOT, etc.)
  • Assemble a bunch of logic gates to form a microprocessor
  • Tell a microprocessor what to do via machine code
  • Assembly language is a more human-readable way to produce microprocessor machine code
  • C is a great bridge between assembly and higher-level languages. C will help you understand Assembly and vice versa.
  • C++ is basically an object-oriented extension grafted onto C
  • And on to higher-level languages (Java, C#, etc.)
glaxaco
+15  A: 

I'd advise against it, for the simple purpose that you won't learn anything useful or insightful from it (horrified gasp from the audience). You say you know Java. Good. So you already know about dangling pointers, you don't need malloc and free for that. You know Scheme, so C or ASM won't teach you anything except uglyness.

On the other hand, I would (strongly) advise learning C++ because this is a whole different story there, at least if you don't program “mainstream” C++. Let me clarify. C++ actually allows a bunch of very different techniques (they call it multi-paradigm language for a reason). Probably the least interesting (but most practiced) technique is OOP. Why does OOP in C++ suck? Because 1001 other languages do it better than C++.

C++, on the other hand, is the best (I will repeat: the. best.) language when it comes to algorithms because its template semantics, coupled with the iterator/range idiom allows a very transparent, type-agnostic programming style.

This may not be of practical interest for many programmers (it is for me) but it will make them better programmers nonetheless, because C++ is 50 years of theoretical computer science condensed in one language.

Take C's pointers. They are the single reason that made C so important because they provide a perfect abstraction for the memory architecture of modern PCs. However, the concept of pointers is nothing compared to the much grander, encompassing concept of C++'s iterators of which C pointers are only one instance (a “random access iterator”). On the other hand, take Java's iterators. They, too, are only one instance of the more general C++ concept, namely an input iterator.

C++'s iterators may be the single best concept in all of computer science, and I challenge anyone to find something more general and useful (… and I immediately exclude recursion).

Konrad Rudolph
I will attempt your challenge: types. I subscribe to the theory that most bugs are type errors and would be caught at compile-time if we were writing in the right language.
A. Rex
@A. Rex: I guess types are so fundamental that I simply didn't think of them. Kudos! However, this only enforces my original point (C vs. C++) because concerning type safety and compile-time type errors C++ definitely has huge advantages over C.
Konrad Rudolph
this answer should be the accepted one!
Comptrol
Java doesn't have dangling pointers. It has null references, which you can argue are equivalent to null pointers. Null != dangling. A dangling pointer is usually a pointer to freed memory. Moreover, `malloc` is part of the C++ standard library, and `new` is expressly designed to be implementable in terms of it.
Matthew Flaschen
@Matthew: true but not all that relevant to the point I was trying to make: if you dereference an invalid pointer, it goes boom, whether by throwing an exception or by messing up your system with subtle errors. And please elaborate your point about `malloc` vs. `new`, I don’t understand it.
Konrad Rudolph
The point is that a solid understanding of C++ requires understanding `malloc`.
Matthew Flaschen
@Matthew: that may be true. But it’s not important for *beginners*. Manual memory management is advanced stuff, it shouldn’t be among the first things you learn about the language. For C, that’s not an option; for C++ on the other hand, it is.
Konrad Rudolph
I didn't say it was important for beginners. The questioner has "7 years programming experience", and was wondering whether C is a valuable language to learn *next*.
Matthew Flaschen
@Matthew: exactly; and my answer was, “no, since C is cluttered with irrelevant details without actually giving new insights. Take C++ instead, it *has* new insights and makes the details less important.”
Konrad Rudolph
I'm interested to know what these "irrelevant details" are.
mrduclaw
@mrduclaw: mainly, manual memory management. This is a major stumbling block for beginners. Furthermore, the lack of abstraction. I’m aware that C actually offers *very good* abstraction but that’s not what beginners learn – or indeed *can* learn. Good abstraction in C (beyond function-level abstraction) is very hard. Implementing generic data structures and algorithms is just much easier in C++ than in C.
Konrad Rudolph
+5  A: 

I think everyone should learn C, for many reasons:

  1. It is COOL to brag that you can program in C :D:D:D. Well, let's see this as a joke.

  2. To have a closer understand of the hardware. As a matter of fact, we will move further and further from the machine as technology progress (Asm -> C -> Java -> Javascript -> ???). However, that does not mean a real programmer should not care about the iron (silicon, silly me). After all, there are tasks which human does better than Computer and vice vesa. Understanding the machine helps the programmers to know what should be done and what should be left alone (right?). Lastly, you can write faster code by understand the machine better. The computer does not know to "create a big number" or "send this object to hard drive." Knowing this, you would tackle those stuffs with more care and create better codes.

  3. Learn C and break your PC! Seriously! You cannot create kernel modules with Java, right? Nor can do you some small yet deep stuffs below the abstraction layer provided by Java. Learn C and get your hand dirty :D (your mind entertained in the process). Red Alert: back up frequently, or you WILL regret.

  4. You cannot play with Open Source without knowing C. I think that 90% of source code is in C (or C++). Many new projects are in newer languages, but the important ones (Linux, GTK+, etc.) are still in C. Without C, you cannot understand them, right? And you cannot hack them. And you cannot break your machine.

  5. C is fun to learn, to be sure. It is a small language with extreme power. It also has vast amount of library for everything. And it lets you do cool stuffs, as above. Well, if you don't think those stuffs are cool, what is?

About Assembly, well, you can try, but beware, you MAY break your mind (and your machine, of course) along the way. Compared to C, I think it is just to barbaric. C is barbaric enough to have fun, any more will waste your time with doing too little stuffs. Yeah, Assembly wastes your time a lot, since you need to write huge code just to get some very very simple tasks done. If you do insist on learning Assembly, I think you can have fun with those for embedded systems (like ARM or so). First, those languages are more practical (you can build actual stuffs). More important, they are LESS insane than x86 asm (nightmare, nightmare).

A: 

In short, yes. C was one of my first languages I learned and always refer back to the way C handles things and comparing to today. I think C and Assembly are great to know what is really going on in your computer where todays languages abstract away too many things and developers really can't understand the fundamentals.

Much programming on Linux systems is done with C and C++ still today, so that should say a lot. It is a very fundamental langage to at least grasp the concepts from, even if you never write commerial C.

Rob Bazinet
+1  A: 

At NASA, C and Java show up on a lot (and I mean a LOT) of our deployed robots and satellites. Why? It runs light and works well with our hardware. If you ever plan on working in a field where components won't be bought at New Egg or PCMall, I'd pick up some C.

Katie
A: 

If you want (or need) to write C programs, then, yes, obviously.

Otherwise, there are better languages to learn. I write predominantly in C++ (for good or ill) and I've never learned C, nor had any need to. It is certainly not required.

DrPizza
+2  A: 

Do you need to know C? Obviously not or else there would be a lot less programmers. Will it make you a better programmer? Debatable or there would be no point in asking this question.

All I know is from experience in the classroom (not done with school yet) the people who know at least one lower level language can program circles around the ones who stick with C++ or higher. I am glad I was forced to learn it, x86 ASM still gives me the shudders though.

Brian Paden
+1  A: 

I say that it never hurts to lean a new language. Pick up the K&R book and give it a shot.

The biggest reason that I'm glad I learned C is that a lot of languages inherit their syntax from it; as you've already learned Java, this probably isn't so much of a big deal for you.

As for the assembly languages, if you're going to try one, you might as well go with Intel X86 since it's basically everywhere. It's not too hard, just very tedious. But, if you ever do any kind of work on an embedded system, it'll be nice to know how to put ASM together, even if you'll be doing it for a different chip.

A: 

The general reason to learn C that people give is to learn how computers work and by doing so write code that translates better in computer instructions. For that end I (as a college student) found out that my digital logic courses where far better for that end than learning C.

http://www.amazon.com/Fundamentals-McGraw-Hill-Electrical-Computer-Engineering/dp/0072499389/ref=sr_1_1?ie=UTF8&s=books&qid=1219947016&sr=8-1

This book is great for that end. But much of it you do not need to know unless you really want to design hardware.

Hoffmann
+1  A: 

It depends. If you plan to learn c++ or objective-c, you should learn c since both c++ and objective-c are super sets of c. Also, if you want to code for resource constrained platforms like many embedded systems, c comes in very handy. However, today there are many languages to choose from, so leaning c is not absolutely necessary. Finally, I disagree that c is a "Historic" language since there is a lot of software being written in c. Yes, its old but not obsolete.

segfault
+2  A: 

In general, you should learn a variety of languages, if you're serious about enlarging your conceptual vocabulary. Either C or Assembler will force you to deal with the lowest level of programming detail (as seen from the CPU). But you should balance that with e.g. Haskell or Lisp for exposure to programming as seen at the completely conceptual level.

Programmers who think that there's only One Right Way to think about programming are self-limiting, IMHO. (Not evil, just missing out on some good alternative perspectives.) What would you think of a carpenter who only used a handsaw?

However, back to your original question, I think you should only learn C (or any other language) if you have your own reasons for doing so. I don't recommend spending the time just because somebody told you that it is the only way to understand pointers, any more than I recommend avoiding it just because somebody told you that it is outdated.

I believe that someone with a real aptitude (and hunger) for programming will find a way to learn more and do better; someone without the passion probably won't benefit from being exposed to some syntax.

joel.neely
+3  A: 
privatehuff
+1  A: 

There is merit to many of the arguments regarding the usefulness of learning C. Those arguments are well covered in the other comments.

You should learn C because you have the time to, and it will expand your mind. This alone is reason.

dicroce
+1  A: 

Yes, it is a great starting point to better understand both hardware and the underpinnings of interpreted or byte compiled languages, just as learning a functional language such as Haskell or Erlang might help you structure your programs in new and interesting ways. Even if you learn nothing else from the exercise, broadening your perspective can hardly be a bad thing.

Related to increasing your understanding of hardware, I would also highly recommend using an emulator where you can tune the CPU caches to learn more about pipelining and cache characteristics. In college we used a MIPS emulator and a cross compiler for that, but I am sure other options are available these days.

Hank
A: 

short answer? YES!

mapleoin
A: 

In answer to the original question, and the add-on of Is it better to learn C or Assembler?: learn both - write a simple processor simulator in C. The best way to learn any language is to have something you want/need to do with it, and you're already a programmer anyway so you should pick up C practically without noticing as you figure out how to emulate a simple processor. Then write something in assembly for your simulated processor.

David Hicks
A: 

Of course!

Paul Oyster
+1  A: 

In your particular case, your favorite languages are Python and Scheme. The most used distribution of Python is CPython which is written in C. There are also many C based Scheme implementations. http://www.cs.indiana.edu/scheme-repository/imp.html

I've found C useful when installing many python packages. If you ever need to write your own python package you may have to do some C coding. This is also useful, if you ever need improve the 20% of your code which is "slow" you will want to do it in C.

C is the foundation language for many other general purpose languages like C++, Python, Java, Perl, PHP, etc. Aswell as specialized languages like CUDA, Specman etc.

It's hard to talk about C without talking about C++. These combined languages have offer the many of the most advanced features of modern programming languages as well as a uber programming control.

C/C++ are ranked #2 and #3 on the TIOBE index

Gregory
+1  A: 

I think you should learn C, but I think you should learn assembler before C. One of the advantages of learning assembler is you can develop a grasp on how the high level constructs you are using are implemented, which can aid you in making better decisions at times. Now, I don't suggest you write a lot of code in assembler, that's mostly just crazy, but understanding assembler -- any assembler -- is important.

Then the question becomes, which one? Well, because you're not going to be writing production code in it, I personally would opt for a pure simple machine, something as close to a dumb load-store architecture as possible, which would tend to lean you towards the MIPS and other risc architectures, and away from vaxen and especially away from ia32 (intel).

With an understanding of asm (even at a basic level), learning c would be easy, and the mapping of c to assembler is quite transparent and obvious (for non-optimized code, anyways).

Brian Mitchell
+4  A: 

Learning C is important. Every scripting and bytecode-interpreted language in existence was written using C or C++. It is empowering to learn the underlying technology that enables all of these higher-level technologies.

A perfect example is that you can use the C debugging tools to figure out what is wrong in a web application. At my last job, I had a problem with Rails segmentation faulting while loading an external library. I used gdb, nm and strace to solve this. If I hadn't known how to debug native applications using the gnu toolchain, this would have been nearly impossible to solve.

Learning C is important for your development as a programmer. It adds to your skillset and empowers you to understand software at a fundamental level.

hoyhoy
+18  A: 

What's the deal with C being important because of its "historical" relevance? Most of the software you and I use everyday is written in C! Your OS, browser, office suite, email app, media player, calendar, IM, VOIP softphone, and drawing tools are written in C, and this is not going to change in the next 5 years. .NET and Java are almost a decade old (Java already is) and even though they have matured a lot they have not replaced C/C++ as the language of choice for these apps.

Regardless of the educational value of learning a lower level language (which I totally buy) there's a real market for C/C++ programming skills. Stop talking like there isn't.

Max Caceres
"Your OS, browser, office suite, email app, media player, calendar, IM, VOIP softphone, and drawing tools are written in C". Actually, most modern desktop software is C++ (at least Firefox, Thunderbird, OpenOffice.org, KDE apps and MS Office are written in C++). But I grant that at least the Gnome uses C :-).
sleske
True, although for the purpose of this question I'm not sure the distinction matters. I'd find it hard to learn C++ without also learning C.
Max Caceres
On Sourceforge, there is more code written in C than in any other language.
kotlinski
@kotlinski: Curiously, I found that many Open Source projects use C, while in the industry, C++ seems to be more widespread. I'm not sure what to make of this.
sbi
+1  A: 

Absouletly....

C is neither as library rich as Java, nor as easy-to-implement as Python, but it being a low level language teaches a lot about how things work in a program. One can learn most about stacks and data-structures in C, than any other language. Most of all, it is mother-of-all-languages! :-)

Mohit Ranka
+1  A: 

I think C is a valuable and worthy language for anyone to learn. It is like an essential ingredient to a tool-kit.

Zee JollyRoger
A: 

My advice is to focus first on writing everything in the most productive language you can. For me, this is Python. C and its relatives are becoming niche languages for special case purposes. The number of these cases is dwindling. People claim speed concerns to write C or C++ code, possibly optimizing tight loops and the light, but more and more often I'm hearing stories about prototyping in Python and rewriting in C, and because of the higher difficulty of maintaining the C implementation, their Python "prototype" actually remains faster. For those cases where you could have a difference, usually in small per-function units, there are solutions that you could find more favorable, such as the increasingly popular Cython, the HIT compiler Psyco, and simply learning good optimization techniques. Of course, everything I'm saying here can be equally true about other high-productivity languages.

Now, that isn't to say there are no good reasons to use C. There are important uses it still has, namely in close-to-the-wire coding. Kernel work and modules, tight graphics routines, etc.

ironfroggy
+2  A: 

Learning C and Assembly programming are both worthwhile experiences--that much is easy to establish. But C is also easy to learn, because it is a small language that hardly does anything to get between the programmer and the underlying machine. I can understand how one might be hesitant to take the mental leap required to program in, say, Lisp, but understanding C seems like a relatively small deal.

Certainly there are many programming styles and problem domains that make C programming difficult, but that has more to do with the inherent difficulty of programming than with the C language itself. I find that C is one language (perhaps the only language) in which I've nearly always understood exactly what it is doing. That is to say that I find myself confident in knowing precisely what the various C data types and operators do.

Assembly programming is not difficult either, but it is highly arbitrary. With assembly, one tends to have a set of very precisely defined operators to deal with, and it requires some imagination to see how they can be combined to achieve something useful. What one is learning with assembly is how the machine architecture works rather than the language, because assembly really isn't much of a "language." It's just a set of macros for the raw machine code.

If you've done any low-level programming, such as in assembly, and you've done any high-level programming, such as in Python or JavaScript, then you pretty much get C for free. Given that, why not "learn" it? :) The real obstacle here is understanding computer architecture, not learning a language.

Parappa
+1  A: 

Unix is to C language as C is to assembly language as assembly is to machine language. If you learn Unix you will begin to understand C. If you learn C you will begin to understand assembly language. So I think C is an excellent pivot point that looks lower-level to Unix and higher-level to assembly.

Take on assembly only if you want to understand down to the machine instructions. But down there it becomes a tower of Babel, because instead of a single C language with HEADERS (*.h files), you have different languages reflecting different machine architectures.

+3  A: 

Many programmers can survive their entire careers without learning C or Assembler. However, if you choose to learn them, you will 1. understand solid prinicples such as heap, stack, and memory management and 2. gain an increased appreciation for all the work that compilers do for you automatically.

Austin
A: 

You should learn C if you have a chance to use it, otherwise focus on what you think is relevant for your current (and possible future) projects.

Although I have extensive experience using C in embedded development I can say this: I would not go and get a driving license for trucks if I am driving regular limousine cars.

Dan Cristoloveanu
+1  A: 

I think that the great advantage of learning C (or C++ as well, in my opinion) is that it lets you understand what's happening really when you run your program: allocation issues, pointers, references and so on. With high level languages this is hidden and allows you to program without having it in mind...which is not good at all if you want to be a real programmer.

A: 

I say yes too.

The C is good way to understand the machine. Of course, assembly may be better. But it is not popular like C in development.

A: 

It is a lot more common I believe for programs to run on C. It's the original I think (right?) which is open source and then you can learn other C-based languages.

After you learn to program in C you can learn C++, C# or even Java.

if you want to program as close to the Operating system as possible, learn C to program an operating system.

it's the fundamental language for Operating systems such as linux, windows and even Mac OSX.

and after you learn it, as I said, it leads to other programming languages easily.

C is easy to learn and just requires some time to get used to. Plus after learning it, you can actually study C based languages such as Java, which I know you know, so it's similar anyways. Then you can learn how Java actually works, and maybe learn more about how to program better. :)

A: 

Yes, everybody should learn C.

It will teach you to appreaciate the managed execution of Java and .Net.

Take a look at assembly too, just to know what it is.

The relation between them is best described by this quote:

"C combines the power of assembly with the flexibility of assembly." (Kim Øyhus)

Guge
A: 

I did C after learning Java (as a student). The C Programming Language book is invaluable and will be nearly all you need (combined with this helpful website :)). I'd say yes as there is not much reason not to.

GreenRails
A: 

Yes, you should. C is timeless language. Better when it come with assembly.

plan9assembler
+1  A: 

Yes!

Every new language I've learnt has had a language feature that's given me a Eureka moment that has, quite simply, made me a better programmer. It's just the same as when, say, DRY finally clicks, and your code instantly becomes twice as maintainable.

If you're working in Java and suddenly realise that what you really need is

  • a closure,
  • a function pointer,
  • a Lisp macro,
  • eval,
  • type inference,

then learning a new language has made you that little bit wiser, which is never a bad thing.

Alex
A: 

If you are not learning the language for practical reasons, then you should consider assembly on a simple architecture. The basics of C are very much similar to the basics of C++, and you won't learn nearly as much as from assembly. If you want very specific advice, go grab a free assembler/simulator (Such as Easy68k) and make your first console program in assembly! It will be simple enough to figure out on your own yet complex enough to extrapolate to more advanced architectures such as the x86 you're working on.

A: 

If the reason behind learning a language is to understand the machine, I'd say learn assembly. If the reason is to learn core programming concepts, I'd say spend time with the core of C, i.e. pointers, memory management, etc. and then move on to C++. From my experience, I appreciated Java so much more because of my C++ background. The problem isn't that C++ doesn't allow things like interfaces, it's that they have to be consistently applied and the language makes this difficult. Yes you can define abstract base classes but unless you have the entire maintenance team on the same page of rules, like declaring virtual destructors, you end up feeling like you're working with uranium without your lead undies. What the gung-ho C/C++ coders aren't telling you is how many scars they got by learning the hard way how to do it the 'right' way.

Kelly French
+1  A: 

C, sure. maybe D after. Know List too. Assembler? Z80 for a fundamental introductory and/or ARM for fun and a more complex system. x86, only if you got a job for this or if you hate yourself.

bigown
You must have tried assembler for 16 bit DOS with the 64Kb limit segments :)
Arthur Kalliokoski
A: 

I think that assembler is very good for you. I did not have problems to understand C pointers because I had programmed a computer with z80 processor that my father presented to me.

But C is important too. It is structured programming. You do the same but C is different and more important to know the system because all the systems are written in C, today.

loriser
+16  A: 

Speaking as someone who has learned both C and Assembler I'm not sure that there's any real value to be gained from retrospectively learning those languages. They aren't particularly complex - the difficulty in using them stems from the fact that it's very easy to make mistakes, and those mistakes can be very difficult to find. Some people might argue that such a programming environment might force you to be more careful in your work but since you already have a few years under your belt I imagine you've already learned that lesson.

Joel Spolsky suggests that knowing C will help you to work around a leaky abstraction but I think you might find that in most cases somebody out there has already done it and been kind enough to post their solution on the internet. Google is our friend.

There's also the point that technology is moving so fast it's practically impossible for one person to keep up with it. Your time might be better spent researching the next big productivity booster.

Phil
I think your statement that "they aren't particularly complex" is misleading. Syntactically, the languages are fairly simple, as languages go. However, programming is an interaction between the complexity of the language and the sophistication of the programmer. Simpler languages often force more complicated code (e.g. a LINQ expression vs. writing an equivalent algorithm in ASM). If you learn C, you'll learn new things about vtables, functors, closures, and many other things because you're writing them yourself, from scratch.
Kennet Belenky
Do you feel that I'm selling C or assembler short? I hope not because that's really not the point I want to make. Knowledgeable developers are admirable and there is always value in learning, but in this case is there enough value to justify learning C or assembler? No, because when a developer needs to understand new concepts they'll take the time they need to do the appropriate research.
Phil
I think what @Kennet Belenky might have been suggesting was that developers doing your "appropriate research" might have to do less of it to get a better understanding of the goal, in general, if they had known C/ASM. I would argue that the languages themselves are probably less useful than learning to think in terms of them, which isn't something you can as easily pick-up from a simple Google search.
mrduclaw
I disagree; concepts of programming are very often easy to pick up from a google search. I think it's the wealth of information we have at our finger-tips that makes the JIT approach to learning viable if not optimal.
Phil
@Phil, yes! I encourage all novice programmers to compose code by copy-and-pasting snippets they find on CodeProject ;) @mrduclaw did a very good job of summarizing my point of view. You may also wish to see my answer to this question: http://stackoverflow.com/questions/2339459/is-there-any-reason-a-net-windows-programmer-needs-to-learn-c-or-c-anymore/2339496#2339496
Kennet Belenky
@Kennet, does that mean you think the OP is a novice? Let's not put words in each other's mouths... Nobody can know everything; nobody needs to know everything. Be ruthlessly selective in what you learn and maximise productivity. I'll see your Leaky Abstraction and raise you a Fire and Motion.
Phil
+1  A: 

There is one particularly good reason, as a Java programmer, to learn C and the POSIX APIs that (typically) go with it: It gives you the ability to use JNI.

nsayer
+3  A: 

C is so widespread that, and this is regrettable, a lot of languages have similarities to C despite being intended for a different paradigm. I suppose the idea was to reduce the learning curve or something. Anyway C syntax has 'colourd' the syntaxes of many languages: C++, Java, C#, and on and on ...

C excels as the language to replace assembly programming and gain re-usability. Don't ask "C or assembler", ask "C or all the assembler languages". Pretty much anything you can write in assembler you can write just as well in C, and don't need to rewrite much when you change hw.

Almost all other languages rely on C in one way or another, many are implemented in C. The one compiler you are almost guaranteed to find when you target any hardware is C. So if you want to build a component that reaches all the hardware your first thought is to write it in C.

As a consequence, I'd say every programmer should know both C and higher level languages. At the least the skill will enable you to import components you may find you need into the high level language you prefer to use.

But don't confuse C with C++.
Many times you will see "C/C++" as though they are interchangeable. They are not.

C++ tries to be all things to all people and consequently comes out as the epitome of mediocrity. If you wan Object Oriented, almost any other, Objective C, Java, C# is preferable. C is much better than C++ at being C.

pbernatchez
+1  A: 

I would suggest learning a little of assembler first. It helps you very much to understand pointers, bit manipulations and ways to optimize an algorithm. x86 will do, because it's better documented and can be easily tested. And please use the NASM compiler (Netwide assembler), not MASM or TASM, because it is much more intuitive, and does not try to make a high level language out of assembler.

ruslik
A: 

I'm not sure how to answer this

bob
This, at least, is not the correct way.
Ruben Steins