您的位置:首页 > 编程语言 > C语言/C++

《C++入门经典(第4版)》之C++编程总结

2015-09-08 10:34 218 查看
C++要比许多人想象的更容易理解。如果你非常渴望学习,并具备逻辑思考的能力,掌握C++就会比想象的更容易。开发C++技巧,学习数百万人已在使用的语言,掌握C++技能,它提供了在几乎任何环境下开发应用程序的能力。
本文的C++语言对应最新的ISO标准,一般称为C++ 14。C++14对以前的标准C++ 11进行了较小的扩展,所以本书的内容大都不专用于C++ 14。本文的所有示例都可以使用目前遵循C++ 11的编译器来编译和执行。


通过本文学习C++,需要一个遵循C++ 11标准的编译器和一个适合编写程序代码的文本编辑器。目前,有几个编译器兼容C++11,其中一些是免费的。
GNUProject生产的GCC编译器全面支持C++ 11,是一个开源产品,可免费下载。安装GCC并将它与合适的编辑器一起使用,对新手而言略有难度。安装GCC和合适编译器的一种简单方法是,从http://www.codeblocks.org上下载Code::Blocks。Code::Blocks是Linux、AppleMac OS X和Microsoft
Windows的一个免费IDE,它允许使用几个编译器(包括用于GCC、Clang和openWatcom的编译器)开发程序。这表示,安装Code::Blocks会获得C、C++和Fortran的支持。
另一种方法是使用在MicrosoftWindows下运行的Microsoft Visual C++,它不仅完全兼容C++ 11,而且已经安装好了。其免费版本是Microsoft VisualStudio 2013 Express。编写本书时,它可以编译本书的大多数示例,最终应能编译所有示例。MicrosoftVisual C++可以从http://www.microsoft.com/en-us/download/details.aspx?id=43733上下载。与GCC相比,Microsoft
Visual C++编译器的限制多一些,但根据它对C++ 11的支持力度,这是一个专业的编译器,还支持其他语言,例如C#和Basic。当然,也可以安装这两个编辑器。还有其他支持C++ 11的编辑器,在网上搜索会很快找到它们。
本书的内容循序渐进,所以读者应从头开始一直阅读到最后。但是,没有人能仅从一本书中获得所有的编程技巧。本书仅介绍如何使用C++编程,读者应自己输入所有的例子,而不是从下载文件中复制它们,再编译和执行输入的代码,这似乎很麻烦,但输入C++语句可以帮助理解C++,特别是觉得某些地方很难掌握时,自己输入代码就显得非常有帮助。如果例子不工作,不要直接从书中查找原因,而应在自己输入的例子代码中找原因,这是编写C++代码时必须做的一个工作。
有时必须在详细解释示例之前使用示例中的元素。本章将概述C++的主要元素及其组合方式,以帮助理解这些元素,还要探讨与计算机中表示数字和字符相关的几个概念。

本章主要内容

● 现代C++的含义

● C++程序的元素

● 如何注释程序代码

● C++代码如何变成可执行程序

● 面向对象的编程方式与过程编程方式的区别

● 二进制、十六进制和八进制数字系统

● Unicode

1.1 现代C++

现代C++使用最新、最好的C++元素编程。这是C++ 11 标准定义的C++语言,最新标准C++ 14 对它进行了谨慎的扩展和改进。本书介绍C++ 14 定义的C++。毫无疑问,C++是目前世界上使用最广泛、最强大的编程语言。如果打算学习一门编程语言,C++就是一个理想的选择。它能在极大范围内的计算设备和环境中高效地开发应用程序:个人电脑、工作站、大型计算机、平板电脑和移动电话。几乎任何程序都可以用C++编写:设备驱动程序、操作系统、薪水管理程序、游戏等。C++编译器也是唾手可得的。最新的编译器运行在PC、工作站和大型机上,常常具备跨编译功能,即可以在一个环境下开发代码,在另一个环境下编译并执行。C++带有一个非常大的标准库,其中包含大量例程和定义,提供了许多程序需要的功能。例如,数值计算、字符串处理、排序和搜索、数据的组织和管理、输入输出等。标准库非常大,本书仅涉及其皮毛。详细描述标准库提供的所有功能,需要好几本书的篇幅。Beginning
STL 是使用标准模板库的一个指南,而标准模板库是C++标准库中以各种方式管理和处理数据的一个子集。

