tags:

views:

859

answers:

13

I've been learning C at Varsity for just shy of 2months now, and next year we'll be moving on to C++.

Are there any habits I should get into with my C programming which will aid a transition to C++ in the future, or is it best to think of them completely separately ?

When you learnt C then C++, did the way you coded in C change in any way ?

A: 

Function pointers. Google first hit.

kenny
What so special about function pointers? He doesn't want to use 'class' in C ?
Naveen
Function pointers are less useful in C++ than there are in C simply because there are a number of problems to which a C solution might be function pointers whereas C++ has other language features that might provide an alternative solution. `virtual` functions, and functor classes spring to mind. In moving from C to C++, I wouldn't recommend a greater emphasis on function pointers.
Charles Bailey
Yes, @Naveen that's my point. Knowing them and where they came.
kenny
Why are function pointers relevant to someone who already knows C, and needs to learn C++?
jalf
@jalf, I would be surprised that someone who has been using C for 2 months is solid on function pointers.
kenny
A: 

C++ is object orientated, C is not. So common things like keeping pointer code clean and comment's on functions/methods and understand how to not get infinite preprocessor loops using #IFDEFs.

However the object orientated approach can often be nicer to actually code thinking about objects. So you need to think about the new features difference.

ewanm89
+2  A: 

Here are some points :

1) Make sure you are proficient in Pointers. Focus on how Arrays and pointers works, what are the similarities and differences between them.

2) The best way to perfect c is to write programs. Write as many as you can. For starter you can write custom functions for some of the library functions.You may try your hands on Strcpy, strcmp, strncpy, memcpy, memmove.

3) Learn how to Debug.(Gdb is really cool).

4) Start following a particular coding style and try to stick with it.

5) Always furnish your code with meaningful comments.

Duleb
Next year is still far away. Don't worry about c++. I would advice that just concentrate on c skill and your logical reasoning ability.
Duleb
If gdb is really cool, what is MSVC's debugger? Super-awesome? At least. :-D
KiNgMaR
Pointers? They're less of an issue in C++ than C. How is this useful advice to someone transitioning from C to C++?
jalf
He would be moving to c++ next year and that ,as i already mentioned is long way off. At present he should just concentrate on C. I firmly believe that you don't know pointers, you don't know C.
Duleb
+5  A: 

C++ programs are totally different. you had better spend your time learning C++ than working on C elements trying to improve them for C++.

For example even the simple 'Hello World' program, differs considerably:

C:

#include <stdio.h>
int main(void)
{
  printf("Hello, world!\n");
  return 0;
}

C++:

#include <iostream>
int main()
{
   std::cout << "Hello, world!\n";
}

(Examples from here).

As 'printf' is a function whereas 'cout' is not a function but an instance of an ostream class.

Further reading: iostream.

Liran Orevi
Right, I vote for changing c++'s name to k++ : C is different of C++, it has nothing in common, except letter.
Clement Herreman
reaching the end of `main()` will return `0` in C99, so one difference less
Christoph
the first peice of code listed is 100% valid c++:<ewanm89@enterprise> ~ % g++ hello.cpp [0]<ewanm89@enterprise> ~ % ./a.out [0]Hello, world!<ewanm89@enterprise> ~ % cat hello.cpp [0]#include <stdio.h>int main(void){ printf("Hello, world!\n"); return 0;}
ewanm89
I agree with the answer text, but this isn't a very good example. It just shows that printf is replaced with cout, and it's in a different header. That in itself doesn't really illustrate that "C++ programs are totally different"
jalf
he return is handled identically, with c99 returning 0 at end of function, generally it is recommended to include cstdio rather than stdio.h (at end of day it is identical though).In fact the only difference in the second is you are using the object orientated iostream lib to do the console print out. And this about doubles the size of both the asm and the final binary with such a trivial piece of code.
ewanm89
I could start listing the asm ;)
ewanm89
most of the c++ version of such a trivial piece of code is object orientation layer initialization junk.
ewanm89
@jalf, you are right, it doesn't fully illustrate the difference, As you cleverly put it, C++ is huge, maybe this small example is enough to give the average novice the feeling that C++ is not the same as C, and will encourage to open a book for more elaborate examples. (On a side note it does introduce a bit about classes, namespaces, and the << operator, still there is so much more...)
Liran Orevi
+6  A: 

If you can get hold of it I'd recommend the first 3 chapters of The C++ Programming Language by the creator of C++ Bjarne Stroustrup.

In particular the "Notes to the reader" and "Tour of C++" will give you a good understanding of where/how C++ differs from C and to focus your further learning. Of course the whole book is useful to have nearby when working with C++.

Interestingly for your situation, in chapter 1, Bjarne actually says

"in the continuing debate on whether one needs to learn C before C++, I am firmly convinced that it is best to go directly to C++".

Of course he would, wouldn't he, but if you accept his reasoning you would be best to jump straight in to C++ as soon as possible.

Ash
@Ash: It is a compulsory text for the C++ courses at my Uni, will get it when funds allow. :)
_ande_turner_
+4  A: 

You're shifting to C++ means that you felt you needed classes, or better libraries. Thats what I feel. I am also learning better features of C++, with my C background. Uptil now, I have had a look at vectors mainly [apart from classes and templates].

I feel the languages are too similiar to

think of them completely separately.

Lazer
+4  A: 

My guess is that the C++ you will be learning is probably not going to be overly object oriented, at least it wasn't in my university anyway. We ran C++ programs essentially as C programs.

Definitely read up on how classes can be implemented, along with understanding the basics of pointers.

Your file I/O handling will be different as well...instead of fstream read up on the syntax of implementing the iostream functions.

Scour the web for tutorials on simple C++ programs...CodeProject is always a good resource.

espais
@espasis: C++ is used to teach OO, strange that teaching OO as a subject is left til 3rd year, and we've been using Java for the first 18months. :s
_ande_turner_
I'm one of the few at my university that understand how to code c/c++ in a non OOP way. The old timer C lecturers can but some of the new lecturers and most of the students have no idea how to code in a C style over a C++ style.
ewanm89
+3  A: 

Use structures and function pointers as much as possible to mimic the methods of the classes and the abstract methods.

