【问题标题】:Is it true that there is no need to learn C because C++ contains everything? [closed]真的不需要学习C,因为C++包罗万象吗? [关闭]
【发布时间】:2010-09-13 18:59:57
【问题描述】:

我正在上 C++ 编程课程,教授告诉我们没有必要学习 C,因为 C++ 包含 C 中的所有内容以及面向对象的特性。然而,其他一些人告诉我,这不一定是真的。任何人都可以对此有所了解吗?

【问题讨论】:

  • 在你的教授的辩护中,在教学时过于具体会让大多数人难以理解,并且会失去对重要内容的关注。所以他可能知道它不是一个严格的超集。

标签: c++ c


【解决方案1】:

概述:

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++ 中是不好的做法。预处理器滥用、不必要地使用原始指针、结构语义只是我想到的几个例子。
  • ...而你越“老”,就越难改掉这些习惯。
  • 我相信类型转换问题(void *)可以通过大多数平台上的编译器选项来解决。
  • 知道如何处理诸如滥用预处理器之类的事情并不意味着您会使用它。基本上你会使用你知道的最好的方法,知道一些额外的东西不会伤害你。它只会让您稍后在其他人的代码中检测到它,并能够自己重构它。
  • 让您更接近它的“最佳答案”。
【解决方案2】:

虽然 C++ 确实旨在保持与 C 的高度兼容性,并且您在 C++ 中学习的部分内容将适用于 C,但思维方式完全不同。使用 Boost 或 STL 编程 C++ 与使用 C 编程的体验截然不同。

有一个术语叫做将 C++ 用作更好的 C。这意味着使用一些 C++ 语言特性和工具来简化 C 编程(例如,在 for 语句中声明 for 循环的索引变量)。但现在,现代 C++ 开发似乎与 C 有很大不同,除了大量语法外,在这些情况下,C 遗留问题似乎是一种负担,而不是一种好处。

【讨论】:

    【解决方案3】:

    如果您知道 C++ 的语法,您可能不需要学习 C 的语法,但您确实需要了解 C 中的编码实践与 C++ 中的编码实践有何不同。

    所以你的教授不是 100% 正确的。
    在 C 中,您没有将代码排列成逻辑模块的类,也没有 C++ 多态性。然而,您仍然需要以某种方式实现这些目标。
    尽管 C 的语法在某种程度上是 C++ 的子集,但 C 中的编程 并不是 C++ 中的编程的子集。完全不同。

    【讨论】:

      【解决方案4】:

      是和不是。

      正如其他人已经回答的那样,C++ 语言是 C 语言的超集,但有一些小例外,例如 sizeof('x') 给出不同的值。

      但我认为没有很清楚地说明的是,当谈到这两种语言的使用时,C++ 不是超集,而是不同的。 C++ 包含新的(如果它们更好,可以讨论)做基本事情的方法,例如写入屏幕。旧的 C 方法仍然存在,但您通常使用新的方法。这意味着一个简单的“hello world”程序在 C 和 C++ 中看起来不同。所以说简单的东西在 C 和 C++ 中是不一样的,然后你只需在 C++ 中添加更高级的东西,比如对面向对象编程的支持。

      因此,如果您学习过 C++,则需要重新学习很多内容才能使用 C 进行编程。(嗯,可以将 C++ 作为 C 的扩展来教授,仍然使用 printf 和 malloc 而不是 iostreams和新的,然后添加类和其他 C++ 东西,但这种使用 C++ 的方式通常是不受欢迎的。)

      【讨论】:

        【解决方案5】:

        没有 C++ 并不是真正的 C 超集。如果您有兴趣,可以查看这篇文章以获得更广泛的差异列表: http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B

        【讨论】:

        • 随着我们接近 C1x 和 C++1x 标准,兼容性会越来越强。尽管委员会努力实现兼容性,但已经有一些功能不会同时出现在两种语言中(根据草案)。
        【解决方案6】:

        Not entirely true.

        最大的“陷阱”是类型——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++ 之间的差异,并能够同时使用这两种语言进行编程。但差异远不止肤浅。

        【讨论】:

          【解决方案7】:

          确实,对于大多数用途,C++ 包含 C 所做的一切。语言律师会很快指出,有一些非常特殊的边缘情况是有效的 C 但不是有效的 C++。

          一个这样的例子可能是 C 声明

          int virtual;
          

          声明一个名为“virtual”的整数。由于“virtual”是 C++ 中的关键字,因此这不是有效的 C++。

          【讨论】:

            【解决方案8】:

            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

            【讨论】:

              【解决方案9】:

              Stroustrup本人advices against先学C。但话又说回来,他(以及他这一代的许多其他人)设法从 C 开始成为 C++ 大师。

              【讨论】:

              【解决方案10】:

              我个人不同意你的教授。

              一般来说,C++ 是基于 C 的,在这个“意义上”包含它并扩展它。

              但是,由于传统上人们学习了 C,然后才学习 C++ 的扩展,因此您教授的说法是不正确的,因为要正确使用 C++,您需要掌握 C 起源。有可能在教你一些东西时,你的教授或教科书不会特别提到什么来自哪种语言。

              此外,重要的是要了解,尽管有相似之处,但并非每个 C 程序在 C++ 下都以相同的方式运行。例如,C++ 编译器对 C 结构的解释不同(作为所有公共的类)。

              我教的时候,先教C核,再上C++。

              【讨论】:

              • “C 结构的解释不同”?据我所知,只要您不添加任何特定于 C++ 的东西(例如成员函数),C++ 中的“所有内容都是公共的类”的工作方式与 C 中的结构完全相同。因此,带有结构的 C 程序在编译为 C++ 时的工作方式完全相同。还是我错了?
              • 从纯粹的角度来看,当您在 C++ 中编译结构时,它会生成一个包含默认构造函数和复制构造函数的类。它曾经是我几年前参加的高级 OOP 课程中的一个问题,然后又教了几年。
              • "...要正确使用 C++,您需要掌握 C 起源..." 我会说这是明显错误的。我认为要正确使用 C++,您需要忘记所有 C 习惯。这很难,这也是我非常强烈反对这个POV的原因。
              【解决方案11】:

              如果班上的任何学生打算成为嵌入式软件工程师,那么他们可能别无选择,只能使用 C 编程(请参阅 this questionthis one 等)。

              当然,学习了 C++ 后,对他们来说,这可能与其说是从头开始,不如说是一种过渡——但它仍然使你教授的说法不真实!

              【讨论】:

              • 情况似乎发生了变化。 embedded.com/212101526
              • 是的 - 但在这种情况下,慢慢来。尽管如此,并非所有嵌入式处理器都具有 C++ 编译器,那些通常会为 C++ 选项收费更高的编译器,并且大多数现有代码仍然是用 C 编写的。所以我坚持我的答案!
              猜你喜欢
              • 1970-01-01
              • 2020-12-12
              • 1970-01-01
              • 1970-01-01
              • 2010-09-15
              • 1970-01-01
              • 2010-09-14
              • 1970-01-01
              • 2021-02-17
              相关资源
              最近更新 更多