就C++语言的范围和库的广度而言,初学者常常觉得C++令人生畏。将C++的全部内容放在一本书里是不可能的,但其实不需要学会C++的所有内容,就可以编写实用的程序。该语言可以循序渐进地学习,这并不是很难。例如学习开车,没有相关的专业知识和经验,也可以成为非常有竞争力的司机,在印第安纳波利斯安全地开车。通过本书,可以学到使用C++高效编程所需的所有知识。读完本书后,你肯定可以编写自己的应用程序,还可以开始研究C++及其标准库的所有内容。

1.2 C++程序概念

本书后面将详细论述本节介绍的所有内容。图1-1 是一个完全可以工作的完整C++程序,后面将解释该程序的各个部分。这个示例将用作讨论C++一般内容的基础。



图1-1 一个完整的C++程序

1.2.1 注释和空白

图1-1 中的前两行是注释。添加注释来解释程序代码,可以使他人更容易理解程序的工作方式。编译器会忽略一行代码中双斜杠后面的所有内容,所以这种注释可以跟在一行代码的后面。第一行注释指出包含代码的文件名。这个文件在本书的下载代码中。本书每个可工作示例的文件都以这种方式给出。文件扩展名.cpp 表示,这是一个C++源文件。其他扩展名,例如,.cc 也用于表示C++源文件。程序的所有可执行代码放在一个或多个源文件中。

需要把注释放在多行上时,可以使用另一种注释形式。例如:

<span style="font-family:Microsoft YaHei;font-size:14px;">/* This comment is
over two lines. */</span>


编译器会忽略/*和*/之间的所有内容。可以修饰这种注释,使其更加突出。例如:

<span style="font-family:Microsoft YaHei;font-size:14px;">/************************
* This comment is *
* over two lines. *
************************/</span>


空白是空格、制表符、换行符、换页符和注释的任意序列。编译器一般会忽略空白,除非由于语法原因需要使用空白把元素区分开来。

1.2.2 预处理指令和头文件

图1-1 的第三行是一个预处理指令。预处理指令会以某种方式修改源代码,之后把它们编译为可执行的形式。这个预处理指令把标准库头文件iostream 的内容添加到这个源文件Ex1_01.cpp 中。头文件的内容插入到#include 指令的位置。头文件包含源文件中使用的定义。iostream 包含使用标准库例程从键盘输入和将文本输出到屏幕上所需的定义。具体而言,它定义了std::cout 和std::endl。每个程序都可以包含一个或多个标准库头文件的内容,也可以创建和使用自己的头文件,以包含本书后面构建的定义。如果Ex1_01.cpp
中省略了包含iostream 头文件的预处理指令,源文件就不会编译,因为编译器不知道std::cout 和std::endl 是什么。在编译之前,把头文件的内容包含到源文件中。

提示:

尖括号和标准头文件名之间没有空格。对于一些编译器而言,尖括号<和>之间的空格很重要;如果在这里插入了空格,程序就不会编译。

1.2.3 函数

每个C++程序都至少包含一个函数,通常包含许多函数。函数是一个命名的代码块,这些是定义好的操作,例如读取输入的数据,计算平均值,或者输出结果。在程序中使用函数的名称执行或调用函数。程序中的所有可执行代码都放在函数中。程序中必须有一个名为main 的函数,执行总是自动从这个函数开始。main()函数总是调用其他函数,这些函数又可以调用其他函数,以此类推。函数提供了几个重要的优点:

● 程序分解为离散的函数,更容易开发和测试。

● 函数可以在程序的几个不同的地方重用,与在每个需要的地方编写操作代码相比,这会使程序更小。

