I have only read the first couple replies. But, here's a good answer.
At a high level, C++ supports better code design by providing an organizational paradigm that maps more to our world and the things we tend to simulate. C++ compilers also support a few features that C compilers don't.
But, the following are true:
* Most C++ code that I have seen (thousands of programs) were written as though they were written in C. Classes were used for little more than namespace value. You can spot programs like this as while they may have many classes, their class hierarchy is roughly flat.
* You can do about the same thing in C that you can in C++, with a little [mental, and code] effort.
On that second one, consider this:
* In C, you define a struct (Player) that is to represent info for a game player (name, position, facing).
* All of your C functions that relate to the player have the form:
void someFunc( Player* player, [other parameters])
for e.g.:
void movePlayer( Player* player, float x, float y, float z )
You have essentially done what C++ does; you have encapsulated player data into a discrete storage unit, and you have written methods that operate on this block of data.
In C++, the Player* parameter is hidden from your code, but available inside methods as "this".
Inheritance could be done as follows:
struct DeadPlayer {
Player player;
Point deathLocation;
}
Now, you write methods that take a DeadPlayer* as their first argument (and observe, you can pass DeadPlayer pointers to all methods that expect a Player).
So, the C++ language is really about data organization and coding style, not so much about underlying behavior.
Oh, and yes, there are a few more details than this, such as V-Table points and the like, but they aren't essential to understanding the difference.
One final note: while you can do just about anything in C you can in C++, there are a handful of advantages to C++. With the example Player above, it might be possible to send a mal-formed or un-initialized Player to a method, whereas in C++, it is easier to isolate control over the classes data so that you can assure it's state is consistent and always good. You could "hack" around these protections (via static casting), but in general, if you use the language as Stroustrup intended, it can really save a lot of headaches and prevent a lot of bugs.