Loading

C++Primer 第1章

第1章 开始

1.1 编写一个简单的C++程序

每个C++程序都包含一个或多个函数,其中一个必须命名为main。操作系统通过调用main来运行C++程序。

一个函数的定义包含四部分:返回类型(return type)、函数名(function name)、一个括号包围的形参列表(parameter list,允许为空)以及函数体(function body)。

main函数的返回类型必须为int

在大多数系统中,main的返回值被用来指示状态。返回值0表明成功,非0的返回值的含义由系统定义,通常用来指出错误类型。

1.1.1 编译、运行程序

从命令行运行编译器

假定main程序保存在文件prog1.cc中,可以用如下的命令来编译它:

$ CC prog1.cc

其中,CC是编译器程序的名字,$是系统提示符。编译器生成一个可执行文件。Windows系统会将这个可执行文件命名为prog1.exe。UNIX系统中的编译器通常将可执行文件命名为a.out。

在Windows系统中运行可执行文件(可省略.exe):

$ prog1

在一些系统中,即使文件就在当前目录或文件夹中,也必须显示指出文件的位置。

$ .\prog1

"."后跟一个反斜线指出该文件在当前目录中

为了在UNIX系统中运行一个可执行文件,我们需要使用全文件名,包括文件扩展名:

$ a.out

如果需要指定文件位置:

$ ./a.out

访问main的返回值的方法依赖于系统。在UNIX和Windows系统中,执行完一个程序后,都可以通过echo命令获得其返回值。

在UNIX系统中,通过如下命令获得状态:

$ echo $?

在Windows系统中查看状态可键入:

$ echo %ERRORLEVEL%

运行GNU编译器:

$ g++ -o prog1 prog1.cc

-o prog1是编译器参数,指定了可执行文件的文件名。

1.2 初识输入输出

C++语言并未定义任何输入输出(IO)语句,取而代之,包含了一个全面的标准库(standard library)来提供IO机制(以及很多其他设施)。

本书中的很多示例都使用了iostream库。iostream库包含两个基础类型istreamostream,分别表示输入流和输出流。一个流就是一个字符序列,是从IO设备读出或写入IO设备的。术语“流(stream)”想要表达的是,随着时间的推移,字符是按顺序生成或消耗的。

标准输入输出对象

标准库定义了4个IO对象。为了处理输入,我们使用一个名为cin的istream类型的对象。这个也被称为标准输入(standard input)。对于输出,我们使用一个名为cout的ostream类型的对象。此对象也被成为标准输出(standard output)

标准库还定义了其他两个ostream对象,名为cerrclog。通常使用cerr来输出警告和错误消息,因此它也被称为标准错误(standard error)。而clog用来输出程序运行时的一般性信息。

一个使用IO库的程序

#include <iostream>
int main()
{
    std::cout << "Enter two numbers:" << std::endl;
    int v1 = 0, v2 = 0;
    std::cin >> v1 >> v2;
    std::cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << std::endl;
    return 0;
}

向流写入数据

main的函数体的第一条语句执行了一个表达式(expression)。在C++中,一个表达式产生一个计算结果,它由一个或多个运算对象和(通常是)一个运算符组成。这条语句中的表达式使用了输出运算符(<<)在标准输出上打印消息:

std::cout << "Enter two numbers:" << std::endl;

<<运算符接受两个运算对象:左侧的运算对象必须是一个ostream对象,右侧的运算对象是要打印的值。此运算符将给定的值写到给定的ostream对象中。输出运算符的计算结果就是其左侧运算对象。

这条输出语句使用了两次<<运算符。因为第一个运算符返回其左侧的运算对象,因此第一个运算符的结果成为了第二个运算符的左侧运算对象。

这样,我们就可以将输出请求连接起来。因此,我们的表达式等价于:

(std::cout << "Enter two numbers:") << std::endl;

链中每个运算符的左侧运算对象都是相同的,在本例中是std::cout。我们也可以用两条语句生成相同的输出:

std::cout << "Enter two numbers:";
std::cout << std::endl;

第一个输出运算符给用户打印一条消息。这个消息时一个字符串字面值常量(string literal),是用一对双引号包围的字符序列。

第二个运算符打印endl,这是一个被称为操纵符(manipulator)的特殊值。写入endl的效果是结束当前行,并将与设备关联的缓冲区(buffer)中的内容刷到设备中。缓冲刷新操作可以保证到目前为止程序所产生的所有输出都真正写入输出流中,而不是仅停留在内存中等待写入流。

从流读取数据

std::cin >> v1 >> v2;