● 函数常常可以在许多不同的程序中重用,节省了时间和精力。

● 大程序常常由一组程序员共同开发。每个组员负责编写一系列函数,这些函数是整个程序中已定义好的一个子集。没有函数结构,这就是不可能的。

图1-1 中的程序只包含main()函数。该函数的第一行是:

<span style="font-family:Microsoft YaHei;font-size:14px;">int main()</span>


这称为函数头,标识了函数。其中int 是一个类型名称,它定义了main()函数执行完毕时返回的值的类型整数。一般情况下,函数定义中名称后面的圆括号,包含了调用函数时要传递给函数的信息的说明。本实例中的圆括号是空的,但其中可以有内容。第5章将学习如何指定执行函数时传递给函数的信息的类型。文本中总是在函数名的后面加上圆括号,以区分函数与其他代码。函数的可执行代码总是放在花括号中,左花括号跟在函数头的后面。

1.2.4 语句

语句是C++程序的基本单元。语句总是用分号结束。分号表示语句的结束,而不是代码行的结束。语句可以定义某个元素,例如计算或者要执行的操作。程序执行的所有操作都是语句指定的。语句按顺序执行,除非有某个语句改变了这个顺序。第4 章将学习可以改变执行顺序的语句。图1-1 的main()中有3 个语句。第一个语句定义了一个变量,变量是一个命名的内存块,用于存储某种数据。在本例中变量的名称是answer,可以存储整数值:

<span style="font-family:Microsoft YaHei;font-size:14px;">int answer {42}; // Defines answer with the value 42</span>


类型int 放在名称的前面,这指定了可以存储的数据类型——整数。注意int 和answer之间的空格。这里的一个或多个空白字符是必需的,用于分隔类型名称和变量名称。如果没有空格,编译器会把名称看作intanswer,这是编译器无法理解的。answer 的初始值放在变量名后面的花括号中,所以它最初存储了42。answer 和{42}之间也有一个空格,但这个空格不是必需的。花括号不是名称的一部分,所以无论如何,编译器都可以区分名称和初始值的指定。但是,应以统一的风格使用空白,提高代码的可读性。在第一个语句的末尾有一个多余的注释,解释了上述内容,这还说明,可以在语句中添加注释。

//前面的空白也不是强制的,但最好保留这个空白。

可以把几个语句放在一对花括号{}中,此时这些语句就称为语句块。函数体就是一个语句块,如图1-1 所示,main()函数体中的语句就放在花括号中。语句块也称为复合语句,因为在许多情况下,语句块可以看作是一个语句,详见第4 章中的决策功能。在可以放置一个语句的任何地方,都可以放置一个包含在花括号对中的语句块。因此,语句块可以放在其他语句块内部,这个概念称为嵌套。事实上,语句块可以嵌套任意级。

1.2.5 数据输入输出

在C++中,输入和输出是使用流来执行的。如果要输出消息,可以把该消息放在输出流中,如果要输入数据,则把它放在输入流中。因此,流是数据源或数据池的一种抽象表示。在程序执行时,每个流都关联着某个设备,关联着数据源的流就是输入流,关联着数据目的地的流就是输出流。对数据源或数据池使用抽象表示的优点是,无论流代表什么设备,编程都是相同的。例如,从磁盘文件中读取数据的方式与从键盘上读取完全相同。在C++中,标准的输出流和输入流称为cout 和cin,在默认情况下,它们分别对应计算机的屏幕和键盘。第2 章将从cin
中读取输入。

在图1-1 中,main()的下一个语句把文本输出到屏幕:

<span style="font-family:Microsoft YaHei;font-size:14px;">std::cout<< "The answer to life, the universe, and everything is "
<< answer
<<std::endl;</span>
该语句放在3 行上,只是为了说明这么做是可行的。名称cout 和endl 在iostream 头文件中定义。本章后面将解释std::前缀。<<是插入操作符,用于把数据传递到流中。第2 章会遇到提取操作符>>,它用于从流中读取数据。每个<<右边的所有内容都会传递到cout 中。把endl 写入std::cout,会在流中写入一个换行符,并刷新输出缓存。刷新输出缓存可确保输出立即显示出来。该语句的结果如下:

