【问题标题】:What's the difference between C and C++ [closed]C和C++有什么区别[关闭]
【发布时间】:2009-03-12 21:56:08
【问题描述】:

我知道 C++ 有对象的概念,但 C 没有。我也知道几乎所有关于 C 的知识都适合 K & R,但 C++ 库要复杂得多。不过肯定还有其他很大的不同。

C 和 C++ 的主要区别是什么?

【问题讨论】:

  • “++”部分...:P
  • 你不认为这些是主要区别吗?
  • @Trent:我愿意,但 C++ 仅仅是带有对象和更大书籍的 C 吗?如果是这样,那就回答了我的问题,但我一直觉得它的作用远不止于此。也许我错了。
  • “仅仅”将是对 OOP 与程序性的轻描淡写。就像说“功能”是“只是没有状态的编程”。好吧,也许没那么大。
  • 这个问题与 - 特定的编程问题,或 - 软件算法,或 - 程序员常用的软件工具无关;并且是 - 一个软件开发独有的实用、可回答的问题 (stackoverflow.com/help/on-topic)

标签: c++ c


【解决方案1】:

C++ 语言说它们是一样的:

int C = 0;
assert(C++ == C);

【讨论】:

  • K&R 的使徒知道这句话的先见之明。
  • 大声笑虽然这不是真的。你的平等测试的结果是未定义的...... :) 我想知道这两种语言是什么意思。 :p
  • gcc 和 vc++ 都说是真的
  • @jalf:不只是结果; 行为未定义。
  • 我更喜欢这个版本:int C = 0; assert(C++ >= C);
【解决方案2】:

查看 Stroustrup 的常见问题解答here,具体来说:

C 和 C++ 有什么区别?

C++ 是 C 的直接后代 保留几乎所有 C 作为子集。 C++ 提供更强大的类型检查 比 C 和直接支持更广泛 比 C 更丰富的编程风格。 从某种意义上说,C++ 是“更好的 C” 它支持编程风格 使用具有更好类型检查的 C 完成 和更多的符号支持(没有 效率损失)。在相同的 从某种意义上说,ANSI C 是比 K&R 更好的 C C.另外,C++支持数据 抽象,面向对象 编程和泛型编程 (参见 C++ 编程语言(第 3 版)”;附录 B 讨论 兼容性问题可用于 下载)。

【讨论】:

【解决方案3】:

我想你回答了你自己的问题:类

这是一种完全不同的设计范式。我认为混乱的出现是因为许多人开发的 C++ 程序基本上是 C 程序,甚至没有意识到这一点。

用它的创造者 Stroustrup 的话来说,这允许:

编辑:添加了一些其他有趣的东西

【讨论】:

  • 投赞成票是因为“......很多人开发的 C++ 程序基本上都是 C 程序,甚至没有意识到这一点。”
【解决方案4】:

简而言之,C 渴望成为一种“可移植的汇编语言”。它使事情变得简单,让您可以做几乎直接映射到底层硬件的事情,并且不会呈现很多高级抽象(您有函数并且......仅此而已)

C++ 试图成为一切。高级语言、低级语言、面向对象语言、多范式语言、系统编程语言、嵌入式编程语言和应用程序开发语言。

这两种语言实际上并没有太多共同点,除了一些共同的语法。一个 C 程序可以编译为 C++,只需进行微小的更改,但它与为该语言编写的“正确”C++ 代码没有任何共同之处。