输入运算符(>>)与输出运算符类似,它接受一个istream作为其左侧运算对象,接受一个对象作为其右侧运算对象。它从给定的istream读入数据,并存入给定对象中。与输出运算符类似,输入运算符返回其左侧运算对象作为其计算结果。因此,此表达式等价于:

(std::cin >> v1) >> v2;

本例中的输入操作从std::cin读入两个值,并将第一个值存入v1,将第二个值存入v2。它与下面两条语句的执行结果是一样的:

std::cin >> v1 
std::cin >> v2;

完成程序

std::cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << std::endl;

这条语句中运算对象并不都是相同类型的值,某些运算对象是字符串字面值常量,某些运算对象是int值,标准库定义了不同版本的输入输出运算符,来处理这些不同类型的运算对象。

1.3 注释简介

C++中注释的种类

C++中有两种注释:单行注释和界定符对注释。

单行注释以双斜线(//)开始,以换行符结束。这种注释可以包含任何文本,包括额外的双斜线。

另一种注释使用继承自C语言的两个界定符(/*和*/)。这种注释可以包含除*/外的任意内容,包括换行符。

注释界定符可以放置于任何允许放置制表符、空格符或换行符的地方。当注释界定符跨越多行时,最好能显示指出其内部的程序行都属于多行注释的一部分。我们所采用的风格是,注释内的每行都以一个星号开头,从而指出整个范围都是多行注释的一部分。

注释界定符不能嵌套

image-20221114142000096

1.4 控制流

1.4.1 while语句

while语句反复执行一段代码,直至给定条件为假为止。

while语句的形式为:

while(condition)
    statement

while语句的执行过程是交替得检测condition条件和执行关联的语句statement,直至condition为假时停止。

1.4.2 for语句

for语句包含两部分:循环头和循环体。循环头控制循环体的执行次数,它由三部分组成:一个初始化语句(init-statement)、一个循环条件(condition)以及一个表达式(expression)

1.4.3 读取数量不定的输入数据

#include <iostream>
int main()
{
    int sum = 0, value = 0;
    //读取数据直到碰到文件尾,计算所有读入的值的和
    while(std::cin >> value)
        sum += value;
    std::cout << sum << std::endl;
    return 0;
}

因为输入运算符会返回其左侧运算对象,while循环条件实际上检测的时std::cin。

当我们使用一个istream对象作为条件时,其效果是检测流的状态。如果流是有效的,即流未遇到错误,那么检测成功。当遇到文件结束符(end-of-file),或遇到一个无效输入时(例如输入的值不是一个整数),istream对象的状态会变为无效。处于无效状态的istream对象会使条件变为假。

从键盘输入文件结束符

当从键盘向程序输入数据时,对于如何指出文件结束,不同操作系统有不同的约定。在Windows系统中,输入文件结束符的方法是敲Ctrl+Z,然后按Enter或Return键。在UNIX系统中,包括Mac OS X系统中,文件结束符输入是用Ctrl+D。

1.4.4 if语句

与大多数语言一样,C++也提供了if语句来支持条件执行。与while语句类似,if也对一个条件进行求值,如果条件为真,则执行条件之后的语句块。

1.5 类简介

在C++中,我们通过定义一个类(class)来定义自己的数据结构。一个类定义了一个类型,以及与其关联的一组操作。类机制是C++中最重要的特性之一。实际上,C++最初的一个设计焦点就是能定义使用上像内置类型一样自然的类类型(class type)

1.5.1 Sales_item类

每个类实际上都定义了一个新的类型,其类型名就是类名。与内置类型一样,我们可以定义类类型的变量。

使用文件重定向

当测试程序时,反复从键盘敲入数据作为程序的输入是非常乏味的。大多数操作系统支持文件重定向,这种机制允许我们将标准输入和标准输出与命名文件关联起来:

$ addItems <infile> outfiles

假定$是操作系统提示符,addItems为已编译好的可执行文件addItems.exe(在UNIX中是addItems),则上述命令会从一个名为infile的文件读取数据,并将输出结果写入到一个名为outfile的文件中,两个文件都位于当前目录中。

1.5.2 初始成员函数

成员函数是定义为类的一部分的函数,有时也被称为方法(method)

我们通常以一个类对象的名义来调用成员函数。使用点运算符(.)来表示我们需要对象的成员。点运算符只能用于类类型的对象。其左侧运算对象必须是一个类类型的对象,右侧运算对象必须是该类型的一个成员名,运算结果为右侧运算对象指定的成员。

当用点运算符访问一个成员函数时,通常我们是想调用该函数。我们使用调用运算符(())来调用一个函数。调用运算符是一对圆括号,里面放置实参(argument)列表(可能为空)。

item1.isbn();

posted @ 2022-11-15 22:57  泠枫Jun  阅读(43)  评论(0编辑  收藏  举报