tags:

views:

616

answers:

19

As a person who wanted to increase his fundamental programming skills, I chose to learn C++ instead of C. Which leads me to ask: Is there any fundamental skills that I leave in C that might not be obtained by learning C++?

Related question: Should I learn C before learning C++?

+1  A: 

It really depends on which subset of C++ you learned. For example, you could get by in C++ using only the iostreams libraries; that would leave you without experience in the C stdio library. I'm not sure I would call stdio a fundamental skill, but it's certainly an area of experience one should be familiar with.

Or perhaps manually dealing with C-style null-terminated strings and the str*() set of functions might be considered a fundamental skill. Practice avoiding buffer overflows in the face of dangerous API functions is definitely worth something.

Greg Hewgill
+6  A: 

I don't think there are any skills that you can learn in C but not C++, but I would definitely suggest learning C first still. Nobody can fit C++ in their head; it may be the most complex non-esoteric language ever created. C, on the other hand, is quite simple. It is relatively easy to fit C in your head. C will definitely help you get used to things like pointers and manual memory management much quicker than C++. C++ will help you understand OO.

Also, when I say learn C, it's okay to use a C++ compiler and possibly use things like iostreams if you want, just try to restrict yourself to mostly C features at first. If you go all out and learn all the weird C++ features like templates, RAII, exceptions, references, etc., you will be thoroughly confused.

Zifre
As an esoteric language fan, I don't know of any esoteric languages more complicated than C++ either. Maybe INTERCAL, but I doubt it. For all it's COME FROMs, it's still a fairly simple imperative language.
Chris Lutz
Yes, I was thinking of INTERCAL when I wrote that. Certainly though, C++ is *easier to use* than INTERCAL.
Zifre
+2  A: 

I wouldn't say you missed anything fundamental. Check out Compatibility of C and C++ for a few non-fundamental examples, though.

Several additions of C99 are not supported in C++ or conflict with C++ features, such as variadic macros, compound literals, variable-length arrays, and native complex-number types. The long long int datatype and restrict qualifier defined in C99 are not included in the current C++ standard, but some compilers such as the GNU Compiler Collection[3] provide them as an extension. The long long datatype along with variadic templates, with which some functionality of variadic macros can be achieved, will be in the next C++ standard, C++0x. On the other hand, C99 has reduced some other incompatibilities by incorporating C++ features such as // comments and mixed declarations and code.

Bill the Lizard
A: 

Most C code can be compiled as C++ code with a few minimal changes. For examples of a very few things that can't be changed see Why artificially limit your code to C?. I don't think any of these could be classed as fundamental though.

anon
+15  A: 

If all you've ever used is object-oriented programming languages like C++ then it would be worthwhile to practice a little C. I find that many OO programmers tend to use objects like a crutch and don't know what to do once you take them away. C will give you the clarity to understand why OO programming emerged in the first place and help you to understand when its useful versus when its just overkill.

In the same vein, you'll learn what it's like to not rely on libraries to do things for you. By noting what features C++ developers turned into libraries, you get a better sense of how to abstract your own code when the time comes. It would be bad to just feel like you need to abstract everything in every situation.

That said, you don't have to learn C. If you know C++ you can drag yourself through most projects. However, by looking at the lower-level languages, you will improve your programming style, even in the higher-level ones.

Kai
Exactly, especially in C++ which can be a real minefield if you have no clue what's going on in the background as it doesn't have all the safety belts and airbags Java and C# do.
DrJokepu
+1  A: 

This is just a shot in the dark, but perhaps you use function pointers more in C than in C++, and perhaps utilizing function pointers as a skill might be boosted by starting to learn C. Of course all of these goodies are in C++ as well, but once you get your hands on classes it might be easy to just keep focusing on them and miss out on other basic stuff.

You could for example construct your own inheritance and polymorphism "system" in pure C, by using simple structs and function pointers. This needs a more inventive thinking and I think builds up a greater understanding of what is happening "in the box".

If you start with C++ there is a chance that you miss out on these little details that are there in C++ but you never see them, since the compiler does it for you.

Just a few thoughts.

Magnus Skog
A: 

