1.1 编写一个简单的C++程序
- 每个C++程序都包含一个或多个函数,其中一个必须命名为main。操作系统通过调用main来运行C++程序。
- 一个函数的定义包含四部分:返回类型、函数名、一个括号包围的形参列表以及函数体。
- main函数的返回类型必须为int,即整数类型。int类型是一种内置类型,即语言自身定义的类型。
- 函数体是一个以左花括号开始,以右花括号结束的语句块。
- return语句结束函数的执行,通常还会向调用者返回一个值。当return语句包括一个值时,此返回值的类型必须与函数的返回类型相同。在大多数系统中,main的返回值被用来指示状态,返回值0表示成功,非0的返回值的含义由系统定义,通常用来指出错误类型。
- 在C++中,大多数C++语句以分号表示结束。
- 类型是程序设计最基本的概念之一。一种类型不仅定义了数据元素的内容,还定义了这类数据上可以进行的运算。程序所处理的数据都保存在变量中,而每个变量都有自己的类型。
1.1.1 编译、运行程序
- 集成开发环境(IDE)将编译器与其他程序创建和分析工具包装在一起。在开发大型程序时,这类集成环境可能是非常有用的工具。
- 程序文件通常被称为源文件。不同编译器使用不同的后缀命名约定,最常见的包括.cc、.cxx、.cpp、.cp及.C。
1.2 初识输入输出
- C++语言并未定义任何输入输出(IO)语句,取而代之,包含了一个全面的标准库来提供IO机制(以及很多其他设施)。
- iostream库包含两个基础类型istream和ostream,分别表示输入流和输出流。一个流就是一个字符序列,是从IO设备读出或写入IO设备的。术语“流”想要表达的是,随着时间的推移,字符是顺序生成或消耗的。
- 标准库定义了4个IO对象。为了处理输入,我们使用一个名为cin(发音为see-in)的istream类型的对象。这个对象也被称为标准输入。对于输出,我们使用一个名为cout(发音为see-out)的ostream类型的对象。此对象也被称为标准输出。标准库还定义了其他两个ostream对象,名为cerr和clog(发音分别为see-err和see-log)。我们通常用cerr来输出警告和错误消息,因此它也被称为标准错误。而clog用来输出程序运行时的一般性信息。
- 系统通常将程序所运行的窗口与这些对象关联起来。因此,当我们读取cin,数据将从程序正在运行的窗口读入,当我们向cout、cerr和clog写入数据时,将会写到同一个窗口。
- 每个使用标准库设施的程序都必须包含相关的头文件。#include指令用于包含头文件,其后尖括号中的名字则指出要包含的头文件是哪一个。#include指令和头文件的名字必须写在同一行中。通常情况下,#include指令必须出现在所有函数之外。我们一般将一个程序的所有#include指令都放在源文件的开始位置。
- 在C++中,一个表达式产生一个计算结果,它由一个或多个运算对象和(通常是)一个运算符组成。
- 输出运算符(<<)接受两个运算对象:左侧的运算对象必须是一个ostream对象,右侧的运算对象是要打印的值。此运算符将给定的值写到给定的ostream对象中。输出运算符的计算结果就是其左侧运算对象,所以可以在一条输出语句中使用多个输出运算符,将多个输出请求连接起来。
- 字符串字面值常量是用一对双引号包围的字符序列。
- endl是一个被称为操纵符的特殊值。向输出流写入endl的效果是结束当前行,并将与设备关联的缓冲区中的内容刷到设备中。缓冲刷新操作可以保证到目前为止程序所产生的所有输出都真正写入输出流中,而不是仅停留在内存中等待写入流。程序员常常在调试时添加打印语句,这类语句应该保证“一直”刷新流。否则,如果程序崩溃,输出可能还留在缓冲区中,从而导致关于程序崩溃位置的错误推断。
- 命名空间可以帮助我们避免不经意间的名字定义冲突,以及使用库中相同名字导致的冲突。标准库定义的所有名字都在命名空间std中。
- 通过命名空间使用标准库有一个副作用:当使用标准库中的一个名字时,必须显示说明我们想使用来自命名空间std中的名字,如std::cout等。其中,作用域运算符(::)指出我们使用的名字位于哪一个命名空间。
- 初始化一个变量,就是在变量创建的同时为它赋予一个值。
- 输入运算符(>>)接受一个istream对象作为其左侧运算对象,接受一个对象作为其右侧运算对象。它从给定的istream对象读入数据,并存入给定对象中。输入运算符返回其左侧运算对象作为其计算结果,所以可以在一条输入语句中使用多个输入运算符,将多个输入请求连接起来。
1.3 注释简介
- 注释可以帮助人类读者理解程序。注释通常用于概述算法,确定变量的用途,或者解释晦涩难懂的代码段。编译器会忽略注释,因此注释对程序的行为或性能不会有任何影响。由于程序员倾向于相信注释的内容是正确可信的,因此,错误的注释比完全没有注释更糟糕,因为它会误导读者。所以,记住在修改代码后及时更新注释。
- 单行注释以双斜线(//)开始,以换行符结束。当前行双斜线右侧的所有内容都会被编译器忽略,这种注释可以包含任何文本,包括额外的双斜线。
- 界定符对注释以/*开始,以*/结束,可以包含除*/外的任意内容(因而不能嵌套),包括换行符。编译器将落在/*和*/之间的所有内容都当作注释。注释界定符可以放置于任何允许放置制表符、空格符或换行符的地方。界定符对注释可以跨越程序中的多行,若如此做,最好能显式指出其内部的程序行都属于多行注释的一部分,如在注释内的每行开头都加上一个星号等。
1.4 控制流
1.4.1 while语句
- while语句反复执行一段代码,直至给定条件为假为止。其形式为:while (condition) statement。while语句的执行过程是交替地检测condition条件和执行关联的语句statement,直至condition为假时停止。
- 所谓条件就是一个产生真或假的结果的表达式。
- 在while语句中,循环体statement可以是语句块。所谓语句块,就是用花括号包围的零条或多条语句的序列。语句块也是语句的一种,在任何要求使用语句的地方都可以使用语句块。
- +=是一种复合赋值运算符,作用是将其右侧的运算对象加到左侧运算对象上,将结果保存到左侧运算对象中。它本质上与一个加法结合一个赋值是相同的。
- 递增运算符(++)的作用是将运算对象的值增加1。与之对应,递减运算符(--)的作用是将运算对象的值减少1。递增运算符与递减运算符都有前缀式和后缀式两种。
1.4.2 for语句
- 每个for语句都包含两部分:循环头和循环体。循环头控制循环体的执行次数,它由三部分组成:一个初始化语句、一个循环条件以及一个表达式。
- 初始化语句用于为控制循环的变量赋初值。如果控制循环的变量是由初始化语句定义的,那么这个变量只能在for循环内部使用,在循环结束后是不能使用的。初始化语句只在for循环入口处执行一次。
- 循环体每次执行前都会检查循环条件,只要条件为真,就会反复执行循环体并计算表达式的结果(通常是用递增或递减运算符修改控制循环的变量)。
1.4.3 读取数量不定的输入数据
- 实现不断读取数据直至没有新的输入的一种方法是:while (std::cin >> value)。
- 当我们使用一个istream对象作为条件时,其效果是检测流的状态。如果流是有效的,即流未遇到错误,那么检测成功。当遇到文件结束符,或遇到一个无效输入时,istream对象的状态会变为无效。处于无效状态的istream对象会使条件变为假。
- 在不同的操作系统中,如何指出文件结束有不同的约定。在Windows系统中输入文件结束符的方法是敲Ctrl+Z,而在UNIX和Mac OS X系统中输入文件结束符的方法是敲Ctrl+D。
- 编译器无法检查一个程序是否按照其作者的意图工作,但是可以检查形式上的错误,如语法错误、类型错误、声明错误。声明错误的通常情况是:对来自标准库的名字忘记使用std::、标识符名字拼写错误等。
- 错误信息通常包含一个行号和一条简短描述,描述了编译器认为的我们所犯的错误。因为一个错误常常会具有传递效应,导致编译器在其后报告比实际数量多得多的错误信息,所以建议按照报告的顺序来逐个修正错误,并在每修正一个错误或一小部分明显的错误后就立即重新编译代码。这就是所谓的“编辑-编译-调试”周期。
1.4.4 if语句
- if语句的形式是:if (condition) statement else statement。当condition条件为真时执行紧跟着的statement,否则执行if语句后面的语句,或是执行紧跟着对应else语句的statement(如果有的话)。
- C++用=进行赋值,用==作为相等运算符。两个运算符都可以出现在条件中。一个常见的错误是想在条件中使用==(相等判断),却误用了=。
- C++程序很大程度上是格式自由的,即何处放置花括号、缩进、注释以及换行符通常不会影响程序的语义。但我们所做的选择会影响程序的可读性。当我们要选择一种格式风格时,思考一下它会对程序的可读性和易理解性有什么影响,而一旦选择了一种风格,就要坚持使用。
1.5 类简介
- 类机制是C++最重要的特性之一。一个类定义了一个类型,以及与其关联的一组操作。
- 习惯上,头文件根据其中定义的类的名字来命名。我们通常使用.h作为头文件的后缀,但也有一些程序员习惯.H、.hpp或.hxx。标准库头文件通常不带后缀。
1.5.1 Sales_item类
- 每个类实际上都定义了一个新的类型,其类型名就是类名。与内置类型一样,我们可以定义类类型的变量。
- 一般而言,类的作者决定了类类型对象上可以使用的所有操作。
- 包含来自标准库的头文件时,使用尖括号(<>)包围头文件名,而对于不属于标准库的头文件,则用双引号("")包围。
- 大多数操作系统支持文件重定向,这种机制允许我们将标准输入和标准输出与命名文件关联起来:$ addItems <infile >outfile。假定$是操作系统提示符,addItem为某一可执行文件,则上述命令会从一个名为infile的文件读取输入,并将输出结果写入到一个名为outfile的文件中,两个文件都位于当前目录中。
1.5.2 初识成员函数
- 成员函数是定义为类的一部分的函数,有时也被称为方法。
- 我们使用点运算符(.)来访问成员函数。点运算符的左侧运算对象必须是一个类类型的对象,右侧运算对象必须是该类型的一个成员名,运算结果为右侧运算对象指定的成员。
- 我们使用调用运算符(())来调用一个函数。调用运算符是一对圆括号,里面放置实参列表(可能为空)。
1.6 书店程序
(无)