27

Possible Duplicate:
Should I learn C before learning C++?

As a professional (Java) programmer and heavy Linux user I feel it's my responsibility to learn some C (even though I may never use it professionally), just to make me a better coder.

Two questions :

  1. Should I try C or C++ first - I realise they are different languages with some common ground. Is it useful to learn a bit of both, or just try one? I hear C++ is a bit of a nightmare behemoth of a language.

  2. What are the best resources (books, tutorials, practice programs, reference code) for a Java developer like myself.

Thanks

Community
  • 1
  • 1
lucas1000001
  • 2,740
  • 1
  • 25
  • 22
  • 11
    +1 for recognizing your duty ;) – Aiden Bell Aug 21 '10 at 18:41
  • 2
    I realize this comment isn't the most useful in the world...but did you even *try* searching for answers to either of those questions? We've seen them so many times. – KevenK Aug 21 '10 at 18:43
  • I did but couldn't find anything decent - if you could point me at some that would be useful – lucas1000001 Aug 21 '10 at 18:44
  • Also: http://stackoverflow.com/questions/598552/should-i-learn-c-before-learning-c and http://stackoverflow.com/questions/171126/learning-c-and-or-c-from-beginner-to-advanced – Aiden Bell Aug 21 '10 at 18:45
  • 7
    For me, C is quite simple and elegant low-level language which I enjoy using. C++ is... well, I don't want to hurt anyone's feelings. (BTW, I'm a java programmer also.) – Nikita Rybak Aug 21 '10 at 18:45
  • @Aiden Bell - thanks for those links! – lucas1000001 Aug 21 '10 at 18:46
  • 1
    @Nikita Rybak - I have no problem saying it: C is good. C++, Java, C# and PHP pretty much smell. Python and C all the way. ;) – Aiden Bell Aug 21 '10 at 18:52
  • 1
    @Aiden Well, I was looking for some stronger words, like the one rhyming with "morrible" :) – Nikita Rybak Aug 21 '10 at 19:02
  • @Nikita - I consider "smell" to be fairly strong for those languages ;) - A high insult. – Aiden Bell Aug 21 '10 at 19:03
  • 1
    Don't learn either. Learn a completely different language. I recommend something functional. Lisp perhaps. There's some good books on Scheme as well. – Dennis Zickefoose Aug 21 '10 at 20:20
  • 1
    @Dennis Zickefoose - Whats wrong with learning C? He knows one that is purely OOP, so it makes sense to learn something functional (as you said, lisp, maybe haskell), as well as something purely procedural and low level. – alternative Aug 21 '10 at 20:53
  • 1
    @mathepic: Java has a lot of procedural elements itself. Outside of memory management, there isn't much for C to teach in terms of actual programming. – Dennis Zickefoose Aug 21 '10 at 21:14
  • Thanks for all the advice everyone! Much appreciated! I'm checking out Clojure (so hoping that will give me a kick in the right direction where function languages are concerned) and from the posts, it seems C is the way to go with procedural - trying to lose the 'oh he's just a java progammer' tag ;) - thanks again – lucas1000001 Aug 21 '10 at 22:29
  • Haha, thought this was very relevant to my post http://i.imgur.com/G7WyP.gif – lucas1000001 Aug 22 '10 at 17:42

7 Answers7

33

C is simple to learn, difficult to master. as a Java programmer the barrier will be memory and structure .. and undoing the damage Java may have done to the algorithm producing portions of your brain ;)

I would recommend getting familiar with the GCC toolchain on your Linux box, through tutorials on the Internet. Then read The C Programming Language, and a copy of Linux Application Development doesn't hurt. Also, on Linux glib will save you from reinventing the wheel ... but at least try to create your own linked-list, hashmap, graph and other API to learn. Pointer arithmetic, arrays and learning that elements such as structs are just named-offsets in a binary chunk are all important. Spend time with malloc and free and memcheck. With C, your tools and toolchain are very important and the IDE isn't necessarily your friend when learning.

I would pick C over C++ as C is a good foundation to get used to the memory management and pointer usage of C.

The best thing you can do is apply what you learn to a real project. But be prepared to bash your head against the wall allot in Valgrind and GDB. I have been programming C for years, and I am still no C monk.

I do agree that C is a great language, it shows up a bad programmer. But remember:

Any sufficiently complicated C program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

The moral of which is learn other languages too, rather than just C-derived ones! Consider some Lisp dialect, Erlang (which is cool at the moment), Haskell, etc. They will expand your horizons from the 2x2 cell of Java. Consider looking at SICP too.