<span style="font-family:Microsoft YaHei;font-size:14px;">The answer to life, the universe, and everything is 42</span>
可以给每行语句添加注释。例如:

<span style="font-family:Microsoft YaHei;font-size:14px;">std::cout << "The answer to life, the universe, and everything is "
// This statement
<< answer // occupies
<< std::endl; // three lines</span>


双斜杠不必对齐,但我们常常对齐双斜杠,使之看起来更整齐,代码更容易阅读。

1.2.6 return 语句

main()中的最后一个语句是return。return 语句会结束函数,把控制权返回给调用函数的地方。在本例中它会结束函数,把控制权返回给操作系统。return 语句可能返回一个值或没有返回值。本例的return 语句给操作系统返回0,表示程序正常结束。程序可以返回非0 值,例如1、2 等,表示不同的异常结束条件。Ex1_01.cpp 中的return 语句是可选的,可以忽略它。这是因为如果程序执行超过了main()的最后一个语句,就等价于执行return 0。

1.2.7 名称空间

大项目会同时涉及几个程序员。这可能会带来名称问题。不同的程序员可能给不同的元素使用相同的名称,这可能会带来一些混乱,使程序出错。标准库定义了许多名称,很难全部记住。不小心使用了标准库名称也会出问题。名称空间就是用于解决这个问题的。

名称空间类似于姓氏,它置于该名称空间中声明的所有名称前面。标准库中的名称都在std 名称空间中定义,cout 和endl 是标准库中的名称,所以其全名是std::cout 和

std::endl。其中的两个冒号有一个非常奇特的名称:作用域解析操作符,详见后面的说明。这里它用于分隔名称空间的名称std 和标准库中的名称,例如cout 和endl。标准库中的几乎所有名称都有前缀std。

名称空间的代码如下所示:

<span style="font-family:Microsoft YaHei;font-size:14px;">namespaceih_space {
// All names declared in here need to be prefixed
// with ih_space when they are reference from outside.
// For example, a min() function defined in here
// would be referred to outside this namespace as ih_space::min()
}</span>


花括号对中的所有内容都位于ih_space 名称空间中。

警告:

main()函数不能定义在名称空间中,未在名称空间中定义的内容都存在于全局名称空间中,全局名称空间没有名称。

1.2.8 名称和关键字

Ex1_01.cpp 包含变量answer 的定义,并使用在iostream 标准库头文件中定义的名称cout 和endl。程序中的许多元素都需要名称,定义名称的规则如下:

● 名称可以是包含大小写拉丁字母A~Z 和a~z、数字0~9 和下划线_的任意序列。

● 名称必须以字母或下划线开头。

● 名称是区分大小写的。

名称可以用下划线开头,但最好不要使用这样的名称,它们可能与C++标准库中的名称冲突,因为C++标准库以这种方式定义了大量的名称。C++标准还允许名称有任意长度,但有的编译器对此有某种长度限制,这个限制常常比较宽,不是一个严格的限制。大多数情况下,不需要使用长度超过12~15 个字符的名称。

下面是一些有效的C++名称:

<span style="font-family:Microsoft YaHei;font-size:14px;">toe_count shoeSize Box democrat Democrat number1 x2 y2 pValue out_of_range</span>
大小写字母是有区别的,所以democrat 和Democrat 是不同的名称。编写由两个或多个单词组成的名称时,有几个约定;可以把第二个及以后各个单词的首字母大写,或

者用下划线分隔它们。

关键字是C++中有特殊含义的保留字,不能把它们用于其他目的。例如,class、double、throw 和catch 都是保留字。

1.3 类和对象

类是定义数据类型的代码块。类的名称就是类型的名称。类类型的数据项称为对象。创建变量,以存储自定义数据类型的对象时,就要使用类类型名称。定义自己的数据类型,就可以根据具体的问题提出解决方案。例如,如果编写一个处理学生信息的程序,就可以定义Student 类型。Student 类型可以包含学生的所有特征,例如年龄、性别或学校记录——这些都是程序需要的。