C is essentially a subset of C++. There are differences as highligted by some of the other answers, but essentially most C compiles as C++ with only a little modification.

The benefits of learning C is that it's a much more compact language and learning it is therefore quicker. C also requires you to work on a relatively low abstraction level which is good for understanding how the computer actually works. I personally grew up with assembly and moved to C from there, which I now see as a definitive advantage in understanding how compilers actually map high abstraction level contstructs to actual machine code.

In C++ you can find yourself quickly entrenched in higher levels of abstraction. It's good for productivity but not necessarily so for understanding.

So my advice is: study C++ if you have the motivation, but first concentrate on the core low level constructs that are common with C. Only then move to the higher level things such as object orientation, templates, extensive class libraries and so on.

laalto
+1  A: 

Depends on how you approach C++. I would normally recommend starting at a high level, with STL containers and smart pointers, and that won't make you learn the low-level details. If you want to learn those, you probably should just jump into C.

David Thornley
+5  A: 

Compare the following code examples (apologies, my C++ is a little rusty).

C++:

int x;

std::cin >> x;

C:

int x;

scanf("%d", &x);

So, what do you see above? In C++, a value is plugged into a variable. That's cool, but what does it teach us? In C, we notice a few things. The x has a funny & in front of it, which means it's address is being passed. That must mean that the scanf function actually needs to know where in memory x is. Not only that, but it needs a format string, so it must not really hvae any idea of what address you're giving it and what format it's getting information in?

C lets you discover all these wonderful things about how the Computer and the Operating System actually work, if you will put effort towards it. I think that's pretty cool.