Aiden Bell
  • 28,212
  • 4
  • 75
  • 119
  • 2
    Eh, C isn't particularly difficult to master. C++ is difficult to master, and that's pretty much the reason why C is better suited for some projects. – jalf Aug 21 '10 at 18:53
  • I agree, already in the process of learning Clojure ;) – lucas1000001 Aug 21 '10 at 18:53
  • 6
    @jalf - I disagree. C is simple, no doubt, but beauty is in application and elegance. Mastery is in producing beautiful C programs not ones that treat memory and logic like crap. – Aiden Bell Aug 21 '10 at 18:54
  • I disagree about C before C++. Especially coming from an OO/Java background. The posts here might help him decide, I suggest C++ and not C. http://stackoverflow.com/questions/145096/is-it-true-that-there-is-no-need-to-learn-c-because-c-contains-everything/145098#145098 – KevenK Aug 21 '10 at 18:57
  • How is C++ difficult to master compared to C? You can do most of C in C++. You don't have to write all the structures yourself (something you _should_ be doing...). – alternative Aug 21 '10 at 19:59
  • @KevenK C++ before C doesn't make sense at all. C is (+/- some differences) a subset of C++. Even if you are learning "just" C++ you will learn C in the process. The problem is that you will miss the part describing the differences between C and C++ (which is not good). – Šimon Tóth Aug 21 '10 at 20:02
  • @mathepic: some of us distinguish between "writing code that is accepted by a C++ compiler" and actually writing good C++ code (which I'd expect someone who "mastered" the language to do – jalf Aug 21 '10 at 20:26
  • 1
    @Aiden: C being easy to learn is one of the main reasons it is used in the Linux kernel: they need a language that people can pick up and use with a minimum of difficulty, and still write reasonably solid code. My point was simply that as much as I prefer C++, C is definitely *much* easier to master. – jalf Aug 21 '10 at 20:28
27

Coming from ASM, C, then C++, and finally landing (forced) into the Java territory, I thought I may provide an opinion about the subject.

First, with all due respect to the Java community, the business experience shows that while C/C++ programmers can get used to the Java principles and programming (it may not be that easy), the opposite happens more rarely. In other terms, a C++ programmer will have to learn and cope with tons of Java rules (Frameworks...) but she will eventually (and usually) be able to produce a long term working code by injecting a lot of her system experience into the process. A Java programmer going to C, used to more theoretical principles, and strict structure rules may

  • feel insecure as she has to decide many things, like program organization and structure
  • feel surprised with the pointers, and memory management: allocation and freeing, which has to be thought carefully - discovering the world of memory leaks
  • feel discouraged, as the bugs won't appear black on white in a console dictated by the JVM through 200 lines of stack trace, but may happen at a deeper / system level, maybe caught thanks to an IDE in front of which the Java programmer will contemplate some assembly code for the 1st time in her life
  • feel perplex as to what algorithm and how to implement it, the one that was integrated into Java that she never had to worry about...

So, now, my task is to help you to feel secure, confident, and motivated before learning C/C++!

My advice is to start with C, because

  • C by itself owns all the very concepts you never had to face with Java
  • as a Java programmer you already have a classes 'approach', and starting with C++, you may be tempted to stick to the Java OO principles
  • C principles are limited to a few. C looks like the very last human thing before entering the dark world of assembly language.

What I would emphasize during the C study is, for instance

  • Pointers Java uses pointers of course, but hides its access while actually passing classes to methods as pointers. In C, you will have to learn the difference between by value and by reference. Also, the more subtle difference between char x[3] and char *x = "ab". And how convenient pointers are to go through an array etc..., you know *++x or *x++. A lot has been said about pointers, my advice would be

    1. always keep control, i.e. don't put too many indirections when not necessary
    2. don't typedef pointers, like typedef int *pointerToInt ; it seems easier at first (pointerToInt pi instead of int *pi) after a few levels, I prefer to count the stars than the 'pointerTo' [some big cies do that]. Except maybe the pointers to functions, unreadable anyway.
  • Memory When you need memory, you allocate it, and when you don't need it anymore, you free it. Easy. The thing is to allocate the right amount, and not to free it twice... Have to get used to that. And get used to the heap, the stack... And When your program runs and address NULL (0) you may have a visible exception. Maybe not.

  • Data structure So you want to use a convenient HashMap? Sure, after you developed it. Or there are some libraries you can link that do that kind of thing, just chose the right one. To be fair, when programming in C, you [have to] think different, and may find a more appropriate algorithm than a map for a given problem.

All in all, you will feel disoriented at first, but eventually (unless you have nightmares) you will find before you a lot of room for fun and pleasure. C allows a person to program with complete freedom: C goes according to your ideas, not the opposite.

Déjà vu
  • 28,223
  • 6
  • 72
  • 100
  • lol, your right that errors tend to be buried in massive stack traces/tread dumps. But I think that most memory problems can simply be solved by spending some time in the profiler. This is an essential learning experience for Java people to prevent memory leaks. – TheLQ Aug 21 '10 at 22:02
11

If the goal is to make you a better coder, aim for languages that actually try to be different. Java, C++ and C are all closely related.

True, one is primarily a procedural language, one tries really hard to pretend to be OOP, and one is a mix of at least 4 different paradigms, but they're all imperative languages, they all share a lot of syntax, and basically, they're all part of the same family of languages.

Learning C isn't going to teach you anything dramatically new. It might teach you a bit about memory layout and such, but you can learn that in many other ways, and it's just not very relevant to a Java programmer.

On the other hand, the language is relatively easy to pick up, and widely used for a lot of Linux software, so if you want to contribute to any of those, learning C is a good idea. It just won't make you a much better Java programmer.

As for C++, calling it a "nightmare behemoth of a language" probably isn't far from the truth. It is big and complex and full of wierd pitfalls and traps for the unwary beginner.

but it also has some redeeming qualities. For one thing, it is one of the only languages to support the generic programming paradigm, and that allows you to express many advanced concepts very concisely, and with a high degree of flexibility and code reuse.

It's a language that'll probably both make you hate C++ for being such an overengineered mess, and all other languages for missing C++ features that'd have made your code so much simpler.

Again, learning C++ won't make a huge difference to you as a Java programmer, except that it'll reveal a number of shortcomings in Java that you weren't aware of until now.

Learning either language is good, but what's better is learning something different.

Learn SML or Scheme or Haskell. Or Ruby, Python or Smalltalk. How about Erlang or Occam? Or Prolog.

Learn something that isn't either Java's sibling or ancestor, something that is designed from scratch to have nothing in common with Java. Learn a functional language like SML, or a dynamically typed one like Python, or one that radically changes how you deal with concurrency, like Erlang.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • 1
    +1: This says everything I wanted to say, but didn't want to fit into a comment. – Dennis Zickefoose Aug 21 '10 at 22:14
  • +1 great post. Would add Clojure as an option - completely different language paradigm from Java (functional, dynamic, concurrent, Lisp), but runs on Java platform so relatively easy for a Java person to understand the environment at least. – mikera May 24 '12 at 02:32
7
  1. It depends on what you want to learn. I think it's probably best to sit back and consider why you really want to do this at all. If Java does what you want, and you're just doing this out of some misplaced sense of duty, I think there are probably better ways to spend your time. The reputation of C++ as a "nightmare behemoth" is spread mostly by insecure Java programmers trying to justify what, in their hearts, they know to have been a second-rate choice1.
  2. There are a couple of books specifically written for Java programmers learning C and/or C++. Though it's not specifically for Java programmers, if you do decide on C++ rather than C, I'd consider Acclerated C++.

1I'm at least sort of joking, of course, but there are an almost amazing number of Java programmers who seem to have a chip on their shoulder. If you tell somebody who uses Python or Ruby (for just a couple of examples) that it's slow, the typical reaction is them looking a little puzzled and saying something like: "If you say so -- it seems fast enough to me." Suggesting the same about Java is practically guaranteed to produce claims that you're obviously ignorant and expressing nothing but blind hatred.

Edit: As far as choosing between C and C++ goes, for somebody accustomed to Java, C will simply be an exercise in frustration. The difference in language would require considerable adjustment anyway, but moving from a library the size of Java's to one the size of C's will simply result destroying his productivity for quite a while, and is more likely to just prejudice him again all languages with "C" in the name than help him actually learn anything.

Moving directly from Java to C is like taking somebody whose idea of a sporty car is when he drives the Lincoln Town Car instead of being chauffeured in the limousine, and when he decides racing is cool, you dump him directly in the seat of an Outlaw sprint car. Give him a chance in (not only much safer, but actually faster) street-legal sports car first...

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • If you say so -- Java programmers seem normal enough to me. – President James K. Polk Aug 21 '10 at 19:19
  • well, if you surround yourself with crazy people, I'm sure they'd seem normal too. ;) I can definitely recognize what Jerry is talking about. Without getting into whether or not Java is *actually* a second-rate language, Java programmers often do seem to have some kind of inferiority complex, like they feel they're not "real" programmers until they've learned C++. Where a Python or Ruby or Haskell programmer just couldn't care less about a primitive language like C++, a Java programmer often seems to have a feeling that they've taken "the easy way out" and that it reflects badly on them. – jalf Aug 21 '10 at 20:30
  • @jalf Its the reputation that C/C++ have given Java, as well as its label as an "Introductory language" thats taught at most schools. I'll tell you that I kinda suffer from this, which pushed me to learn C#. The difference with Python is that its dynamic, newish, and very popular. – TheLQ Aug 21 '10 at 21:58