1.4 模板

有时程序需要几个类似的类或函数,其代码中只有所处理的数据类型有区别。编译器可以使用模板给特定的自定义类型自动生成类或函数的代码。编译器使用类模板会生成一个或多个类系列,使用函数模板会生成函数。每个模板都有名称,希望编译器创建模板的实例时,就会使用该名称。标准库大量使用了模板。

1.5 程序文件

C++代码存储在两种文件中。源文件包含函数,因此包含程序中的所有可执行代码。源文件的名称通常使用扩展名.cpp,但也使用其他扩展名,例如.cc。头文件包含元素的定义,例如.cpp 文件中的可执行代码使用的类和模板。头文件的名称通常使用.h 扩展名,但也使用其他扩展名,例如.hpp。当然,实际的程序一般包含其他类型的文件,这些文件包含的内容与C++无关,例如定义图形用户界面(GUI)的资源。

1.6 标准库

如果每次编写程序时,都从头开始创建所有内容,就是一件非常枯燥的工作。许多程序都需要相同的功能,例如从键盘上读取数据,计算平方根,将数据记录按特定的顺

序排列。C++附带大量预先编写好的代码,提供了所有这些功能,因此不需要自己编写它们。这些标准代码都在标准库中定义。标准库的一个子集是标准模板库(STL),它包含

大量的类模板,用于创建类型,以组织和管理数据。标准库还包含许多函数模板,用于执行各种操作,例如排序和搜索数据集合,进行数值处理等。本书将学习STL 的几个功能,但全面讨论STL 需要一整本书的篇幅。Beginning STL 是本书的后续产品,专门介绍STL。

1.7 代码的表示样式

代码排列的方式对代码的可读性有非常重要的影响。这有两种基本的方式。首先,可以使用制表符和/或空格缩进程序语句,显示出这些语句的逻辑;再以一致的方式使用定义程序块的匹配花括号,使块之间的关系更清晰。其次,可以把一个语句放在两行或多行上,提高程序的可读性。安排匹配花括号和缩进语句的约定称为表示样式。代码有许多不同的表示样式。表1-1 显示了三种常用的代码表示样式。



本书的示例使用样式1。

1.8 创建可执行文件

从C++源代码中创建可执行的模块需要两步骤。第一步是编译器把每个.cpp 文件转换为对象文件,其中包含了与源文件内容对应的机器码。第二步是链接程序把程序的对象文件合并到包含完整可执行程序的文件中。在这个过程中,链接程序会集成程序使用的标准库函数。

图1-2 表明,3 个源文件经过编译后,生成3 个对应的对象文件。用于标识对象文件的文件扩展名在不同的机器环境上是不同的,这里没有显示。组成程序的源文件可以在不同的编译器运行期间单独编译,但大多数编译器都允许在一次运行期间编译它们。无论采用哪种方式,编译器都把每个源文件看作一个独立的实体,为每个.cpp 文件生成一个对象文件。然后在链接步骤中,把程序的对象文件和必要的库函数组合到一个可执行文件中。

实际上,编译是一个迭代的过程,因为在源代码中总是会有输入错误或其他错误。更正了每个源文件中的这些错误后,就可以进入链接步骤,但在这一步可能会发现有更多的错误!即使链接步骤生成了可执行模块,程序仍有可能包含逻辑错误,即程序没有生成希望的结果。为了更正这些错误,必须回过头来修改源代码,再编译。这个过程会继续下去,直到程序按照希望的那样执行为止。如果程序的执行结果不像我们宣称的那样,其他人就有可能找到我们本应发现的许多错误,这是毋庸置疑的。一般说来,如果程序非常大,就总是包含错误。



图1-2 编译和链接过程

1.9 表示数字

在C++程序中,数字的表示有许多方式,所以必须理解表示数字的各种可能性。如果很熟悉二进制数、十六进制数和浮点数的表示,就可以跳过本节。

