【发布时间】:2010-09-13 18:59:57
【问题描述】:
我正在上 C++ 编程课程,教授告诉我们没有必要学习 C,因为 C++ 包含 C 中的所有内容以及面向对象的特性。然而,其他一些人告诉我,这不一定是真的。任何人都可以对此有所了解吗?
【问题讨论】:
-
在你的教授的辩护中,在教学时过于具体会让大多数人难以理解,并且会失去对重要内容的关注。所以他可能知道它不是一个严格的超集。
我正在上 C++ 编程课程,教授告诉我们没有必要学习 C,因为 C++ 包含 C 中的所有内容以及面向对象的特性。然而,其他一些人告诉我,这不一定是真的。任何人都可以对此有所了解吗?
【问题讨论】:
概述:
C++ 几乎是 C 的超集,你的教授是正确的,因为不需要单独学习 C。
C++ 增加了整个面向对象方面、通用编程方面以及不那么严格的规则(比如需要在每个函数的顶部声明的变量)。 C++ 确实改变了 C 中某些术语的定义,例如结构,尽管仍然是以超集的方式。
为什么它不是严格超集的示例:
This Wikipedia article 有几个很好的例子来说明这种差异:
一个常见的区别是 C 允许从 void* 指向其他指针类型,但 C++ 才不是。因此,以下是有效的 C 代码:
int *i = malloc(sizeof(int) * 5);... 但要使其在 C 和 C++ 需要使用显式的 演员:
int *i = (int *) malloc(sizeof(int) * 5)另一个常见的可移植性问题是 C++ 定义了许多新的关键字, 比如 new 和 class,可能是 用作标识符(例如变量 名称)在 C 程序中。
This wikipedia article 也有进一步的不同:
C++ 编译器禁止 goto 跨越初始化,如以下 C99 代码:
void fn(void)
{
goto flack;
int i = 1;
flack:
;
}
你应该首先学习什么?
你应该先学习 C++,不是因为先学习 C 会伤害你,也不是因为你必须忘掉任何东西(你不会),而是因为先学习 C 没有任何好处。无论如何,您最终将了解有关 C 的所有内容,因为它或多或少包含在 C++ 中。
【讨论】:
虽然 C++ 确实旨在保持与 C 的高度兼容性,并且您在 C++ 中学习的部分内容将适用于 C,但思维方式完全不同。使用 Boost 或 STL 编程 C++ 与使用 C 编程的体验截然不同。
有一个术语叫做将 C++ 用作更好的 C。这意味着使用一些 C++ 语言特性和工具来简化 C 编程(例如,在 for 语句中声明 for 循环的索引变量)。但现在,现代 C++ 开发似乎与 C 有很大不同,除了大量语法外,在这些情况下,C 遗留问题似乎是一种负担,而不是一种好处。
【讨论】:
如果您知道 C++ 的语法,您可能不需要学习 C 的语法,但您确实需要了解 C 中的编码实践与 C++ 中的编码实践有何不同。
所以你的教授不是 100% 正确的。
在 C 中,您没有将代码排列成逻辑模块的类,也没有 C++ 多态性。然而,您仍然需要以某种方式实现这些目标。
尽管 C 的语法在某种程度上是 C++ 的子集,但 C 中的编程 并不是 C++ 中的编程的子集。完全不同。
【讨论】:
是和不是。
正如其他人已经回答的那样,C++ 语言是 C 语言的超集,但有一些小例外,例如 sizeof('x') 给出不同的值。
但我认为没有很清楚地说明的是,当谈到这两种语言的使用时,C++ 不是超集,而是不同的。 C++ 包含新的(如果它们更好,可以讨论)做基本事情的方法,例如写入屏幕。旧的 C 方法仍然存在,但您通常使用新的方法。这意味着一个简单的“hello world”程序在 C 和 C++ 中看起来不同。所以说简单的东西在 C 和 C++ 中是不一样的,然后你只需在 C++ 中添加更高级的东西,比如对面向对象编程的支持。
因此,如果您学习过 C++,则需要重新学习很多内容才能使用 C 进行编程。(嗯,可以将 C++ 作为 C 的扩展来教授,仍然使用 printf 和 malloc 而不是 iostreams和新的,然后添加类和其他 C++ 东西,但这种使用 C++ 的方式通常是不受欢迎的。)
【讨论】:
没有 C++ 并不是真正的 C 超集。如果您有兴趣,可以查看这篇文章以获得更广泛的差异列表: http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B
【讨论】:
最大的“陷阱”是类型——C++ 的类型比 C 强得多,而在 C++ 中解决这个问题的首选方法在 C 中根本不可用。也就是说,您可以在 C 中的类型之间静默转换(尤其是指针类型),但在 C++ 中没有。 C++强烈推荐使用 static_cast/reinterpret_cast/const_cast 方法来解决这些问题。
更重要的是,如果你学习 C++ 语法和习惯,你可能会发现很难处理 C(有人可能会说这很好;我自己更喜欢 C++,但有时它只是不是一个选择,或者您必须处理 C 而不是 C++ 中的遗留代码)。同样,您最可能遇到的问题是处理指针(特别是 char* 和一般数组用法;在 C++ 中使用 std::string 和 std::vector 或其他集合只是 更好 )。
当然可以学习 C++,然后了解 C 和 C++ 之间的差异,并能够同时使用这两种语言进行编程。但差异远不止肤浅。
【讨论】:
确实,对于大多数用途,C++ 包含 C 所做的一切。语言律师会很快指出,有一些非常特殊的边缘情况是有效的 C 但不是有效的 C++。
一个这样的例子可能是 C 声明
int virtual;
声明一个名为“virtual”的整数。由于“virtual”是 C++ 中的关键字,因此这不是有效的 C++。
【讨论】:
C(尤其是 C89)和 C++ 有很大的共同核心,但 C 和 C++ 之间肯定存在差异。显然,C++ 具有所有面向对象的特性,加上泛型编程,加上异常,加上 C 没有的命名空间。但是,C 也有 C++ 中没有的特性,例如支持(接近于过时的)非原型符号来声明和定义函数。尤其是以下函数声明的含义在 C 和 C++ 中是不同的:
extern void function();
在 C++ 中,这是一个不返回任何值且不接受参数的函数(因此,无论它们是什么,都只因其副作用而被调用)。在 C 中,这是一个不返回值但没有关于参数列表的信息的函数。在调用函数之前,C 仍然不需要在范围内声明(通常;如果函数采用参数的变量列表,则必须在范围内声明,因此在使用 printf() 之前对 #include <stdio.h> 等至关重要)。
也有区别:
sizeof('c')
在 C++ 中,答案是 1;在 C 中,答案通常是 4(具有 8 位字符的 32 位系统)甚至 8(具有 64 位 int 的 64 位系统)。
一般来说,您可以编写在 C 和 C++ 编译器下编译的代码,而不会有太大的困难——我的大部分代码一直都是这样做的。这些异常要么是我的粗心大意造成的,要么是因为我有意识地利用了 C99 中 C++ 98 中没有的优秀特性,例如指定的初始化程序或long long。
【讨论】:
Stroustrup本人advices against先学C。但话又说回来,他(以及他这一代的许多其他人)设法从 C 开始成为 C++ 大师。
【讨论】:
我个人不同意你的教授。
一般来说,C++ 是基于 C 的,在这个“意义上”包含它并扩展它。
但是,由于传统上人们学习了 C,然后才学习 C++ 的扩展,因此您教授的说法是不正确的,因为要正确使用 C++,您需要掌握 C 起源。有可能在教你一些东西时,你的教授或教科书不会特别提到什么来自哪种语言。
此外,重要的是要了解,尽管有相似之处,但并非每个 C 程序在 C++ 下都以相同的方式运行。例如,C++ 编译器对 C 结构的解释不同(作为所有公共的类)。
我教的时候,先教C核,再上C++。
【讨论】:
如果班上的任何学生打算成为嵌入式软件工程师,那么他们可能别无选择,只能使用 C 编程(请参阅 this question 和 this one 等)。
当然,学习了 C++ 后,对他们来说,这可能与其说是从头开始,不如说是一种过渡——但它仍然使你教授的说法不真实!
【讨论】: