1、C++简介
C++继承了 C 语言高效、简洁、快速和可移植性的传统。C++面向对象的特性带来了全新的编程方法,这种方法是为应付复杂程度不断提高的现代编程任务而设计的。
C++的模板特性提供了另一种全新的编程方法——泛型编程。
C++融合了 3 种不同的编程方式:C 语言代表的过程性语言、C++在 C 语言基础上添加的类代表的面向对象语言、C++模板支持的泛型编程。
2、C++简史
2.1 C 语言
20 世纪 70 年代早期,贝尔实验室的 Dennis Ritchie 致力于开发 UNIX 操作系统(操作系统是能够管理计算机资源、处理计算机与用户之间交互的一组程序。例如,操作系统将系统提示符显示在屏幕上以提供终端式界面、提供管理窗口和鼠标的图形界面以及运行程序)。为完成这项工作,Ritchie 需要一种语言,它必须简洁,能够生成简洁、快速的程序,并能有效地控制硬件。
传统上,程序员使用汇编语言来满足这些需求,汇编语言依赖于计算机的内部机器语言。然而,汇编语言是低级(low-level)语言,即直接操作硬件,如直接访问 CPU 寄存器和内存单元。因此汇编语言针对于特定的计算机处理器,要将汇编程序移植到另一种计算机上,必须使用不同的汇编语言重新编写程序。这有点像每次购买新车时,都发现设计人员改变了控制系统的位置和功能,客户不得不重新学习驾驶。
然而,UNIX 是为在不同的计算机(或平台)上工作而设计的,这意味着它是一种高级语言。高级(high-level)语言致力于解决问题,而不针对特定的硬件。一种被称为编译器的特殊程序将高级语言翻译成特定计算机的内部语言。这样,就可以通过对每个平台使用不同的编译器来在不同的平台上使用同一个高级语言程序了。Ritchie 希望有一种语言能将低级语言的效率、硬件访问能力和高级语言的通用性、可移植性融合在一起,于是他在旧语言的基础上开发了 C 语言。
2.2 C 语言编程原理
由于 C++在 C 语言的基础上移植了新的编程理念,因此我们首先来看一看 C 所遵循的旧的理念。一般来说,计算机语言要处理两个概念——数据和算法。数据是程序使用和处理的信息,而算法是程序使用的方法。
2.3 面向对象编程
虽然结构化编程的理念提高了程序的清晰度、可靠性,并使之便于维护,但它在编写大型程序时,仍面临着挑战。为应付这种挑战,OOP 提供了一种新方法。与强调算法的过程性编程不同的是,OOP 强调的是数据。OOP 不像过程性编程那样,试图使问题满足语言的过程性方法,而是试图让语言来满足问题的要求。其理念是设计与问题的本质特性相对应的数据格式。
在 C++中,类是一种规范,它描述了这种新型数据格式,对象是根据这种规范构造的特定数据结构。类规定了可使用哪些数据来表示对象以及可以对这些数据执行哪些操作。
OOP 程序设计方法首先设计类,它们准确地表示了程序要处理的东西。OOP 编程并不仅仅是将数据和方法合并为类定义。例如,OOP 还有助于创建可重用的代码,这将减少大量的工作。信息隐藏可以保护数据,使其免遭不适当的访问。多态让您能够为运算符和函数创建多个定义,通过编程上下文来确定使用哪个定义。继承让您能够使用旧类派生出新类。
2.4 C++和泛型编程
泛型编程(generic programming)是 C++支持的另一种编程模式。它与 OOP 的目标相同,即使重用代码和抽象通用概念的技术更简单。不 Bjarne Stroustrup 的主页过 OOP 强调的是编程的数据方面,而泛型编程强调的是独立于特定数据类型。它们的侧重点不同。OOP 是一个管理大型项目的工具,而泛型编程提供了执行常见任务(如对数据排序或合并链表)的工具。术语泛型(generic)指的是创建独立于类型的代码。C++的数据表示有多种类型——整数、小数、字符、字符串、用户定义的、由多种类型组成的复合结构。例如,要对不同类型的数据进行排序,通常必须为每种类型创建一个排序函数。泛型编程需要对语言进行扩展,以便可以只编写一个泛型(即不是特定类型的)函数,并将其用于各种实际类型。C++模板提供了完成这种任务的机制。
2.5 C++的起源
与 C 语言一样,C++也是在贝尔实验室诞生的,Bjarne Stroustrup 于 20 世纪 80 年代在这里开发出了这种语言。C++是 C 语言的超集,这意味着任何有效的 C 程序都是有效的 C++程序。它们之间有些细微的差异,但无足轻重。C++程序可以使用已有的 C 软件库。库是编程模块的集合,可以从程序中调用它们。
3、可移植性和标准
在可移植性方面存在两个障碍,其中的一个是硬件。硬件特定的程序是不可移植的。
将依赖于硬件的部分放在函数模块中可以最大限度地降低可移植性问题。这样只需重新编写这些模块即可。
3.1 C++的发展
Stroustrup 编写的《The Programming Language》包含 65 页的参考手册,它成了最初的 C++事实标准。下一个事实标准是 Ellis 和 Stroustrup 编写的《The Annotated C++Reference Manual》。C++98 标准新增了大量特性,其篇幅将近 800 页,且包含的说明很少。C++11 标准的篇幅长达 1350 页,对旧标准做了大量的补充。
4、程序创建的技巧
假设您编写了一个 C++程序。如何让它运行起来呢?具体的步骤取决于计算机环境和使用的 C++编译器。
1.使用文本编辑器编写程序,并将其保存到文件中,这个文件就是程序的源代码。
2.编译源代码。这意味着运行一个程序,将源代码翻译为主机使用的内部语言——机器语言。包含了翻译后的程序的文件就是程序的目标代码(object code)。
3.将目标代码与其他代码链接起来。
4.1 创建源代码文件
给源文件命名时,必须使用正确的后缀,将文件标识为 C++文件。这不仅告诉您该文件是 C++源代码,还将这种信息告知编译器。后缀由一个句点和一个或多个字符组成,这些字符被称作扩展名。
4.2 编译和链接
Stroustrup 实现 C++时,使用了一个 C++到 C 的编译器程序,而不是开发直接的 C++到目标代码的编译器。前者叫做 cfront(表示 C 前端,C front end),它将 C++源代码翻译成 C 源代码,然后使用一个标准 C 编译器对其进行编译。这种方法简化了向 C 的领域引入 C++的过程。其他实现也采用这种方法将 C++引入到其他平台。随着 C++的日渐普及,越来越多的实现转向创建 C++编译器,直接将 C++源代码生成目标代码。这种直接方法加速了编译过程,并强调 C++是一种独立(虽然有些相似)的语言。
例如,要编译 C++源代码文件 spiffy.C,则应在 UNIX 提示符下输入
如下命令:
CC spiffy.C
编译器将生成一个扩展名为 o 的目标代码文件。在这个例子中,编译器将生成文件 spiffy.o。
接下来,编译器自动将目标代码文件传递给系统链接程序,该程序将代码与库代码结合起来,生成一个可执行文件。在默认情况下,可执行文件为 a.out。如果只使用一个源文件,链接程序还将删除 spiffy.o 文件,因为这个文件不再需要了。要运行该程序,只要输入可执行文件的文件名即可:
a.out
注意,如果编译新程序,新的可执行文件 a.out 将覆盖已有的 a.out(这是因为可执行文件占据了大量空间,因此覆盖旧的可执行文件有助于降低存储需求)。然而,如果想保留可执行文件,只需使用 UNIX 的 mv 命令来修改可执行文件的文件名即可。与在 C 语言中一样,在 C++中,程序也可以包含多个文件。在这种情况下,可以通过在命令行上列出全部文件来编译程序:
CC my.C precious.C
如果有多个源代码文件,则编译器将不会删除目标代码文件。这样,如果只修改了 my.C 文件,则可以用下面的命令重新编译该程序:
CC my.C precious.o
这将重新编译 my.C 文件,并将它与前面编译的 precious.o 文件链接起来。可能需要显式地指定一些库。例如,要访问数学库中定义的函数,必须在命令行中加上-lm 标记:
CC usingmath.C -lm