Ответы:
Если сравнить 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 ++, если вы объявляете 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 вы используете. Страуструп сделал C ++ максимально совместимым и не более совместимым со стандартами ANSI 1989 и ISO 1990, и версия 1995 года ничего не изменила. Комитет C пошел в несколько ином направлении со стандартом 1999 года, а комитет C ++ изменил следующий стандарт C ++ (вероятно, в следующем году или около того), чтобы соответствовать некоторым изменениям.
Страуструп перечисляет несовместимость с C90 / C95 в Приложении B.2 «Язык программирования C ++», Special Edition (это 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в стандартных заголовках C.
Есть также некоторые старые особенности C, которые больше не считаются хорошим стилем. В C вы можете объявить функцию с определениями аргументов после списка аргументов. В C такое объявление int foo()означает, чтоfoo() может принимать любое количество аргументов любого типа, а в C ++ оно эквивалентно int foo(void).
Похоже, это касается всего, что касается Страуструпа.
Если вы используете 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 ++ .
Ряд ответов здесь касается различий в синтаксисе, которые могут привести к сбою компиляторов C ++ в исходном коде C89 (или C99). Однако есть некоторые тонкие языковые различия, которые допустимы для обоих языков, но могут привести к разному поведению. sizeof (char)Разница , что Навин упоминается один из примеров, но написать программу , которая будет печатать «C» , если скомпилирован как (ANSI) C программы, и «C ++» , если скомпилирован как ++ программ C перечислены некоторые другие.
Компиляторы C обычно допускали небольшую обрезку углов, в отличие от C ++. C ++ намного строже, чем C. И, как правило, некоторые из этих различий зависят от компилятора. g ++ допускает некоторые вещи, которые, например, не позволяет компилятору Intel C ++. Даже хорошо написанный код C не будет компилироваться с современным компилятором C ++.
Вы не можете сравнивать языки только по синтаксису. Если вы это сделаете, возможно, вы увидите C как подмножество C ++. На мой взгляд, того факта, что C ++ - объектно ориентированный (а C - нет), достаточно, чтобы сказать, что C и C ++ - разные языки.