in

C++ 解释:你需要了解的一切

关键点

  • c++是一种通用的、编译的、区分大小写的编程语言。
  • 要编写c++程序,你需要熟悉它的语法。有兴趣学习c++编程的人可以参考stephen prata的《c++ primer plus》等参考资料。
  • c++最初是在1985年由贝尔实验室的bjarne stroustrup提出的。

c++是什么?

c++是世界上最著名和最普遍的计算机编程语言之一,它在整个计算机科学的历史上投下了浓重的阴影。即使在它最初出现的近四十年后的现在,它仍然非常受欢迎。它在各种领域中仍然占据重要地位,并被用于各种各样的用途。

这种卓越的持久性的原因是什么?用一个词来说:强大。事实的简单和原始的事实是,当一个足够熟练的编码人员使用c++时,它是一种令人惊讶的强大工具。它是一种旨在处理尽可能广泛任务的编程语言。因此,它充满了各种各样的奇特功能,其中有些可能很奇异甚至有点荒谬,但所有这些功能都是为了服务一个目的。

虽然有些人因为这个事实而谴责它复杂和令人费解,但其他人则发誓它的便利性。

c++是一种将不同的编程范例(过程式、面向对象和泛型)的强大功能融合在一起的编程语言,以实现最大效果。它是一种利用编译器使自己更接近机器灵魂并提高性能的语言。它是一种学习起来并不轻松但可以丰富回报那些足够用心掌握它的人的语言。

下面,我们将深入了解c++的细节。虽然这里提供的信息不能让您编写该语言的代码,但它将全面了解您应该了解的所有重要事实。

c++:准确定义

c++是一种通用的、编译的、区分大小写的编程语言,它被创建为c语言的扩展。与c语言一样,c++可以作为一种过程性编程语言,但它通过提供面向对象和泛型编程范式的功能以及执行一些低级内存操作的能力,超越了c语言。

c++是如何工作的?

c++最初是在1985年由贝尔实验室的另一位计算机科学家bjarne stroustrup提出的。

©maria vonotna/shutterstock.com

要真正解释c++为什么如此强大和多功能,它如何完成所有各种各样的工作,我们必须解释并定义上述定义中提到的一些关键的编程术语。通过建立和阐明这些重要概念,我们将能够结合它们创建一个广泛但有启发性的语言功能的图景。

编程范式的结合:过程性、面向对象和泛型

“通用目的”这个术语简单地意味着可以编写 c++ 代码使计算机几乎可以做任何事情。没有任何重要的编程功能超出了这种语言的范围。事实上,它甚至提供了许多奇特和独特的功能,这些功能通常不常使用,但编程人员仍然可以使用。这是因为该语言的创造是根据实用的和折中的哲学指导的:只要某个东西可以用来解决实际问题,语言的创造者 bjarne stroustrup 就会努力包含它。

c++ 如何能拥有如此广泛的能力?为了回答这个问题,我们必须深入研究各种编程范式的主题。

计算机编程可以被分解成一系列或多或少离散的范式,这些范式决定了每个特定范式下编写的代码的结构。所使用的特定范式或范式也会对在其指导下构建的程序在解决特定类别问题方面的适用性产生影响。

我们不需要在这里讨论每个范式及其复杂性。只需要关注三个范式,因为它们是 c++ 组合的三个范式:过程化编程、面向对象编程和泛型编程。

过程化编程是可能最接近非专业人士对计算机程序的直观想法的风格。广义上讲,每个计算机程序都有两个组成部分:数据是程序操纵和处理的对象,算法是程序运行的指令集。过程化编程偏重于这种分离的算法方面,也就是说,过程化程序的构建是根据程序必须执行一定的指令集这一思想进行的,然后这些指令通常按间接的顺序编写到程序中。通常,过程化程序由一系列要执行的操作(称为函数)和一组传递给这些函数的数据类型(称为参数)组成。

相比之下,面向对象编程则颠倒了这种取向。与过程化编程不同,面向对象编程更加注重数据。每个应用面向对象编程原则的程序员都希望构建与他试图解决的问题的基本特征相对应的数据形式。他的程序因此将根据该问题或与之类似的问题量身定制,因此可以简单自然地解决它。

与面向对象编程相关的有一些术语,我们在这里简要定义一下。类是一组用于创建特定类型数据的指令。对象是根据某个类中指定的指令构建的特定数据结构。方法是在某个类的特定上下文中执行的操作,也就是说,它是函数的面向对象等效形式,但局限于给定类。

还有四个其他特殊术语对于理解面向对象编程至关重要:

  • 封装
  • 抽象
  • 继承
  • 多态

封装

封装指的是在面向对象编程程序中,每个类都是一个独立的整体。每个类中的代码与其他类中的代码完全隔离。

