有什么我可以在C中做,但我不能用C ++做?

有什么我可以在C中做,但我不能用C ++做? 我在一个样本面试问题网站上偶然发现了这个问题……

以下是与C ++不兼容的Cfunction的详细列表 。

声明一个名为’class’的变量,如:

int class = 0; 

…那就是我可以用C做什么但不能用C ++做。

这两种语言都是图灵完备的,所以理论上你可以在两者中编写同样function的应用程序。

OTOH,C ++不是C的超集。特别是C99具有C ++没有的一些function。 例如指定的初始值设定项,结构中的可变长度数组和自动变量。 根据你的“任何东西”,这可能是C ++不能做但C可以做的事情。

在C中,您可以创建数组文字(“复合文字”),但在C ++中则不能

 /* p points to the first element of an array of 4 int */ int *p = (int[]){1, 2, 3, 4}; 

您还可以创建一个在编译时尚未知的大小的数组,但C ++没有这种可能性(“可变长度数组”):

 // create array. size is known at runtime only. int p[rand() % 5 + 1]; 
 int new = 0; 

在C中工作,但显然无法在C ++中工作,因为’new’是一个保留字。

还有其他一些带有保留字的“技巧”,但除此之外,你几乎可以用C语言做C中的所有事情。

你可以在C语言中一些你不能用C ++编写的东西(因为C ++有更严格的语法检查,而C有更广泛的’遗留’语法)。

此外,可能有一些运行时环境(O / S +库+编译器)支持C但不支持C ++,因此您可以在那些无法执行C ++的平台上执行C.

C ++缺少C99的restrict限定符 。 因此,没有办法告诉编译器基于知道指针不是别名来执行优化。

相当多的事情。 例如,在C中,您可以编写如下代码:

 void * v = 0; char * p = v; 

你可以创建这样的数组:

 int main() { int n = 42; int a[n]; return 0; } 

它们都不会在C ++下编译。

从语法上讲,你可以在C中编写一些不能用C ++编译的东西(参见ISO C和ISO C ++之间的不兼容性,以获得难以理解的细节)。 如果你问的是更高级别,如果有一些程序可以用C语言编写,但不能用C ++编写,那么答案就是“不”。

在’C’中,您不需要前向声明。 这允许您传递错误解释的参数。 (这不是一个很棒的function,但你不能用C ++做到这一点)

在文件A中:

 float sum(float a, float b) { return a+b; } 

在文件B中

 main() { printf("%f\n", sum(1,2)); } 

与C,这编译,但打印0.000

使用C ++,你需要一个float sum(float,float); 在printf之前,它给出了预期的结果。

您可以在C中稀疏地初始化数组。我喜欢使用它来映射int-> sometype用于相对密集的静态映射,其中未映射的值可以解释为0:

 int my_array[] = { [1] = 3, [4] = 2 }; printf("%d %d %d\n", sizeof my_array, my_array[0], my_array[1]); /* prints 20, 0, 3 */ 

实际上,我可以想到一个例子:

当您创建要由其他应用程序共享的库(.lib文件或.dll文件)时,最好使用C而不是C ++,因为结果更具可移植性。 您可以使用’extern“C”’块在C ++编译器中执行此操作。

具体来说,C ++有一个怪癖,其中没有名称修改的标准约定 – 用于将库的函数签名转换为编译器使用的更低级别的名称。 因此,例如,如果您具有类似’int addNumbers(int a,int b)’的函数,则不同的C ++编译器可能会将此函数转换为不同的名称,这可能会在您要导入库时导致问题。 如果您使用C编译器或围绕您的库使用C块导入和导出代码,虽然您不会看到此问题,因为只有一种方法可以在C中修改函数名称。

您可以使用任何编程语言执行几乎所有操作。 当然,表达它的方式会有所不同,代码量,代码清晰度,易于进一步维护。 有些任务可以用Prolog中的几行编写,用C ++编写几页代码,依此类推。

一些限制因素是可用的库,可用的编译器和低级问题。 但是,当您在典型的PC上考虑C和C ++时,在其中任何一个中都可以做到的事情没有区别。

除非你当然要求C和C ++之间的差异 – 因为这些人已经给了你这个想法。

 char *c = malloc(sizeof(char)); 

在C中有效,而不是C ++,即自动转换void* 。 这当然是一个语法问题,而不是你能做什么,不能_do_(即完成)。

如果标准是解决特定的编程问题,那么两者都可以完成这项工作,尽管在某些情况下由于更高的抽象级别在C ++中执行它可能会更容易一些

1998 C ++标准列出了与1990 C标准不相容的列表,长度为13页(附件C)。 当然,与描述这些语言的页面数量相比,它并不是很多,但仍然可以解决一些问题。

它列出的差异类型的快速摘要:

  • 添加了新关键字(任何使用它们作为标识符的C程序都不是C ++)
  • 字符文字的类型从int更改为char(在C和C ++中比较sizeof('a') !)
  • 字符串文字是const(不能做char* q = expr ? "abc" : "de";
  • 从该语言中删除“暂定定义”。
  • “兼容类型”将从语言中删除。
  • 现在需要转换从void *转换为任何其他指针。
  • 从任何const / volatile指针转换为void *现在需要强制转换。
  • 从语言中删除“隐式声明”。
  • 表达式不能再创建新类型(如p = (void*)(struct x {int i;} *)0;
  • 一些表达式的结果变成了左值(比较char arr[100]; sizeof(0, arr) char arr[100];

……这是附件C的前3页。

如果你遵循1999 C标准,差异将需要永远描述。 虽然C ++ 0x确实包含了一些C99function,但其中许多function本质上是不兼容的,比如复杂类型。

简短的回答是……不,不是真的。 请参阅http://www.research.att.com/~bs/bs_faq.html#difference

这是指最新的C标准吗? 最初的C标准(ANSI 1989或ISO 1990,1995更新)非常接近于C ++的子集。 存在差异,但它们大部分是人为的(最大的例外可能是void *可以自由地转换为C中的任何数据指针而不是C ++中的数据指针)。

然而,1999年出现了一个新的C标准 ,在我停止在最现代的C中做任何事情之后的一段时间。它有新的function,其中一些在今年或明年将进入C ++标准,但不是全部。

在C中,您可以声明以下变量:

 int bool, class, new, delete, template, typename, this, throw, catch, typeid, operator, virtual, static_cast, reinterpret_cast, dynamic_cast, mutable, public, private, protected, friend; //many more 

然后你可以这样做:

 int namespace = private + protected + public; int decltype = static_cast + dynamic_cast + reinterpret_cast; int constexpr = (new + delete) * (template + typename); 

所有这些都是C ++ 11中的关键字。

C ++不支持命名结构成员初始化,在C中你可以这样做:

struct {int x,y; } a = {。x = 3};

您还可以将其与Matt Havener显示的function结合使用:

struct {int a [3],b; } w [] = {[0] .a = {1}, 1 .a [0] = 2};

“如果不能在集会中完成,那就不值得做!”

好吧,幽默一边,我认为 OP在语法上要求,而不是在操作上。

我认为C中有一些不合法的东西是合法的(至少是C89),这些东西在C ++中是不合法的,或者至少是被弃用的……但是(如果它们存在的话)它们是相当模糊的。 C ++在function上是C的超集。

C ++显然不是C的超集,原因很简单:C ++中添加了新的关键字
class,virtual,new等因此不能再用作C ++中的标识符。

有些原因比较微妙。
您可以在Bjarn Stroustrup的网站上找到关于这个问题的详尽答案: C ++编程语言| 附录B.