【讨论】:

    【解决方案5】:

    这是一个展示 c 和 c++ 之间“不兼容”的网站:

    http://david.tribble.com/text/cdiffs.htm#C++-vs-C

    实际上,c 和 c++ 在很多方面存在分歧(除了类、模板、异常等)。

    就主要差异而言,这里有一个很好的列表:

    • 匿名工会
    • 构造函数和析构函数
    • 异常和 try/catch 块
    • 外部函数链接(例如,extern "C")
    • 函数重载
    • 成员函数
    • 命名空间
    • 新建和删除运算符和函数
    • 运算符重载
    • 引用类型
    • 标准模板库 (STL)
    • 模板类
    • 模板函数

    【讨论】:

      【解决方案6】:

      C++主要是C的扩展。最初C++被称为“C with classes”,突出了主要的原始语言扩展。那时已经支持重载函数。从那时起,C++ 获得了异常、分层命名空间模板形式的通用编程,最后是多线程 支持。从 C++11 开始,还有一些对 garbage collection 的最小核心语言支持,例如使用Boehm garbage collector。较小的扩展包括引用类型、尾随函数返回类型语法、可被覆盖的内存分配和释放机制、运行时类型信息等等。

      C 和 C++ 之间的差异,即 C 和 C++ 的“C 子集”之间的差异,总结在 C++11 标准的附录 C 中,标题为“兼容性”,大约 20塞满的页面,其中涉及 C 兼容性的 C1 部分大约有 10 页。

      它也是 C++98 和 C++03 中的附录 C,它也是新的 C++14 标准中的附录 C。


      该标准的 C++11 附录 C 列出了 C 和 C++ 之间的以下不兼容性:

      §C1.1 词汇约定

      新关键字(第 2.12 节)

      该段落仅引用 C++11 §2.12。以下列表是从该表和 C99 中的相应表生成的。

      C99 C++11 _布尔 _复杂的 _假想 对齐 对齐 汇编 自动 自动 布尔 休息休息 案例案例 抓住 字符字符 char16_t char32_t 班级 常量常量 const_cast 常量表达式 继续 继续 声明类型 默认 默认 删除 渡渡鸟 双双 dynamic_cast 其他的 枚举枚举 明确的 出口 外部外部 错误的 浮动 浮动 为 为 朋友 转到转到 如果如果 内联内联 整数 长长的 可变的 命名空间 新的 无例外 空指针 操作员 私人的 受保护 上市 注册 注册 reinterpret_cast 严格 返回 返回 短短 签字 签字 大小的大小 静态的 静态断言 static_cast 结构体 开关开关 模板 这 线程本地 扔 真的 尝试 类型定义 类型标识 类型名称 工会联盟 未签名 未签名 使用 虚拟的 无效 无效 挥发性的 wchar_t 一会儿一会儿

      字符文字的类型从 int 更改为 char (§2.14.3)

      字符串文字 const (§2.14.5)

      §C1.2 基本概念

      C++ 没有“暂定定义”(第 3.1 节)。

      struct 是 C++ 中的范围,而不是 C(第 3.3 节)中的范围。

      显式声明为 const 且未显式声明 extern 的文件范围的名称具有内部链接,而在 C 中它将具有外部链接 ($3.5)。

      main 不能递归调用,也不能获取其地址(第 3.6 节)。

      C 允许在多个地方使用“兼容类型”,而 C++ 不允许(第 3.9 节)。

      §C1.3 标准转换。

      void* 转换为指向对象的类型需要强制转换(第 4.10 节)。

      只有指向非const 和非易失性对象的指针可以隐式转换为void*(第4.10 节)。

      §C1.4 表达式。

      不允许隐式声明函数(第 5.2.2 节)。

      类型必须在声明中声明,而不是在表达式中(第 5.3.3 节、第 5.4 节)。

      条件表达式、赋值表达式或逗号表达式的结果可能是左值(§5.16、§5.17、§5.18)。

      §C1.5 语句。

      现在跳过带有显式或隐式初始化程序的声明是无效的(除非跨整个未输入的块)(§6.4.2,§6.6.4)

      现在从声明为返回值但实际上没有返回值的函数(显式或隐式)返回是无效的(第 6.6.3 节)。

      §C1.6 声明。

      在 C++ 中,staticextern 说明符只能应用于对象或函数的名称。在 C++ 中将这些说明符与类型声明一起使用是非法的(第 7.1.1 节)。

      C++ typedef 名称必须不同于在同一范围内声明的任何类类型名称 (除非typedef 是具有相同名称的类名的同义词)(第 7.1.3 节)。

      const 对象必须在 C++ 中初始化,但可以在 C 中保持未初始化(第 7.1.6 节)。

      C++ 中没有隐式 int(第 7.1.6 节)。

      关键字 auto 不能用作存储类说明符(第 7.1.6.4 节)。

      枚举类型的 C++ 对象只能分配相同枚举类型的值(第 7.2 节)。

      在 C++ 中,枚举器的类型是它的枚举(第 7.2 节)。

      §C1.7 声明符。

      在 C++ 中,使用空参数列表声明的函数不接受任何参数 ($8.3.5)。

      在 C++ 中,不能在返回类型或参数类型中定义类型(第 8.3.5 节、第 5.3.3 节)。

      在 C++ 中,函数定义的语法不包括“旧式”C 函数(第 8.4 节)。

      在 C++ 中,使用字符串初始化字符数组时,字符串中的字符数(包括终止符 '\0')不得超过数组中的元素数(第 8.5.2 节)。

      §C1.8 类。

      在 C++ 中,类声明将类名引入到声明它的作用域中,并将该名称的任何对象、函数或其他声明隐藏在封闭作用域中(第 9.1 节、第 7.1.3 节)。

      在 C++ 中,嵌套类的名称是其封闭类的本地名称(第 9.7 节)。

      在 C++ 中,typedef 名称在类定义中使用后可能不会在该定义中重新声明(第 9.9 节)。

      §C1.9 特殊成员函数。

      隐式声明的复制构造函数和隐式声明的复制赋值运算符不能复制 volatile 左值(第 12.8 节)。

      §C1.10 预处理指令。

      __STDC__ 是否已定义,如果已定义,其值是什么,由实现定义(第 16.8 节)。


      为了简化比较关键字表的重新生成,并建立对给定表的信心,以下是用于生成它的 C++ 程序:

      #include <algorithm>
      #include <iostream>
      #include <iomanip>
      #include <fstream>
      #include <vector>
      #include <string>
      using namespace std;
      
      #define ITEMS_OF( c )   c.begin(), c.end()
      
      enum class Language { c, cpp };
      
      auto compare( Language const a, Language const b )
          -> int
      { return int( a ) - int( b ); }
      
      struct Keyword
      {
          string      word;
          Language    language;
          
          friend
          auto operator<( Keyword const& a, Keyword const& b )
              -> bool
          {
              if( int const r = a.word.compare( b.word ) ) { return (r < 0); }
              return (compare( a.language, b.language ) < 0);
          }
      };
      
      void add_words_from(
          string const& filename, Language const language, vector< Keyword >& words
          )
      {
          ifstream            f( filename );
          string              word;
          
          while( getline( f, word ) )
          {
              words.push_back( Keyword{word, language} );
          }
      }
      
      auto main() -> int
      {
          vector< Keyword >   words;
          add_words_from( "kwc.txt", Language::c, words );
          add_words_from( "kwcpp.txt", Language::cpp, words );
          sort( ITEMS_OF( words ) );
          
          int const w = 20;
      
          int previous_column = -1;
          string previous_word = "";
          cout << left;
          for( Keyword const& kw : words )
          {
              int const column = (int) kw.language;
              int const column_advance = column - (previous_column + 1);
              if( column_advance < 0 || previous_word != kw.word )
              {
                  cout << endl;
                  if( column > 0 ) { cout << setw( w*column ) << ""; }
              }
              else
              {
                  cout << setw( w*column_advance ) << "";
              }
              cout << setw( w ) << kw.word;
              previous_column = column; previous_word = kw.word;
          }
          cout << endl;
      }
      

      【讨论】:

        【解决方案7】:

        模板是另一个很大的区别(除了类/对象)。模板支持例如类型安全的通用容器类型(它们的第一个用例)和(混蛋)lambda 表达式 (boost::lambda)。

        C++ 是一种比 C 更大的语言(不仅仅是库)。

        【讨论】:

          【解决方案8】:

          这个问题没有简短的答案。
          一般 C++ 支持:
          - OOP 范式;
          - 通用编程;
          - 模板元编程;
          - 抽象数据类型;
          - 新的库和标准支持功能范式的元素;
          - 使您的程序最受支持的其他工具;
          - 您也可以编写类似 C 风格的程序,但使用 C++ 编译器;


          但是纯 C - 比 C++ 快一点,而且级别更低。

          【讨论】:

          • C 更快?是什么让你有这样的想法?你是说如果我将一个 C 程序输入到 C++ 编译器,它会神奇地变慢吗?或者也许 C++ 的 std::sort 比 C 的 qsort 慢(提示:不是)。 C++ 有很多工具可以将性能提高到远高于 C 的水平。
          • 当然,它还启用了在使用时会引入一些开销的功能。但是您不必使用它们,而且通常使用它们并不比自己在 C 中实现相同的速度慢。比较两种语言的“速度”是没有意义的。
          • 是的,我同意“比较两种语言的“速度”是没有意义的”,但总的来说,我很难过“快一点”,因为在纯 C 中你不能使用缓慢的特性和您将只使用 POD 类型。
          • C 确实支持通用编程 - 查看 qsort,它允许任意比较函数。这样做只会牺牲类型安全。
          • C 也支持 OO 编程。来自 POSIX 的示例... 一个套接字是一个文件描述符。管道是一个文件描述符。 read() 和 write() 是对所有文件描述符进行操作的函数。这一点都和 C++ 一样面向对象。
          【解决方案9】:

          C++ 相对于 C 的另一个特性是以 throw ... catch 的形式处理异常。

          【讨论】:

            【解决方案10】:

            C++ 比带有类的 C 多得多。 C++ 内部还有许多其他概念,例如模板、函数和运算符重载、异常以及这里已经提到的许多其他概念。这使得 C++ 非常强大和灵活,但也很难学习。不是单一的概念难以理解,而是它们的总和以及它们如何一起发挥作用。看一下 boost,看看 C++ 可以做什么。而且我想需要很长时间才能理解引擎盖下发生的事情,这在 C 的情况下非常清楚。

            或者简而言之:C++ 比 C 的类更多,或者换句话说,C++ 比 Java 加上内存管理更多。

            【讨论】:

              【解决方案11】:

              C++ for C programmers 的两部分中的第一部分中,列出了一些非 OOP 差异:

              • 函数的默认参数
              • 函数重载
              • 您可以在代码中任何需要的地方声明局部变量,而不仅仅是在函数的开头(也是 C99 功能)
              • 引用,如int&amp; x
              • 一般的常量正确性
              • 命名空间
              • 内置布尔类型 bool,带有 truefalse 关键字(在 C99 中也可以通过 stdbool.h)
              • inline 关键字和相关的怪癖,包括隐式内联和自动内联
              • 比 C 大得多的标准库
              猜你喜欢
              • 2016-12-05
              • 2023-03-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-03-24
              • 2013-03-14
              • 1970-01-01
              相关资源
              最近更新 更多