抽象

抽象是指在代码中只显示特定重要的细节,同时隐藏其他所有内容,并让其在后台运行。某些代码片段可能执行高级功能,而与机器内部更接近的其他代码可能执行其他任务。同时考虑这两个层级会产生巨大且不必要的复杂性,而将这些层级分离不仅简化了程序,还使其更易于移植,并且受到更少的影响。

继承

继承是指类应该按层次结构组织,并且更具体的低层级类可以继承更通用的高层级类的属性。高层级类称为父类,而低层级类称为子类。当类可以从其他类继承特性时,程序员需要编写的代码量大大减少。

多态

多态指的是子类在必要时可以覆盖父类的特性。因此,特定的数据或其他特性可以根据需要继承或不继承。

显然,按照这些原则工作使得编写可以执行复杂任务的程序变得更加容易。它还简化了编码并有助于提高程序效率。这些是c++特别擅长的方面。

最后,我们必须讨论泛型编程范式。与面向对象编程一样,该范式广泛使用抽象。与过程式编程类似,它更注重每个程序的算法部分。所有程序都使用不同的数据类型-字符串、整数、浮点数、列表、数组等。这些类型通常彼此不兼容,使得同一函数在不产生错误的情况下无法对其进行操作。但是,能够对不同数据类型执行相同操作通常很有用。泛型编程允许您在不为每种数据类型重写函数的情况下执行此操作。

在这个范式下创建的函数与数据类型无关。与面向对象编程不同,以这种风格编写的程序通常只适用于小型和专门的任务。

总之,c++为您提供了所有这些方法的功能和优势。当一种范式存在缺点时,可以使用其他范式来减轻负担,使您能够平衡利弊。

编译器

c++的另一个关键事实是它是一种编译语言。这意味着所有用它编写的代码都通过一个称为编译器的特殊程序运行,将其转换为其他类型的代码- 在这种情况下,转换为汇编语言。汇编语言是由cpu直接执行的代码。它是用零和一写的。因为它直接在cpu上运行,所以您的机器不需要对其进行任何进一步的转换。这意味着用c++编写的程序可以运行得非常快。因此,这是编码世界中所有性能狂热者钟爱的语言之一。

如何使用c++编写程序,它们是如何工作的?

c++是一种通用、编译的、区分大小写的编程语言。

©dc studio/shutterstock.com

与任何其他编程语言一样,在c++中编写程序需要熟悉其语法。有兴趣学习c++编程的人可以查阅参考书籍,如stephen prata的《c++ primer plus》,或专门教授该语言的大量视频教程,例如this onethis onethis one。然而,不需深入讨论,对c++程序如何运行及简单程序的逻辑和语法进行一般性讨论,可以帮助您掌握语言的工作原理。

任何在c++中工作的程序员的第一个任务是在某种文本编辑器中编写程序,并将其保存为具有适当扩展名的文件。完成后,编译器需要开始处理源代码,将其从高级、可移植、抽象的语言转换为程序必须运行的底层目标代码。如上所述,编译器会因程序所运行的计算机类型而异。然后,程序员必须将其目标代码链接到一些通用的启动代码以及使所有内容正常运行所需的其他函数。这些额外的函数将从适当的c++库中提取。

一旦这些部分正确链接在一起,结果将是包含可执行代码的文件。这是在您的计算机上运行的代码。

分析“hello, world。”

为了简单了解程序的外观,请考虑以下内容:

// c++ program to print “hello, world”

// 用于输入/输出函数的头文件
#include
using namespace std;

// main() 函数:程序的主要部分
int main()
{
// 打印 hello world
cout << “hello, world”;

return 0;
}
这是c++版本的“hello world”程序,这是一个始终向初学者教授的标准程序。让我们将其分解成几个部分,看看它是如何工作的。

在c++中,任何紧跟“//”后面的内容都是注释。编译器会忽略这些内容,只是为了使人类更容易理解代码中发生的情况。正如注释所描述的,这段代码指示计算机打印短语“hello, world.”。

这个程序的主体是函数main()。每个c++程序都有这样一个主函数,尽管其组织方式在不同的程序中变化很大。在这个简单的例子中,该函数没有参数,也就是说,它不从之前调用它的任何函数中获取任何值。这可以通过main()的圆括号中没有任何内容来表示。值得注意的是,因为main()通常是任何程序的焦点,其他函数在该程序中调用main()是非常不寻常的。相反,main()通常由在将程序通过编译器运行后附加到程序中的启动代码调用。

int是指main()返回给调用它的函数的数据类型-在这种情况下是整数。