Alex Gartrell
Yes these are the kinds of little things i am talking about.
Babiker
C++ does not prevent you from learning these things. Both examples are valid C++.
Bill the Lizard
Another cool thing about C is the amount of _undefined_ behaviors : ie scanf will return garbage in case of integer overflow.
You can call me Chuck
@Bill the Lizard but C++ doesn't FORCE you to learn them. It's like saying that C allows you to learn assembly by providing asm("incr %%eax"); If it's a feature that isn't mandated and there's an easier way to do it, it won't (and probably shouldn't) be done.
Alex Gartrell
+4  A: 

There is certainly one thing: memory management. Take following code for example:

struct foo {
   int bar;
   char **box;
};

struct foo * fooTab = (struct foo *) malloc( sizeof(foo) * 100 );
for(int i = 0; i<100; i++) {
   fooTab[i].bar = i;
   fooTab[i].box = (char **) malloc( sizeof(char *) * 10 );
   for(int j = 0; j<10; j++) {
      fooTab[i].box[j] = (char *) malloc( sizeof(char) * 10 );
      memset(fooTab[i].box[j], 'x', 10);
   }
}

Using C++ you simply do not deal with memory allocation in such way. As a result, such skills may be left untrained. This will certainly result in e.g. lower debugging skills. Another drawback may be: lower optimizing skills.

C++ code would look like:

struct foo {
    int bar;
    static int idx;
    vector< vector<char> > box;
    foo() : bar(idx), box(10) {
       idx++;
       for ( auto it = box.begin(); it != box.end(); it++) {
           it->resize(10,'x');
       }
    }
};

int foo::idx = 0;
foo fooTab[100];

As you can see there is simply no way to learn raw memory management with C++-style code.

EDIT: by "C++-style code" I mean: RAII constructors/destructors, STL containers. Anyway I had probably exaggerated, it would be better to say: It is far more difficult to learn raw memory management with C++-style code.

I disagree with your statement that there is "simply no way to learn raw memory management with C++ style code". It is possible to provide fine-grained control over how memory allocation works in C++; in fact, this functionality is commonly used to implement memory pools. See http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14
Paul Morie
@Paul: What I said may be little exaggeration but still, it is far more difficult to have an opportunity to code raw memory management in C++ than in C. And I said: "with C++-style code" meaning: RAII constructors/destructors, STL containers.
+2  A: 

I find it's better to learn memory management in C before attempting to dive into C++.

In C, you just have malloc() and free(). You can typecast things around as pointers. It's pretty straightfoward: multiply the sizeof() by the # items needed, typecast appropriately, and use pointer arithmetic to jump all over the place.

In C++, you have your various reinterpret_cast<> (vs. dynamic_cast, etc) kind of things, which are important, but only make sense when you're realizing that the various castings are meant to trap pitfalls in multiple inheritance and other such lovely C++-isms. It's kind of a pain to understand (learn) why you need to put the word "virtual" on a destructor on objects that do memory management, etc.

That reason alone is why you should learn C. I also think it's easier to (at first) understand printf() vs. the potentially overloaded "<<" operator, etc, but to me the main reason is memory management.

Matt
+1  A: 

The simplicity of C focuses the mind wonderfully.

With fewer things to learn in C, there is a reasonable chance that the student will learn those things better. If one starts with C++ there is the danger of coming out the other end knowing nothing about everything.

John Pirie
+1  A: 

Playing devil's advocate, because I think C is a good starting point...

Personally, I started learning with C, algorithms, data structures, memory allocation, file manipulation, graphics routines... I would call these the elementary particles of programming.

I next learned C++. To over-simplify, C++ adds the layer of object-oriented programming - you have the same objectives as you do regardless of language, but the approach and constructs you build to achieve them are different: classes, overloading, polymorphism, encapsulation, etc...

It wasn't any educated decision on my part, this is simply how my programming course was structured, and it worked out to be a good curriculum.

Another simplification... C is basically a subset of C++. You can "do C" with C++, by avoiding to use the language features of C++. From the perspective of language features. Libraries are different matter. I don't think you will get past more than just programming 101 without beginning to use and build libraries, and there is enough out there to keep you busy for a lifetime.

If your goal is to learn C++ ultimately, then beginning with "C" could be a logical start, the language is "smaller" - but there is so much in "C" that you would probably want to narrow your focus. You are tackling a bigger beast, but if you get guidance, I see no compelling reason not to, despite the path I took.

Jason T
A: 

optimization theory

primarily because the asm output of a C compiler is generally mush more predictable and usually well correlated to the C. This lets you teach/learn why its better to structure code a certain way by showing the actual instructions generated.

Mark
A: 

You should learn data structures in C. First, it will force you to really understand pointers, which will help you to deal with leaky abstractions in higher level languages. Second it will make obvious the benefits of OO.

Dima
A: 

Coding Sytle

By coding style I don't mean {} and whitespace, I mean how you organizing data, classes, files, etc.

I started off learning c++, which usually favors creating classes and organizing things a certain way. I could write c code just fine when needed, but it was never like the c style code that others wrote who started off with c.

One of my OS classes required us to write a file system in C. My partner was originally a C guy and I was amazed at the difference in the code we wrote. Mine was obviously trying to use c++ style coding in c.

It's kindof like when you first learn perl or ruby or something and you are just trying to write the same c# code except translated into that new language rather than using that languages features.

While C is a subset of C++, C programs and C++ programs are so different as to not really be comparable.

Alan Jackson
A: 

Yes, simple structured programming.

With OOP everywhere, it is easy to forget that you can build sound system just by using modules and functions. C's module system is pretty weak, but still...

This is also one of the advantages of functional programming, in my book. Many functional programming languages have a strong module system. When you need more genericity than simple functions can offer, there are always higher order functions.

wmeyer
A: 

if you want to learn new skills and you have good fundamentals of structured programing(SP) you should go for C++. learn to think a given problem in an object oriented(OOP) way (define objects, methods, Inheritance, etc) its sometimes the most difficult part. I was in the same situation as you a few years ago, and i choose C++, because learning a new paradigm, a new way of thinking and design software, sometimes its more difficult that the code itself, and if you don't like C++ or OOP you can go back to C and SP, but at least you will have some OOP skills.

JoeOk
A: 

I would choose C to learn low-level primitives of programming.

For OOP, there are so many other languages to learn before C++ that are much easier to learn. This isn't 1990 when the only OOP languages were Smalltalk and C++, and only C++ was used outside of academia. Almost every new programming language invented since has objects, and almost all are less complex than C++.

Licky Lindsay
Smalltalk was used in industry. I have worked for a company that used it.
Dima