有什么我可以在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.