For example, if you want to define a vehicle, and a car derived from vehicle using C, you would write (sorry, I won't check the code :-) ):

struct Vehicle
  {
  void (*checkFuel)(Vehicle*);
  void (*start)(Vehicle*);
  void (*move)(Vehicle*);
  void (*stop)(Vehicle*);
  }

void start1(Vehicle* v)
  {
  v->checkFuel(v);
  printf("START!");
  }

void start2(Vehicle* v)
  {
  v->checkFuel(v);
  printf("VROOOOMM!");
  }


struct Car
  {
  Vehicule base;
  int (*klaxon)(Car*);
  }

Vehicule* newVehicule()
 {
 Vehicule* v=(Vehicule*)malloc(sizeof(Vehicule));
 v->start= start1;
 v->move=
 (...)
 return v;
 }


Car* newCar()
 {
 Car* c=(Car*)malloc(sizeof(Car));
 Vehicule* v=(Vehicule*)c;
 v->start= start2;
 v->move=
 (...)
 c->kaxon=(...)
 return c;
 }
Pierre
To use the base struct's functions is it would it be Car* c = ...; c->base.function ?
_ande_turner_
As Vehicule is the *first* member of Car, you can safely cast it to Vehicule*. Car* c=(...); ((Vehicule*)c)->start((Vehicule*)c);
Pierre
+6  A: 

Keep the languages separate.

C and C++ can be appear similar, but they are different languages with different rules for similar constructs. If you can isolate one from the other, all the better.

When switching to C++ be ready to unlearn (learn a different, incompatible method) about:

  1. preprocessor: In C++ you should not use the preprocessor as much as in C.
  2. strings: C doesn't have them
  3. pointers: C++ can be coded to handle them more safely
pmg
A: 

The style of programing in C and C++ are entirely different. C++ is object oriented programing where as C is procedure oriented programing. C++ programing is the best in simulating real-world problems using classes/objects. But, basic concepts like pointers, structures, operators, casting operators, data handling are the same in both.. Sturctures and Classes are similar concept but not exactly.. so you can concentrate on programing using structures, pointers, operators and Memory managment while you are learning in 'C'

Red
+17  A: 

The best advice is probably to treat them as completely separate languages. Yes, most C code can be compiled by a C++ compiler, but it's generally not a good way to go.

C is very much a low-level hackery language. What you see is what you get. It has pointers and structs, so you use pointers and structs. It has very little type safety, so you ignore type safety as much as possible.

C++ on the other hand, allows a huge number of abstractions. Rather than pointers, you'll typically want to use iterators, which behave conceptually as pointers, but aren't (or might not be).

Instead of throwing away type information (for example having functions accept a void* so they'll work with any pointer type), you can use templates to retain type safety and still be able to reuse the same single function definition.

And you're given an excellent standard library which enables you to express complex algorithms in terms of simple predefined building blocks.

C++ is a multi-paradigm language. Some answers here have said that C++ is object-oriented, which is partially true. It does have support for object-oriented code, yes, but that's not what C++ is.

C++ also has support for generic programming, which is often preferable over OOP. It has some limited support for functional programming as well. And of course, it still has support for C-style procedural programming as well. The trick in C++ is to understand all of these, so you know which to use when. That is C++'s strength, the ability to switch between and mix all these paradigms. People who call C++ an OOP language miss the point just as much as people who call it an improved C. It allows you to write code in either of these styles, but neither of these are really worthwhile in themselves. C is a better C-like language, and there are plenty of better OOP languages. If you want to stick to one single paradigm, use a language designed for that.

jalf
Thank you for a most inspiring answer.
Liran Orevi
+3  A: 

Funny how many people here claim that C and C++ are "completely different", and how "C++ is object oriented, C is not"...

First off: C++ was initially designed as an extension of the C language. Actually, the C++ standard documentation refers to the C standard. It is true that many things are done different in C++ than in C, but to claim that the two are completely disjunct goes a bit far. Good C code can be compiled with a C++ compiler, and for some trivial problems, C and C++ solutions can look next to identical.

Second, don't let yourself be fooled into believing that C++ is "an object-oriented language". C++ is a language that supports object orientation, true. But it also supports generic programming, and procedural programming. Focussing only on the OOP aspect of C++ takes away much of its power.

As for habits to get into... don't become too attached to C-style strings (char *) and arrays (int foo[]). Both are very rarely used in C++, as there are the much more powerful (and convenient) replacements, string and vector.

Pay close attention to pointers, and dynamic memory allocations. While good C++ code has very little of them, you have to be aware of how they work. While doing so, you will also realize why good C++ code encapsules them, or replaces them with references, so they don't appear much in production-quality code.

When designing your C code, start with a struct holding relevant data (e.g. fields of an address), and then construct functions working on that type of struct (address_read( struct address_t * ), address_write( struct address_t * ), address_modify_name( struct address_t *, char * ) etc.). Add the main() function that calls those functions in appropriate order last. The data is the important part of the program, not the function. That's something that will make the step to C++ (and object-orientation) easier.

There is more, but I don't claim to be answering everything in one SO post. :-)

DevSolar
+14  A: 

There are already a lot of good answers. Mine will be more "mindset oriented".

Data vs. Action!

  • In C, everything is done to think like "Apply this effect to this data".
  • In C++, this is more like "Data should behave".

While the "Data should behave" can be done in C (and it is done!), in C++, everything needed to implement this easily is already accessible : Encapsulation, constructors, overloading overriding, templates, etc..

I found this "Data should behave" idea a very good guiding principle when coding in C++.

C++ syntactic sugar is not optional

You'll find a lot of C++ features that could be done in C, and some people use it as an excuse to not learn them. This mindset is dangerous (this is the part "treat C++ as a new language, and not an extension" seen in some posts).

A side effect of avoiding writing C++ the C++ way is that while a C++ developer is supposed to understand C++ code, he/she is not supposed to understand your little personal framework mimicking C++ sugar with C-only features. In fact, he/she won't be interested by your framework. Truth to be said, he/she will only feel pity/contempt for you because you lost precious time producing that. Ultimately, he/she will hate you if he/she must use your framework instead of the C++ sugar.

Guiding principles like "I can do this the C way" will just make you miss the wagon. Better not to start learning C++ at all if you already have this kind of C-centric mode of thinking.

Your language of choice is never the best. YOU are supposed to become the best. If you write C++ code, then write it the C++ way.

C-compatible C++ code is a semantic error

Typedefing your structs to make them compilable by a C compiler is a bad joke. Using pointers instead of references is a slap to your future self. The extern "C" will only make your code weaker, not stronger. And using void * for genericity will only increase the number of fellow C++ coders who will gladly pay to have your head removed in a spectacularly painful way.

Don't ever bother to write C-compatible code unless you really really really have to.

You'll just weight yourself down with a time-consuming coding style for a feature you'll never use.

The compiler is a powerful friend/enemy

Working low level has strange effects on some developers. They believe a lot on their control of the compiled code. Delegating this control to higher-level constructs is difficult for them.

A good example of that is ditching the constructor/destructor pattern because "sometimes, constructors takes too much time... Better to do it my way...".

The C++ compiler is quite able to optimize apparently unoptimized code. In fact, the code produced by the compiler can be quite different from the one you believe you produced.

Don't try to be better/smarter than the compiler is because:

  1. You probably already lost the fight, as even old compilers will usually produce better code than you can dream to do today
  2. Even if you did win the fight today, it will automatically turn into a defeat tomorrow, as compilers will become better and better in the future, so your "optimized code" of today will become the program bottleneck and refactoring subject of the next years (not mentioning shameful memories for you).

So, trust your compiler.

Don't micromanage the production of your code. Do your own work, and let the compiler do its own.

Note that this point should not be used to justify production of slow/inefficient code. If premature optimization is the root of all evil, you must still use your knowledge of the language and the compiler to produce good and efficient code (see the next point).

Know the advantages/drowbacks/costs of each C++ construct

For example, the fact virtual methods adds one indirection to the function call means for some people that performance will decrease dramatically. Truth is, performance problems are often elsewhere.

Ignorance is no excuse.

Know the code produced for each C++ construct (i.e. inlining, references, constructor, destructor, exception, function overload, function override, template, virtual function, etc.). Know what will be optimized away, and what won't.

This way, not only you won't pay for what you don't need (this is a guiding principle of C++), but you will also profit from what costs you zero but brings you a lot.

Be humble

There are people doing research in C++ that were better at C++ the day of their birth than most of us will ever be. Even if we ignore Stroustrup, names like Meyers, Abrahams, Alexandrescu, Sutter, etc. regularly crop up alongside new ideas. Despite (or as a consequence of) its alien outlook, STL is revolutionary library. And a library like Boost, despite its "small size" when compared to some complete frameworks (like Java or .NET APIs), is a massive repository of excellent code offered to you to study.

Just because you find some new feature "strange" or "alien", don't underestimate it. Trying to understand it will PERHAPS bring you another tool at your disposal, and will ALWAYS increase your mastery of the language, and will ALWAYS make your brain work, which is a good thing in the dev business.

Most people I know who failed their "conversion to C++" just assumed this or this feature was useless because they did not bother to understand it.

RAII !!!!

If you don't know what it is, learn it.

Without RAII, your C++ code is just bugged code that avoided compilation error.

RAII is the single most important notion of C++.

Everything else is related.

paercebal
A couple of things to add to this excellent answer. Use STL from day 1 - don't think of it as clever stuff to use once you are an expert.Before inventing something look in boost.
Martin Beckett
To complete mgb's answer: For your production code, use STL. STL code will 99% ALWAYS be better than your own. Now, a good exercise on your free time is to create your own classes, and compare the result to STL's, both in interface, implementation and performance.
paercebal
and correctness. It's easy enough to create a STL replacement that seems to work well. But it'll almost certainly have subtle bugs regarding exception safety, resource leaks or relying on undefined behavior.
jalf
@jalf : You're right!
paercebal
Awesome!!! My favorite is the part about RAII.
C Johnson