位于花括号中的所有内容构成了主函数的主体。它包含了函数执行的语句。在c++中,每个语句必须以分号结束。cout指的是一个可以在计算机屏幕上显示各种内容的对象。在这种情况下,我们关心的是显示字符串“hello, world.”。“<<”表示这个字符串要传递给cout对象。return指的是主函数要返回的值,尽管在这种情况下,整数0只是一个空值的替代品。因此,return 0只是终止函数。

关于“#include”和“using namespace std;”这两行在c++程序逻辑中的作用的详细讨论超出了本文的范围。然而,简而言之,这些行使程序能够使用c++的标准输入/输出功能,从而使其能够与外界进行通信。它们通过预处理器将您的代码修改一定的方式后运行它。这行代码 #include 使用 #include 指令来定位iostream文件并将其附加到您的代码中。该文件包含了每个程序的输入/输出结构所必需的几个定义。而该行代码 using namespace std; 则使用 using 指令进入一个名为std的命名空间,这是c++的标准命名空间。命名空间是c++编译器的一个预包装单元,包括函数、类、对象和其他组成部分。如果您的程序必须使用具有相同名称的预定义组件,则将这些组件分割到适当的命名空间中可以防止编译器混淆它们。

上面的程序非常简单,我们对它的讨论也相当简略。然而,所说的内容应该足以让您了解一些c++的基本语法,一些关键语句及其含义,以及以这种语言编写的程序的各个部分如何组合在一起。

c++的起源和历史

要在c++中编写程序,您需要熟悉它的语法。任何有兴趣学习c++编程的人都可以参考stephen prata的c++ primer plus等参考书。

一点点前史

为了完全理解c++的历史,并欣赏它在计算机编程的演变和发展中所扮演的角色,我们必须回溯到语言本身诞生之前的很多年。这样做将为我们提供必要的事实,以便将其放置在适当的背景中,看到语言的创造者是如何应对挑战,语言是如何应对这些挑战的,以及为什么这门语言在登上世界舞台数十年后仍然如此强大和受欢迎。

正如上面已经提到的,计算机编程可以分解为一些基本范式,这些范式主要围绕着一个问题展开,即在计算机代码的组织中,是数据还是算法更为重要。直到上世纪60年代末,所有现有的编程语言都属于过程式范式。虽然simula作为首个面向对象编程语言具有不可否认的历史意义,而xerox的smalltalk在20世纪70年代进一步推动了这一范式,通过使用面向对象编程的原则创建了一个功能齐全的图形用户界面,但在20世纪80年代之前,大部分编程语言仍然是过程式的。

随着计算机硬件的进步和能够运行更长更复杂的程序的能力的获取,程序员自然而然地开始顺应他们的硬件,并编写这些更复杂的程序。然而,随着这个过程的加速,过程式方法的固有弱点开始以一些相当混乱和不幸的方式显现出来。所有的程序都需要指定将数据传递给其他一组指令以进行进一步处理的方式。在像basic和fortran这样的过程式语言中,可以使用分支语句来完成这一点。不幸的是,随着程序变得越来越大,它们所需的分支语句的数量以及分支语句与它们所运行的特殊异常和其他规则之间的交互变得极其复杂。不久之后,以这种方式编写的程序开始变成难以管理的庞然大物,对于人类来说,可靠地阅读、修改或调试它们变成了一项巨大的挑战。

在20世纪70年代初,贝尔实验室的计算机科学家dennis ritchie在扩展unix操作系统的功能的项目中遇到了由这些问题引发的障碍。他还面临着进一步的挑战。由于机器的操作系统与其硬件紧密相关,任何修改操作系统的尝试必须使用可以直接控制硬件的语言来完成。ritchie还希望使用一种简洁的语言,可以编写紧凑的程序,并以高速运行。当时对这些挑战的传统应对方法是用汇编语言编写代码。然而,这种解决方案对ritchie来说是不可接受的,因为汇编语言是一种非常低级的语言,也就是说,它是针对每个特定处理器的。这严重影响了可移植性,而可移植性正是ritchie所希望的,因为unix旨在在许多不同类型的计算机上运行。

作为对这一系列问题的回应,ritchie决定创建c语言,它是c++的直接前身。c是一种过程化语言,但它实现了一种称为结构化编程的东西,试图通过将这种行为减少到一小组定义良好的结构中来控制分支,例如for循环,while循环或if-else语句。这些已成为许多不同编程语言的标准部分。结构化编程还通过将程序分解为一系列相对独立的函数,以自上而下的方式来降低程序的复杂性。此外,由于c是一种编译语言,它能够成功地将低级速度、性能和硬件访问与高级可移植性结合起来。

尽管结构化编程确实有助于减轻某些程序的复杂性,但最终证明它只是一种临时的权宜之计。要真正解决这个问题,显然需要从过程范式转变。