1.9.1 二进制数

首先考虑一下常见的十进制数(如324 或911)表示什么。显然,324 是表示三百二十四,911 表示九百一十一。这是“三百”加上“二十”再加上“四”的简写形式,或者是“九百”加上“一十”再加上“一”的简写形式。更明确地说,这两个数表示:

324 是:3×102+2×101+4×100,也就是3×10×10+2×10+4

911 是:9×102+1×101+1×100,也就是9×10×10+1×10+1

这称为十进制表示法,因为这是建立在10 的幂的基础之上。也可以说,这里的数字以10 为基底来表示,因为每个数位都是10 的幂。以这种方式表示数值非常方便,因为人有10 根手指或10 根脚趾或者10 个任何类型的附属物。但是,这对PC 就不太方便了,因为PC 主要以开关为基础,即开和关,加起来只有2,而不是10。这就是计算机用基数2 而不是用基数10 来表示数值的主要原因。用基数2 来表示数值称为二进制计数系统。用基数10 表示数字,数字可以是0~9。一般情况下,以任意n 为基底来表示的数,每个数位的数字是从0
到n-1。

二进制数字只能是0 或1,二进制数1101 就可以分解为:

1×23+1×22+0×21+1×20,也就是1×2×2×2+1×2×2+0×2+1

计算得13(十进制系统)。在表1-2 中,列出了用8 个二进制数字表示的对应的十进制值(二进制数字常常称为位)。



使用前7 位可以表示从0~127 的数,一共128 个不同的数,使用全部8 位可以表示256(即28)个数。一般情况下,如果有n 位,就可以表示2n 个整数,其正值从0 到2n-1。

在计算机中,二进制数相加是非常容易的,因为对应数字加起来的进位只能是0 或1,所以处理过程会非常简单。图1-3 中的例子演示了两个8 位二进制数相加的过程。



相加操作从最右边开始,将操作数中对应的位相加。图1-3 指出,前6 位都向左边的下一位进1,这是因为每个数字只能是0 或1。计算1+1 时,结果不能存储在当前的位中,而需要在左边的下一位中加1。

1.13 本章小结

本章简要介绍了C++的一些基本概念。后面将详细讨论本章提及的内容。本章介绍的基本概念如下:

● C++程序包含一个或多个函数,其中一个是main()函数。执行总是从main()函数开始。

● 函数的可执行部分由包含在一对花括号中的语句组成。

● 一对花括号定义了一个语句块。

● 语句用分号结束。

● 关键字是C++中有特殊含义的一组保留字。程序中的实体不能与C++语言中的任何关键字同名。

● C++程序包含在一个或多个文件中。源文件包含可执行代码,头文件包含可执行代码使用的定义。

● 定义函数的代码通常存储在扩展名为.cpp 的源文件中。

● 源文件使用的定义通常存储在扩展名为.h 的头文件中。

● 预处理器指令指定了要对文件中的代码执行的操作。所有的预处理器指令都在编译文件中的代码之前执行。

● 头文件中的代码通过#include 预处理器指令添加到源文件中。

● 标准库提供了支持和扩展C++语言的大量功能。

● 要访问标准库函数和定义,可以把标准库头文件包含到源文件中。

● 输入和输出是利用流来执行的,需要使用插入和提取运算符,即<<和>>。std::cin是对应于键盘的标准输入流,std::cout 是把文本写入屏幕的标准输出流。它们都在标准库头文件iostream 中定义。

● 面向对象的编程方式需要定义专用于某问题的新数据类型。一旦定义好需要的数据类型,就可以根据这些新数据类型来编写程序。

● Unicode 定义的独特整数代码值表示世界上几乎所有语言的字符,以及许多专用的字符集。代码值也称为代码点。Unicode 还定义了代码点如何编码为字节序列。

《C++入门经典(第4版)》试读电子书免费提供,有需要的留下邮箱,一有空即发送给大家。 别忘啦顶哦!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: