Odpowiedzi:
Jeśli porównasz C89z, C++oto kilka rzeczy
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 dodaje całą masę innych przypadków
// 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;to legalna jednostka TU w C, ale nie w C ++.
auto a;obowiązuje w najnowszej wersji standardu C ++.
a ?
auto x;nie obowiązuje w najnowszej wersji, ale na przykład auto x = 0;jest. Na początku byłem trochę zszokowany :)
C ++ ma również nowe słowa kluczowe. Poniższy kod jest prawidłowym kodem w C, ale nie kompiluje się w C ++:
int class = 1;
int private = 2;
int public = 3;
int virtual = 4;
Jest mnóstwo rzeczy. Prosty przykład (wystarczy udowodnić, że C nie jest odpowiednim podzbiorem C ++):
int* test = malloc(100 * sizeof(int));
powinien kompilować się w C, ale nie w C ++.
int*.
void *, które w C można przypisać do dowolnego typu wskaźnika, a C ++ nie może być przypisane do żadnego innego typu wskaźnika.
W C ++, jeśli zadeklarujesz a struct, unionlub enum, jego nazwa jest natychmiast dostępna bez żadnych kwalifikatorów:
struct foo { ... };
foo x; // declare variable
W C to nie zadziała, ponieważ zadeklarowane w ten sposób typy żyją w swoich własnych odrębnych przestrzeniach nazw. Musisz więc napisać:
struct foo { ... };
struct foo x; // declare variable
Zwróć uwagę na obecność structtam w drugiej linii. Musisz zrobić to samo dla unioni enum(używając odpowiednich słów kluczowych) lub użyć typedefsztuczki:
typedef struct { ... } foo;
foo x; // declare variable
W związku z tym możesz mieć kilka typów różnych rodzajów nazwanych tak samo w C, ponieważ możesz ujednoznacznić:
struct foo { ... };
typedef enum { ... } foo;
struct foo x;
foo y;
Jednak w C ++, chociaż możesz poprzedzić structnazwę słowem kluczowym structza każdym razem, gdy się do niej odwołujesz, przestrzenie nazw są scalane, więc powyższy fragment C jest nieprawidłowy. Z drugiej strony, C ++ robi wyjątek, aby pozwolić typowi i definicji typu dla tego typu mieć tę samą nazwę (oczywiście bez efektu), aby umożliwić użycie typedeftriku niezmienionego od C.
struct, unioni enum) udział ten sam nazw. Lepszym przykładem może byćstruct foo { ... }; typedef enum { ... } foo;
Zależy to również od używanej odmiany C. Stroustrup uczynił C ++ tak kompatybilnym, jak tylko mógł, a nie bardziej kompatybilnym, z normami ISO 1989 ANSI i 1990, a wersja 1995 niczego nie zmieniła. Komisja C poszła w nieco innym kierunku ze standardem 1999, a komisja C ++ zmieniła następny standard C ++ (prawdopodobnie w przyszłym roku), aby dostosować się do niektórych zmian.
Stroustrup wymienia niezgodności z C90 / C95 w Dodatku B.2 „Języka programowania C ++”, wydanie specjalne (czyli wydanie trzecie z dodatkowymi materiałami):
'a'jest intw C, achar w C ++.
Rozmiar wyliczenia to int w C, niekoniecznie w C ++.
C ++ ma // komentarze na końcu linii, C nie (chociaż jest to powszechne rozszerzenie).
W C ++ struct foo {definicja umieszczana jest foow globalnej przestrzeni nazw, podczas gdy w C musiałaby być nazywana struct foo. Pozwala to structdefinicji przesłonić nazwę w zakresie zewnętrznym i ma kilka innych konsekwencji. Ponadto C umożliwia większy zakresstruct definicji i zezwala na ich deklaracje typu zwracanego i typu argumentu.
C ++ jest ogólnie bardziej zawstydzony co do typów. Nie pozwoli na przypisanie liczby całkowitej do obiektu enum, a void *obiekty nie mogą być przypisane do innych typów wskaźników bez rzutowania. W C można podać zbyt duży inicjator (char name[5] = "David" gdzie C odrzuci końcowy znak null).
C89 jest dozwolone intw wielu kontekstach, a C ++ nie. Oznacza to, że wszystkie funkcje muszą być zadeklarowane w C ++, podczas gdy w C89 często można było załatwić intwszystko, co ma zastosowanie w deklaracji funkcji.
W C można przeskoczyć z zewnątrz bloku do wewnątrz za pomocą instrukcji z etykietą. W C ++ nie jest to dozwolone, jeśli pomija inicjalizację.
C jest bardziej liberalny w połączeniach zewnętrznych. W C constzmienna globalna jest niejawnie extern, aw C ++ to nieprawda. C pozwala na kilkakrotne zadeklarowanie globalnego obiektu danych bez znaku extern, ale nie jest to prawdą w C ++.
Wiele słów kluczowych w języku C ++ nie jest słowami kluczowymi w języku C lub występuje #definew standardowych nagłówkach C.
Istnieją również starsze funkcje C, które nie są już uważane za dobry styl. W C możesz zadeklarować funkcję z definicjami argumentów po liście argumentów. W C deklaracja taka jak int foo()oznacza, która foo()może przyjąć dowolną liczbę argumentów dowolnego typu, podczas gdy w C ++ jest to odpowiednik int foo(void).
Wydaje się, że obejmuje wszystko od Stroustrup.
Jeśli używasz gcc, możesz użyć ostrzeżenia -Wc++-compat do ostrzeżenia o kodzie w C, który jest w jakiś sposób wątpliwy w C ++. Obecnie jest używany w samym gcc, a ostatnio stał się znacznie lepszy (może spróbuj nocnej wersji, aby uzyskać najlepsze możliwe).
(To nie jest dokładną odpowiedzią na pytanie, ale ludziom może się to podobać).
Myślę, że największą różnicą jest to, że jest to prawidłowy plik źródłowy w języku C:
int main()
{
foo();
}
Zauważ, że nie zadeklarowałem foo nigdzie .
Oprócz różnic językowych, C ++ wprowadza również pewne zmiany w bibliotece, którą odziedziczył po C, np. Niektóre funkcje zwracają const char *zamiast char *.
s,C,C89,i zauważyć, że jest to nieprawidłowy plik źródłowy C99.
#include <stdio.h>
int new (int n) {
return n/2;
}
int main(void) {
printf("%d\n", new(10));
return 0;
}
Zobacz także wpis C ++ FAQ .
Szereg odpowiedzi tutaj dotyczy różnic w składni, które mogą spowodować niepowodzenie kompilatorów C ++ w kodzie źródłowym C89 (lub C99). Istnieją jednak pewne subtelne różnice językowe, które są legalne w obu językach, ale skutkują różnymi zachowaniami. sizeof (char)Różnicą, że Naveen wspomniano jest jednym z przykładów, ale Napisz program, który będzie drukować „C”, jeśli skompilowany jako (ANSI) C programu, a „C ++” czy kompilowany jako C ++ programu list inni.
Kompilatory C generalnie pozwalały na małe cięcie narożników, czego C ++ nie robi. C ++ jest dużo bardziej rygorystyczny niż C. I ogólnie, niektóre z tych różnic są zależne od kompilatora. g ++ pozwala na pewne rzeczy, na przykład kompilator Intel C ++. Nawet całkiem dobrze napisany kod w C nie da się skompilować za pomocą nowoczesnego kompilatora C ++.
Nie można porównywać języków tylko za pomocą składni. Jeśli to zrobisz, być może zobaczysz C jako podzbiór C ++. Moim zdaniem fakt, że C ++ to OO (a C nie jest) wystarczy, aby powiedzieć, że C i C ++ to różne języki.