5

Regarding (1), I'd probably say C. It's a lot more foreign. Since your goal is to be multilingual for its own sake, moving towards a language that is much different than Java will probably be more useful than learning C++, which will probably make you angry. C++ gets a lot of crap from people, and it's not necessarily awful, but the primary reason is that it is trying to force a new paradigm into the structure of C, which doesn't work as well as a language that starts with that paradigm in the first place.

For (2), I would highly, highly recommend K&R. It assumes some programming familiarity, is brief, to the point, but also is deep enough to explain concepts. It doesn't include exercises, however, which you'll have to find elsewhere. I learned C on the job, I'm afraid (and still paying for it!) so I can't give you educated help there.

spencer nelson
  • 4,365
  • 3
  • 24
  • 22
4

Since you're doing this for self-fulfillment and learning, I say go for broke and give C++ a try.

A small preface before I elaborate: I used to work primarily with C++ and have never worked with C code of any significant size. Now I work with C# for the most part, only using C++ on rare occasions.

I think C++ is a better option because:

  • It's a partial super-set of C: C programs will generally not compile as C++ programs, but the overlap between the two languages is substantial enough that it shouldn't be difficult for you to re-target your skills to work with C code if you need to.
  • C++ will introduce you to more concepts: You'll get all the fun of memory management and bit twiddling that you can do in C. But you'll also get to see generics like you've never seen them before, how algorithms can be written independently from containers, how to do compile-time polymorphism, how multiple inheritance can be actually useful sometimes, etc.
  • You'll learn to appreciate the design of the Java language a lot more: C++ is a complicated languages with many gotchas and edge cases (see the FAQ and the FQA for some examples). By experiencing them for yourself, you'll be able to better understand many of the design decisions that went into making both Java and C#.

