《C++ Primer Plus(第6版)中文版》——1.4 程序创建的技巧

简介:

本节书摘来自异步社区出版社《C++ Primer Plus(第6版)中文版》一书中的第1章,第1.4节,作者: 【美】Stephen Prata,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.4 程序创建的技巧

假设您编写了一个C++程序。如何让它运行起来呢?具体的步骤取决于计算机环境和使用的C++编译器,但大体如下(参见图1.3)。

1.使用文本编辑器编写程序,并将其保存到文件中,这个文件就是程序的源代码。

2.编译源代码。这意味着运行一个程序,将源代码翻译为主机使用的内部语言——机器语言。包含了翻译后的程序的文件就是程序的目标代码(object code)。

3.将目标代码与其他代码链接起来。例如,C++程序通常使用库。C++库包含一系列计算机例程(被称为函数)的目标代码,这些函数可以执行诸如在屏幕上显示信息或计算平方根等任务。链接指的是将目标代码同使用的函数的目标代码以及一些标准的启动代码(startup code)组合起来,生成程序的运行阶段版本。包含该最终产品的文件被称为可执行代码。
image

本书将不断使用术语源代码,请记住该术语。

本书的程序都是通用的,可在任何支持C++98的系统中运行;但第18章的程序要求系统支持C++11。编写本书期间,有些编译器要求您使用特定的标记,让其支持部分C++11特性。例如,从4.3版起,g++要求您编译源代码文件时使用标记-std=c++0x:

image

创建程序的步骤可能各不相同,下面深入介绍这些步骤。

1.4.1 创建源代码文件
本书余下的篇幅讨论源代码文件中的内容;本节讨论创建源代码文件的技巧。有些C++实现(如Microsoft Visual C++、Embarcadero C++ Builder、Apple Xcode、Open Watcom C++、Digital Mars C++和Freescale CodeWarrior)提供了集成开发环境(integrated development environments,IDE),让您能够在主程序中管理程序开发的所有步骤,包括编辑。有些实现(如用于UNIX和Linux的GNU C++、用于AIX的IBM XL C/C++、Embarcadero分发的Borland 5.5免费版本以及Digital Mars编译器)只能处理编译和链接阶段,要求在系统命令行输入命令。在这种情况下,可以使用任何文本编辑器来创建和修改源代码。例如,在UNIX系统上,可以使用vi、ed、ex或emacs;在以命令提示符模式运行的Windows系统上,可以使用edlin、edit或任何程序编辑器。如果将文件保存为标准ASCII文本文件(而不是特殊的字处理器格式),甚至可以使用字处理器。另外,还可能有IDE选项,让您能够使用这些命令行编译器。

给源文件命名时,必须使用正确的后缀,将文件标识为C++文件。这不仅告诉您该文件是C++源代码,还将这种信息告知编译器(如果UNIX编译器显示信息“bad magic number”,则表明后缀不正确)。后缀由一个句点和一个或多个字符组成,这些字符被称作扩展名(参见图1.4)。
image

使用什么扩展名取决于C++实现,表1.1列出了一些常用的扩展名。例如,spiffy.C是有效的UNIX C++源代码文件名。注意,UNIX区分大小写,这意味着应使用大写的C字符。实际上,小写c扩展名也有效,但标准C才使用小写的c。因此,为避免在UNIX系统上发生混淆,对于C程序应使用c,而对于C++程序则请使用C。如果不在乎多输入一两个字符,则对于某些UNIX系统,也可以使用扩展名cc和cxx。DOS比UNIX稍微简单一点,不区分大小写,因此DOS实现使用额外的字母(如表1.1所示)来区别C和C++程序。

image

1.4.2 编译和链接

最初,Stroustrup实现C++时,使用了一个C++到C的编译器程序,而不是开发直接的C++到目标代码的编译器。前者叫做cfront(表示C前端,C front end),它将C++源代码翻译成C源代码,然后使用一个标准C编译器对其进行编译。这种方法简化了向C的领域引入C++的过程。其他实现也采用这种方法将C++引入到其他平台。随着C++的日渐普及,越来越多的实现转向创建C++编译器,直接将C++源代码生成目标代码。这种直接方法加速了编译过程,并强调C++是一种独立(虽然有些相似)的语言。

编译的机理取决于实现,接下来的几节将介绍一些常见的形式。这些总结概括了基本步骤,但对于具体步骤,必须查看系统文档。

1.UNIX编译和链接
最初,UNIX命令CC调用cfront,但cfront未能紧跟C++的发展步伐,其最后一个版本发布于1993年。当今的UNIX计算机可能没有编译器、有专用编译器或第三方编译器,这些编译器可能是商业的,也可能是自由软件,如GNU g++编译器。如果UNIX计算机上有C++编译器,很多情况下命令CC仍然管用,只是启动的编译器随系统而异。出于简化的目的,读者应假设命令CC可用,但必须认识到这一点,即对于下述讨论中的CC,可能必须使用其他命令来代替。

