Відповіді:
Якщо порівнювати C89
з, C++
то ось кілька речей
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 додає ще безліч інших випадків
// 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;
це юридичний TU в C, але не в C ++.
auto a;
це дійсно в останній версії стандарту C ++.
a
?
auto x;
, невірно в останній редакції, але, наприклад, auto x = 0;
є. Спочатку я був трохи шокований :)
C ++ також має нові ключові слова. Нижче наведено дійсний код C, але він не компілюється під C ++:
int class = 1;
int private = 2;
int public = 3;
int virtual = 4;
Речей багато. Просто простий приклад (цього має бути достатньо, щоб довести, що C не є належним підмножиною C ++):
int* test = malloc(100 * sizeof(int));
слід компілювати в C, але не в C ++.
int*
.
void *
, який в C може бути призначений будь-якому типу вказівника, а C ++ не може бути призначений жодному іншому типу вказівника.
У C ++, якщо ви оголосили a struct
, union
або enum
, його ім'я буде негайно доступно без будь-яких кваліфікуючих осіб:
struct foo { ... };
foo x; // declare variable
У C це не спрацює, оскільки типи, проголошені таким чином, живуть у власних просторах імен. Таким чином, ви повинні написати:
struct foo { ... };
struct foo x; // declare variable
Зауважте наявність struct
там у другому рядку. Ви повинні зробити те ж саме для union
і enum
(використовуючи відповідні ключові слова) або скористатися typedef
трюком:
typedef struct { ... } foo;
foo x; // declare variable
Отже, у вас може бути кілька типів різних типів, названих однаковими в C, оскільки ви можете роз'єднати:
struct foo { ... };
typedef enum { ... } foo;
struct foo x;
foo y;
Однак у C ++, хоча ви можете префіксувати struct
ім'я за ключовим словом struct
кожного разу, коли на нього посилаєтесь, простори імен об'єднуються, і тому вищевказаний фрагмент C недійсний. З іншого боку, C ++ спеціально робить виняток, щоб дозволити типу та typedef для цього типу мати однакове ім’я (очевидно, без ефекту), щоб дозволити використання typedef
трюку, незмінного від C.
struct
, union
і enum
) один і ті ж простір імен. Кращим прикладом може бутиstruct foo { ... }; typedef enum { ... } foo;
Це також залежить від того, який різновид C ви використовуєте. Stroustrup зробив C ++ максимально сумісним і не більше сумісним зі стандартами ANSI 1989 та 1990 р. ISO, а версія 1995 року нічого не змінила. Комітет C пішов дещо в іншому напрямку зі стандартом 1999 року, а комітет C ++ змінив наступний стандарт C ++ (можливо, вийшов наступного року або близько того), щоб відповідати деяким змінам.
Stroustrup перераховує несумісність із C90 / C95 у Додатку B.2 до "Мова програмування C ++", Спеціальне видання (яке є 3-м виданням з деяким доданим матеріалом):
'a'
є int
в C, a char
в C ++.
Розмір перерахунку знаходиться int
в C, не обов'язково в C ++.
C ++ має //
коментарі до кінця рядка, C - ні (хоча це звичайне розширення).
У C ++ struct foo {
визначення вкладається foo
у глобальний простір імен, тоді як у C воно має бути позначене як struct foo
. Це дозволяє struct
визначити тенізацію імені у зовнішній області і має кілька інших наслідків. Крім того, C дозволяє розширювати сферу для struct
визначень і дозволяє їх у зворотному описі типу та аргументу.
C ++ загалом суєтніше щодо типів. Це не дозволить призначити ціле число числу enum
, а void *
об'єкти не можуть бути призначені іншим типам вказівників без набору. У C можна надати ініціалізатор перебільшення ( char name[5] = "David"
де C відкине проміжний нульовий символ).
C89 дозволяється неявним int
у багатьох контекстах, а C ++ - ні. Це означає, що всі функції повинні бути оголошені в C ++, тоді як у C89 це часто можна було отримати, припускаючи int
все, що застосовується в декларації функції.
У C можна перейти з-за меж блоку всередину за допомогою оператора з міткою. У C ++ це заборонено, якщо він пропускає ініціалізацію.
C є більш ліберальним у зовнішній зв'язці. У C глобальна const
змінна неявно extern
, і це не вірно в C ++. C дозволяє глобальному об'єкту даних кілька разів оголошуватися без extern
, але це не відповідає дійсності в C ++.
Багато ключових слів C ++ не є ключовими словами на C, або #define
d у стандартних заголовках C.
Є також деякі старі функції C, які вже не вважаються хорошим стилем. В C ви можете оголосити функцію з визначеннями аргументів після списку аргументів. У C декларація як int foo()
означає, що foo()
може приймати будь-яку кількість аргументів будь-якого типу, тоді як у C ++ це еквівалентно int foo(void)
.
Це, здається, охоплює все від Stroustrup.
Якщо ви використовуєте gcc, ви можете скористатись попередженням, -Wc++-compat
щоб попередити про код C, який певним чином є сумнівним у C ++. Наразі його використовують у самому gcc, а останнім часом він значно покращився (можливо, спробуйте нічну версію, щоб отримати найкраще, що можна).
(Це абсолютно не відповідає на питання, але людям це може сподобатися).
Найбільшою різницею, на яку я думаю, є те, що це дійсний вихідний файл C:
int main()
{
foo();
}
Зауважте, що я foo
ніде не декларував .
Окрім мовних відмінностей, C ++ також вносить деякі зміни в бібліотеку, успадковану від C, наприклад, деякі функції повертаються const char *
замість char *
.
s,C,C89,
зауважити, що це недійсний вихідний файл C99.
#include <stdio.h>
int new (int n) {
return n/2;
}
int main(void) {
printf("%d\n", new(10));
return 0;
}
Дивіться також запис C ++ FAQ .
Низка відповідей тут охоплює різниці в синтаксисі, які можуть спричинити збій компіляторів C ++ у вихідному коді C89 (або C99). Однак є деякі тонкі мовні відмінності, які є законними для обох мов, але це може спричинити різну поведінку. sizeof (char)
Різниця , що Навин згадується один з прикладів, але написати програму , яка буде друкувати «C» , якщо скомпільовано як (ANSI) C програми, і «C ++» , якщо скомпільовано як ++ програм C перераховані деякі інші.
Компілятори C зазвичай дозволяють вирізати невеликий кут, який C ++ не робить. C ++ набагато суворіший за C. І взагалі деякі з цих відмінностей залежать від компілятора. g ++ дозволяє деякі речі, наприклад, компілятор Intel C ++. Навіть досить добре написаний код C не компілюється із сучасним компілятором C ++.
Ви не можете порівнювати мови лише за синтаксисом. Якщо ви це зробите, можливо, ви можете бачити C як підмножину C ++. На мою думку, того, що C ++ є OO (а C - ні), достатньо, щоб сказати, що C і C ++ - це різні мови.