It boils down to this: The more you learn the more that you'll be able to learn. And C++ forces a lot of learning on you, definitely more than C. And that's a good thing.

Mhmmd
  • 1,483
  • 9
  • 15
2

C++ will probably feel more familiar to you than C, and will probably be easier to get productive with off the bat. However, C is a much smaller language and should be reasonably straightforward to learn (although beware; by learning C you risk permanent brain damage). My personal reference is "C: A Reference Manual" by Harbison & Steele (currently 5th edition). For C++, I just use the O'Reilly nutshell book.

As a C programmer with some C++ experience and currently making the transition to Java, I can tell you the things about C that are probably going to trip you up almost immediately:

  • C has very little in the way of abstractions; pointers and byte streams are pretty much it. There are no standard container types (lists, maps, etc.). You want anything more sophisticated than a fixed-length array, you will have to roll your own (or use a library developed by someone else).
  • There is no such thing as garbage collection in C. Every byte you allocate dynamically (via malloc() or calloc()) you are on the hook for deallocating (via free()).
  • Arrays in C do not behave like arrays in Java; there are some funky rules regarding array types that at first blush do not make sense (and won't until sufficient brain damage has set in). There is no bounds checking on arrays, and some standard library functions (notably gets() and scanf()) make buffer overrun exploits a real risk.
  • C declaration syntax can get pretty twisted. While you probably won't see anything quite so ugly, declarations like int *(*(*(*f)())[10])(); are possible (f is a pointer to a function returning a pointer to a 10-element array of pointers to functions returning pointer to int`.
  • C implementation limits can vary from platform to platform; for example, the language standard only mandates minimum ranges for types like short, int, and long, but they may be wider than the minimum requirements. If you're expecting an int to always be the same size regardless of platform, you're in for some surprises.
  • Text processing in C is a pain in the ass. Seriously. C does not have a string type as such.
John Bode
  • 119,563
  • 19
  • 122
  • 198