请用CC命令来编译程序。名称采用大写字母,这样可以将它与标准UNIX C编译器cc区分开来。CC编译器是命令行编译器,这意味着需要在UNIX命令行上输入编译命令。

例如,要编译C++源代码文件spiffy.C,则应在UNIX提示符下输入如下命令:

CC spiffy.C

如果由于技巧、努力或是幸运的因素,程序没有错误,编译器将生成一个扩展名为o的目标代码文件。在这个例子中,编译器将生成文件spiffy.o。

接下来,编译器自动将目标代码文件传递给系统链接程序,该程序将代码与库代码结合起来,生成一个可执行文件。在默认情况下,可执行文件为a.out。如果只使用一个源文件,链接程序还将删除spiffy.o文件,因为这个文件不再需要了。要运行该程序,只要输入可执行文件的文件名即可:

a.out

注意,如果编译新程序,新的可执行文件a.out将覆盖已有的a.out(这是因为可执行文件占据了大量空间,因此覆盖旧的可执行文件有助于降低存储需求)。然而,如果想保留可执行文件,只需使用UNIX的mv命令来修改可执行文件的文件名即可。

与在C语言中一样,在C++中,程序也可以包含多个文件(本书第8~第16章的很多程序都是这样)。在这种情况下,可以通过在命令行上列出全部文件来编译程序:

CC my.C precious.C

如果有多个源代码文件,则编译器将不会删除目标代码文件。这样,如果只修改了my.C文件,则可以用下面的命令重新编译该程序:

CC my.C precious.o

这将重新编译my.C文件,并将它与前面编译的precious.o文件链接起来。

可能需要显式地指定一些库。例如,要访问数学库中定义的函数,必须在命令行中加上-lm标记:

CC usingmath.C -lm

2.Linux编译和链接
Linux系统中最常用的编译器是g++,这是来自Free Software Foundation的GNU C++编译器。Linux的多数版本都包括该编译器,但并不一定总会安装它。g++编译器的工作方式很像标准UNIX编译器。例如,下面的命令将生成可执行文件a.out

g++ spiffy.cxx

有些版本可能要求链接C++库:

g++ spiffy.cxx -lg++

要编译多个源文件,只需将它们全部放到命令行中即可:

g++ my.cxx precious.cxx

这将生成一个名为a.out的可执行文件和两个目标代码文件my.o和precious.o。如果接下来修改了其中的某个源代码文件,如mu.cxx,则可以使用my.cxx和precious.o来重新编译:

g++ my.cxx precious.o

GNU编译器可以在很多平台上使用,包括基于Windows的PC和在各种平台上运行的UNIX系统。

3.Windows命令行编译器
要在Windows PC上编译C++程序,最便宜的方法是下载一个在Windows命令提示符模式(在这种模式下,将打开一个类似于MS-DOS的窗口)下运行的免费命令行编译器。Cygwin和MinGW都包含编译器GNU C++,且可免费下载;它们使用的编译器名为g++。

要使用g++编译器,首先需要打开一个命令提示符窗口。启动程序Cygwin和MinGW时,它们将自动为您打开一个命令提示符窗口。要编译名为great.cpp的源代码文件,请在提示符下输入如下命令:

g++ great.cpp

如果程序编译成功,则得到的可执行文件名为a.exe。

4.Windows编译器
Windows产品很多且修订频繁,无法对它们分别进行介绍。当前,最流行是Microsoft Visual C++ 2010,可通过免费的Microsoft Visual C++ 2010学习版获得。虽然设计和目标不同,但大多数基于Windows的C++编译器都有一些相同的功能。

通常,必须为程序创建一个项目,并将组成程序的一个或多个文件添加到该项目中。每个厂商提供的IDE(集成开发环境)都包含用于创建项目的菜单选项(可能还有自动帮助)。必须确定的非常重要的一点是,需要创建的是什么类型的程序。通常,编译器提供了很多选择,如Windows应用程序、MFC Windows应用程序、动态链接库、ActiveX控件、DOS或字符模式的可执行文件、静态库或控制台应用程序等。其中一些可能既有32位版本,又有64位版本。

由于本书的程序都是通用的,因此应当避免要求平台特定代码的选项,如Windows应用程序。相反,应让程序以字符模式运行。具体选项取决于编译器。一般而言,应选择包含字样“控制台”、“字符模式”或“DOS可执行文件”等选项。例如,在Microsoft Visual C++ 2010中,应选择Win32 Console Application(控制台应用程序)选项,单击Application Settings(应用程序设置),并选择Empty Project(空项目)。在C++ Builder中,应从C++ Builder Projects(C++ Builder项目)中选择Console Application(控制台应用程序)。

创建好项目后,需要对程序进行编译和链接。IDE通常提供了多个菜单项,如Compile(编译)、Build(建立)、Make(生成)、Build All(全部建立)、Link(链接)、Execute(执行)、Run(运行)和Debug(调试),不过同一个IDE中,不一定包含所有这些选项。

Compile通常意味着对当前打开的文件中的代码进行编译。
Build和Make通常意味着编译项目中所有源代码文件的代码。这通常是一个递增过程,也就是说,如果项目包含3个文件,而只有其中一个文件被修改,则只重新编译该文件。
Build All通常意味着重新编译所有的源代码文件。
Link意味着(如前所述)将编译后的源代码与所需的库代码组合起来。
Run或Execute意味着运行程序。通常,如果您还没有执行前面的步骤,Run将在运行程序之前完成这些步骤。
Debug意味着以步进方式执行程序。
编译器可能让您选择要生成调试版还是发布版。调试版包含额外的代码,这会增大程序、降低执行速度,但可提供详细的调试信息。
如果程序违反了语言规则,编译器将生成错误消息,指出存在问题的行。遗憾的是,如果不熟悉语言,将难以理解这些消息的含义。有时,真正的问题可能在标识行之前;有时,一个错误可能引发一连串的错误消息。

提示:

改正错误时,应首先改正第一个错误。如果在标识为有错误的那一行上找不到错误,请查看前一行。
需要注意的是,程序能够通过某个编译器的编译并不意味着它是合法的C++程序;同样,程序不能通过某个编译器的编译也并不意味着它是非法的C++程序。与几年前相比,现在的编译器更严格地遵循了C++标准。另外,编译器通常提供了可用于控制严格程度的选项。

提示:

有时,编译器在不完全地构建程序后将出现混乱,它显示无法改正的、无意义的错误消息。在这种情况下,可以选择Build All,重新编译整个程序,以清除这些错误消息。遗憾的是,这种情况和那些更常见的情况(即错误消息只是看上去无意义,实际上有意义)很难区分。
通常,IDE允许在辅助窗口中运行程序。程序执行完毕后,有些IDE将关闭该窗口,而有些IDE不关闭。如果编译器关闭窗口,将难以看到程序输出,除非您眼疾手快、过目不忘。为查看输出,必须在程序的最后加上一些代码:
image

cin.get( )语句读取下一次键击,因此上述语句让程序等待,直到按下了Enter键(在按下Enter键之前,键击将不被发送给程序,因此按其他键都不管用)。如果程序在其常规输入后留下一个没有被处理的键击,则第二条语句是必需的。例如,如果要输入一个数字,则需要输入该数字,然后按Enter键。程序将读取该数字,但Enter键不被处理,这样它将被第一个cin.get( )读取。

5.Macintosh上的C++
当前,Apple随操作系统Mac OS X提供了开发框架Xcode,该框架是免费的,但通常不会自动安装。要安装它,可使用操作系统安装盘,也可从Apple网站免费下载(但需要注意的是,它超过4GB)。Xcode不仅提供了支持多种语言的IDE,还自带了两个命令行编译器(g++和clang),可在UNIX模式下运行它们。而要进入UNIX模式,可通过实用程序Terminal。

提示:

为节省时间,可对所有示例程序使用同一个项目。方法是从项目列表中删除前一个示例程序的源代码文件,并添加当前的源代码。这样可节省时间、工作量和磁盘空间。

相关文章
|
29天前
|
存储 缓存 算法
【C/C++ 性能优化】提高C++程序的缓存命中率以优化性能
【C/C++ 性能优化】提高C++程序的缓存命中率以优化性能
114 0
|
1月前
|
编译器 Linux C++
3C++程序的编写和实现
3C++程序的编写和实现
19 2
|
1月前
|
C++ 开发者
2C++的程序的构成和书写形式
2C++的程序的构成和书写形式
16 2
|
24天前
|
存储 缓存 C++
C++链表常用的函数编写(增查删改)内附完整程序
C++链表常用的函数编写(增查删改)内附完整程序
|
1月前
|
缓存 编译器 程序员
C/C++编译器并行优化技术:并行优化针对多核处理器和多线程环境进行优化,以提高程序的并行度
C/C++编译器并行优化技术:并行优化针对多核处理器和多线程环境进行优化,以提高程序的并行度
62 0
|
1月前
|
缓存 编译器 程序员
C/C++编译器全局优化技术:全局优化是针对整个程序进行的优化,包括函数之间的优化
C/C++编译器全局优化技术:全局优化是针对整个程序进行的优化,包括函数之间的优化
27 0
|
1月前
|
缓存 算法 编译器
C/C++编译器内存优化技术:内存优化关注程序对内存的访问和使用,以提高内存访问速度和减少内存占用。
C/C++编译器内存优化技术:内存优化关注程序对内存的访问和使用,以提高内存访问速度和减少内存占用。
40 0
|
1月前
|
自然语言处理 编译器 调度
深入gcc编译器:C/C++代码如何变为可执行程序
深入gcc编译器:C/C++代码如何变为可执行程序
78 0
|
1月前
|
并行计算 安全 编译器
【C/C++ 编译相关 gcc】一次搞懂GCC编译选项:优化代码、调试程序必备!
【C/C++ 编译相关 gcc】一次搞懂GCC编译选项:优化代码、调试程序必备!
38 0
|
1月前
|
C++ 容器
【C++】程序题( STL标准模板库)
【C++】程序题( STL标准模板库)
25 0
【C++】程序题( STL标准模板库)