Answers:
如果您与进行比较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;在C中是合法的TU,但在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 ++专门为允许类型和该类型的类型定义具有相同的名称(显然无效)而允许使用typedefC不变的技巧。
struct,union和enum)共享相同的命名空间。一个更好的例子是struct foo { ... }; typedef enum { ... } foo;
这也取决于您使用的是哪种C。Stroustrup使C ++尽可能兼容,但不再兼容1989年的ANSI和1990年的ISO标准,而1995年的版本则保持不变。C委员会的方向与1999年标准有所不同,C ++委员会已更改了下一个C ++标准(可能在明年左右发布),以适应某些更改。
Stroustrup在“ C ++编程语言”特别版(这是第3版,其中添加了一些补充材料)的附录B.2中列出了与C90 / C95不兼容的内容:
'a'int在C中是C,char在C ++中是a 。
枚举的大小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标头中的d。
还有一些C的较旧的功能,它们不再被认为是好的样式。在C语言中,可以在参数列表之后声明带有参数定义的函数。在C中,像这样的声明int foo()意味着foo()可以接受任意数量的任何类型的参数,而在C ++中,它等效于int foo(void)。
这似乎涵盖了Stroustrup的所有内容。
如果使用gcc,则可以使用警告-Wc++-compat向您发出有关C代码的警告,而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)Naveen提到的区别是一个示例,但是编写一个程序,如果将其编译为(ANSI)C程序,则将打印“ C”,而如果将其编译为C ++程序,则将打印“ C ++”,列出了其他一些程序。