进入c++

c++最早在1985年以贝尔实验室的另一位计算机科学家布雅尼·斯特劳斯特鲁普的构思面世。斯特劳斯特鲁普从20世纪80年代初开始就一直在致力于该语言的开发,他最初的目标是尽可能地非意识形态化,强调实用性和解决各种问题的能力,而不是预先确定的理论结构或纯粹性。

这在人们注意到有关该语言的某些基本事实时就很明显,比如它不是根据任何单一的编程范式构建的,而是涵盖了多种范式。由于c++是c的超集,任何在c中有效的程序(只有少数非常小的例外)在c++中也自动有效,当然反过来不成立。这立即将过程范式纳入后者语言中。c++最初的特色是它能够利用类、对象和其他oop概念,从而通过重新定位程序构建的方式来解决大型、笨重、难以阅读的程序问题。在这里,斯特劳斯特鲁普受到了simula,这个最初的面向对象编程语言的启发。

随着c++的普及,斯特劳斯特鲁普使其能够利用泛型编程范式的优势。此外,他和其他人逐渐为其配备了一系列广泛的库,为程序员提供了许多问题的经过验证的、预先建立的解决方案。因此,结果是一种高度通用和可移植、极高效、极具灵活性的语言。

与所有新的和发展中的编程语言一样,c++最初没有任何统一的标准,但随着它的成熟,它不可避免地凝固为固定形式。语言需要被标准化,因为任何不一致性——与将程序提交给不同的编译器引发的任何问题完全无关——都意味着程序不能在不同的计算机之间互操作。

1990年,美国国家标准协会(ansi)和国际标准化组织(iso)在联合委员会上首次尝试这样做。 1995年和1996年,他们再次多次会面,提交进一步的标准化建议供公众评论。 到那时,它们还包括了异常、模板(用于泛型编程)、运行时类型识别和标准模板库。

在1998年,国际电工委员会(iec)加入其中,这些组织制定了第一个c++标准。 这些标准在2003年、2011年、2014年、2017年和2020年进行了进一步的完善和更新。

c++在现实世界中的应用

上述关于c++的讨论相当抽象和概括。虽然这是不可避免的,如果希望为读者提供对语言特性和性质的概述,但这可能会让许多人想知道可以使用c++做什么具体的事情。如前所述,c++是根据实用主义哲学创建的,强调实际结果和能力高于一切,因此不应让人以为我们对类、函数、编译器、对象和其他概念的讨论没有实际应用性。

c++是一种编程语言,而编程基本上是为计算机提供执行任务的指令。鉴于我们的世界有多少是由计算机运行、驱动和实现的,单凭这一点就可以明显地看出c++对现实世界中的事物应用广泛。

你可以想象几乎每一件先进的技术或计算机设备都实际上使用了c++,或者至少能够使用。

一些使用c++的实际例子

以下是c++在现实世界中用于实现一些非凡事物的一些领域。请注意,这个列表远非详尽无遗:

  • 视频游戏
  • 飞行软件
  • 科学研究
  • 金融领域
  • google

视频游戏

由于c++程序通常运行速度非常快,所以它们是游戏的自然选择,致力于创建高性能游戏的游戏设计师经常会选择它。《魔兽世界》和《虚幻竞技场》等游戏背后的虚幻引擎,以及《星际争霸》、《反恐精英》等为pc和流行游戏机开发的无数其他游戏都是使用这种语言编写的。

飞行软件

国防承包商大量使用c++来模拟、测试和模拟军用飞机(如f-16和f-35)的飞行能力。商用飞机当然也需要这样的软件,因为商业飞行员经常使用飞行模拟器进行训练。飞机安全性能软件,例如优化机翼设计以最小化阻力的软件,也使用这种语言。飞机安全软件的严格标准使其成为构建程序的特别有吸引力的选择。

科学研究

像太空探索和粒子物理学这样的前沿科学事业,如果没有c++,将不会成为它们现在的样子。欧洲核子研究中心的科学家使用用这种语言编写的程序来分析和解析来自粒子加速器实验的数据。美国国家航空航天局也使用用这种语言编写的程序为其火星车配备自主驾驶能力。

金融领域

主要金融机构在幕后运行着c++代码,使它们保持稳定。无论是使用这种语言编写的高频交易算法的对冲基金,还是使用它高效处理大量交易的信用卡公司,或者使用它设计加密安全系统的银行,c++在金融领域无处不在。

谷歌

甚至谷歌也在使用c++。这种语言的强大之处使得谷歌搜索引擎能够快速显示搜索结果,索引、组织和高效爬取数据,并创建机器学习工具以进一步提高性能。

接下来是…

Written by