Antworten:
Wenn Sie vergleichen C89
mit C++
dann sind hier ein paar Dinge ,
int n;
int n; // ill-formed: n already defined
int a[1];
int (*ap)[] = &a; // ill-formed: a does not have type int[]
int b(a) int a; { } // ill-formed: grammar error
struct A { struct B { int a; } b; int c; };
struct B b; // ill-formed: b has incomplete type (*not* A::B)
auto a; // ill-formed: type-specifier missing
C99 fügt eine ganze Reihe anderer Fälle hinzu
// ill-formed: invalid syntax
void f(int p[static 100]) { }
// ill-formed: n is not a constant expression
int n = 1;
int an[n];
// ill-formed: fam has incomplete type
struct A { int a; int fam[]; };
// ill-formed: two names for one parameter?
void copy(int *restrict src, int *restrict dst);
typedef;
ist eine legale TU in C, aber nicht in C ++.
auto a;
in der neuesten C ++ - Standardversion gültig ist.
a
?
auto x;
also in der neuesten Version nicht gültig, ist es aber zum Beispiel auto x = 0;
. Ich war zuerst ein bisschen schockiert :)
C ++ hat auch neue Schlüsselwörter. Folgendes ist gültiger C-Code, wird jedoch unter C ++ nicht kompiliert:
int class = 1;
int private = 2;
int public = 3;
int virtual = 4;
Es gibt viele Dinge. Nur ein einfaches Beispiel (es sollte ausreichen zu beweisen, dass C keine richtige Teilmenge von C ++ ist):
int* test = malloc(100 * sizeof(int));
sollte in C kompiliert werden, aber nicht in C ++.
int*
.
void *
, das in C einem beliebigen Zeigertyp zugewiesen werden kann, und C ++ kann keinem anderen Zeigertyp zugewiesen werden.
Wenn Sie in C ++ ein struct
, union
oder deklarieren , enum
ist der Name sofort ohne Qualifizierer zugänglich:
struct foo { ... };
foo x; // declare variable
In C funktioniert dies nicht, da die so deklarierten Typen in ihren eigenen Namespaces leben. Sie müssen also schreiben:
struct foo { ... };
struct foo x; // declare variable
Beachten Sie das Vorhandensein von struct
dort in der zweiten Zeile. Sie müssen dasselbe für union
und enum
(unter Verwendung der entsprechenden Schlüsselwörter) tun oder den typedef
Trick verwenden:
typedef struct { ... } foo;
foo x; // declare variable
Folglich können Sie in C mehrere Arten verschiedener Arten haben, die gleich benannt sind, da Sie Folgendes unterscheiden können:
struct foo { ... };
typedef enum { ... } foo;
struct foo x;
foo y;
In C ++ können Sie einem struct
Namen zwar bei struct
jedem Verweis ein Schlüsselwort voranstellen , die Namespaces werden jedoch zusammengeführt, sodass das obige C-Snippet nicht gültig ist. Andererseits macht C ++ speziell eine Ausnahme, um zuzulassen, dass ein Typ und ein Typedef für diesen Typ denselben Namen haben (offensichtlich ohne Auswirkung), um die Verwendung eines typedef
Tricks zu ermöglichen, der von C unverändert bleibt .
struct
, union
und enum
) den gleichen Namensraum teilen. Ein besseres Beispiel wärestruct foo { ... }; typedef enum { ... } foo;
Dies hängt auch davon ab, welche C-Variante Sie verwenden. Stroustrup machte C ++ so kompatibel wie möglich und nicht mehr kompatibel mit den ANSI- und ISO-Standards von 1989 und 1990, und die Version von 1995 änderte nichts. Das C-Komitee ging mit dem Standard von 1999 in eine etwas andere Richtung, und das C ++ - Komitee hat den nächsten C ++ - Standard (wahrscheinlich nächstes Jahr oder so) geändert, um einigen Änderungen zu entsprechen.
Stroustrup listet Inkompatibilitäten mit C90 / C95 in Anhang B.2 von "The C ++ Programming Language", Special Edition (3. Auflage mit zusätzlichem Material) auf:
'a'
ist ein int
in C, ein char
in C ++.
Die Größe einer Aufzählung ist int
in C angegeben, nicht unbedingt in C ++.
C ++ hat //
Kommentare am Zeilenende, C nicht (obwohl es eine übliche Erweiterung ist).
In C ++ wird eine struct foo {
Definition foo
in den globalen Namespace eingefügt, während sie in C als bezeichnet werden müsste struct foo
. Dies ermöglicht einer struct
Definition, einen Namen in einem äußeren Bereich zu schattieren, und hat einige andere Konsequenzen. Außerdem erlaubt C einen größeren Spielraum für struct
Definitionen und erlaubt sie in Rückgabetyp- und Argumenttypdeklarationen.
C ++ ist in Bezug auf Typen im Allgemeinen umständlicher. Es ist nicht möglich, einer Ganzzahl eine Ganzzahl zuzuweisen enum
, und void *
Objekte können ohne Umwandlung keinen anderen Zeigertypen zugewiesen werden. In C ist es möglich, einen übergroßen Initialisierer bereitzustellen ( char name[5] = "David"
wobei C das nachfolgende Nullzeichen verwirft).
C89 ist int
in vielen Kontexten implizit erlaubt und C ++ nicht. Dies bedeutet, dass alle Funktionen in C ++ deklariert werden müssen, während es in C89 oft möglich war, int
für alles, was in der Funktionsdeklaration anwendbar ist , auszukommen .
In C ist es möglich, mit einer beschrifteten Anweisung von außerhalb eines Blocks nach innen zu springen. In C ++ ist dies nicht zulässig, wenn eine Initialisierung übersprungen wird.
C ist liberaler in der externen Verknüpfung. In C ist eine globale const
Variable implizit extern
und in C ++ nicht wahr. Mit C kann ein globales Datenobjekt mehrmals ohne ein deklariert werden extern
, dies ist jedoch in C ++ nicht der Fall.
Viele C ++ - Schlüsselwörter sind keine Schlüsselwörter in C oder #define
d in Standard-C-Headern.
Es gibt auch einige ältere Funktionen von C, die nicht mehr als guter Stil angesehen werden. In C können Sie eine Funktion mit den Argumentdefinitionen nach der Liste der Argumente deklarieren. In C int foo()
bedeutet eine Deklaration wie , dass foo()
eine beliebige Anzahl von Argumenten jeder Art akzeptiert werden kann, während sie in C ++ äquivalent zu ist int foo(void)
.
Das scheint alles von Stroustrup abzudecken.
Wenn Sie gcc verwenden, können Sie die Warnung verwenden -Wc++-compat
, um Sie vor C-Code zu warnen , der in C ++ in irgendeiner Weise zweifelhaft ist. Es wird derzeit in gcc selbst verwendet und ist in letzter Zeit viel besser geworden (versuchen Sie es vielleicht mit einer nächtlichen Version, um das Beste zu bekommen, was Sie können).
(Dies beantwortet die Frage nicht unbedingt, aber die Leute mögen es vielleicht).
Der größte Unterschied besteht meiner Meinung nach darin, dass dies eine gültige C-Quelldatei ist:
int main()
{
foo();
}
Beachten Sie, dass ich foo
nirgendwo deklariert habe .
Abgesehen von Sprachunterschieden nimmt C ++ auch einige Änderungen an der Bibliothek vor, die es von C geerbt hat, z. B. geben einige Funktionen const char *
statt zurück char *
.
s,C,C89,
beachten, dass es sich um eine ungültige C99-Quelldatei handelt.
#include <stdio.h>
int new (int n) {
return n/2;
}
int main(void) {
printf("%d\n", new(10));
return 0;
}
Siehe auch den C ++ - FAQ-Eintrag .
Einige der Antworten hier beziehen sich auf Syntaxunterschiede, die dazu führen würden, dass C ++ - Compiler im C89- (oder C99-) Quellcode fehlschlagen. Es gibt jedoch einige subtile Sprachunterschiede, die in beiden Sprachen legal sind, aber zu unterschiedlichem Verhalten führen würden. Der sizeof (char)
Unterschied, den Naveen erwähnte, ist ein Beispiel, aber Schreiben Sie ein Programm, das "C" druckt, wenn es als (ANSI) C-Programm kompiliert wird, und "C ++", wenn es als C ++ - Programm kompiliert wird, listet einige andere auf.
C-Compiler erlaubten im Allgemeinen ein kleines Schneiden von Ecken, das C ++ nicht zulässt. C ++ ist viel strenger als C. Und im Allgemeinen sind einige dieser Unterschiede vom Compiler abhängig. g ++ erlaubt einige Dinge, die der Intel C ++ - Compiler zum Beispiel nicht tut. Selbst ziemlich gut geschriebener C-Code lässt sich mit einem modernen C ++ - Compiler nicht kompilieren.
Sie können Sprachen nicht nur nach Syntax vergleichen. Wenn Sie das tun, können Sie C vielleicht als Teilmenge von C ++ sehen. Meiner Meinung nach reicht die Tatsache, dass C ++ OO ist (und C nicht), aus, um zu sagen, dass C und C ++ verschiedene Sprachen sind.