第一章 开始
学习一门新的程序设计语言的最好方法就是练习编写程序。
编写一个简单的C++程序
每个C++程序都包含一个或多个函数(function),其中一个必须命名为main。操作系统通过调用main来运行C++程序。
下面是一个简单的main函数,它什么都不做,只是返回给操作系统一个值:
int main()
{
return 0;
}
main函数的返回类型必须为int。int类型是一种内置类型(built-in type),即语言自身定义的类型。
函数体是一个以左花括号(curly brace)开始,以右花括号结束的语句块(block of statements)。
return语句结束函数的执行。main的返回值被用来指示状态。返回值0表明成功,非0的返回值的含义由系统定义,通常用来指出错误类型。
重要概念:类型
一种类型不仅定义了数据元素的内容,还定义了这类数据上可以进行的运算。程序所处理的数据都保存在变量中,而每个变量都拥有自己的类型。
编译、运行程序
编写好程序后,我们就需要编译它,这依赖于操作系统和编译器。
程序源文件命名约定
程序文件通常被称为源文件(source file)。它以一个后缀为结尾,告诉系统这个文件是一个C++程序,比如.cpp。
初识输入输出
C++包含了一个全面的标准库(standard library)来提供IO机制(以及很多其他设施)。
iostream库包含两个基础类型istream和ostream,分别表示输入流和输出流。一个流就是一个字符序列,是从IO设备读出或写入IO设备的。
标准输入输出对象
标准库定义了4个IO对象。为了处理输入,使用名为cin的istream类型的对象。这个对象被称为标准输入(standard input)。对于输出,使用名为cout的ostream类型的对象。这个对象被称为标准输出(standard output)。另外还有其他两个ostream对象,名为cerr和clog,cerr通常用来输出警告和错误消息,因此被称为标准错误(standard error)。clog用来输出程序运行时的一般性消息。
系统通常将程序所运行的窗口与这些对象关联起来。因此,当读取cin,数据将从程序正在运行的窗口读入,当向cout写入数据时,将会写到同一个窗口。
Note
clog关联到标准错误,默认情况下,写到clog的数据是被缓冲的。写到cerr的数据是不缓冲的。
一个使用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;
}
#include <iostream>
告诉编译器我们想要使用iostream库。尖括号中的名字指出了一个头文件(header)。每个使用标准库设施的程序都必须包含相关的头文件。#include指令和头文件的名字必须写在同一行中。#include指令一般出现在所有函数之外,源文件的开始位置。
向流写入数据
std::cout << "Enter two numbers" << std::endl;
这条语句执行了一个表达式(expression)。在C++中,一个表达式产生一个计算结果,它由一个或多个运算对象和(通常是)一个运算符组成。这条语句中的表达式使用了输出运算符(<<)。
<<
运算符接受两个运算对象:左侧必须是一个ostream对象;右侧是要打印的值。此运算符将给定的值写到给定的ostream对象中。计算结果是左侧的ostream对象。
"Enter two numbers"是一个字符串字面值常量(string literal),它是用一对双引号包围的字符序列。
endl是一个被称为操纵符(manipulator)的特殊值。写入endl的效果是结束当前行,并将与设备关联的缓冲区(buffer)中的内容刷到设备中。
Note
一个表达式接一个分号就是一条语句。
使用标准库中的名字
前缀std::指出名字cout和endl是定义在名为std的命名空间(namespace)中的。
命名空间可以帮助我们避免不经意的名字定义冲突。标准库定义的所有名字都在命名空间std中。
从流读取数据
首先定义两个名为v1和v2的变量(variable)来保存输入:
int v1 = 0, v2 = 0;
这两个变量被定义为int类型,并初始化(initialize)为0。初始化一个变量,就是在变量创建的同时为它赋予一个值。
std::cin >> v1 >> v2;
这条语句读入输入数据。输入运算符(>>)接受一个istream作为其左侧运算对象,接受一个对象作为其右侧运算对象。它从给定的istream读入数据,并存入给定对象中。输入运算符返回其左侧运算对象作为计算结果。
注释简介
注释(comments)通常用于概述算法,确定变量的用途,或者解释晦涩难懂的代码段。编译器会忽略掉注释,因此注释对程序的行为和性能不会有任何影响。
C++中注释的种类
C++中有两种注释:单行注释和界定符注释。
注释界定符不能嵌套
界定符对形式的注释是以/*
开始,以*/
结束的。因此,一个注释不能嵌套在另一个注释之内。
如果在调试期间要注释掉包含界定符对形式注释的代码,最好的方式是用单行注释方式注释掉代码段的每一行。
// /*
// * comments
// */
控制流
语句一般是顺序执行的,语句块的第一条语句首先执行,然后是第二条,以此类推。但程序设计语言提供了多种不同的控制语句,允许我们写出更为复杂的执行路径。
while语句
while语句反复执行一段代码,直到给定条件为假为止。
while语句的形式为:
while (condition)
statement
while语句的执行过程是交替地检测condition条件和执行关联的语句statement,直至condition为假时停止。所谓条件就是一个产生真或假的结果的表达式。
statement可以是语句块,也叫循环体。所谓语句块(block),就是用花括号包围的语句序列。语句块也是语句的一种,在任何要求使用语句的地方都可以使用语句块。
for语句
每个for语句都包含两部分:循环头和循环体。循环头控制循环体的执行次数,它由三部分组成:一个初始化语句(init-statement)、一个循环条件(condition)以及一个表达式(expression)。
比如:
for (int val = 1; val <= 10; ++val)
sum += val;
for循环的总体执行流程:
-
创建变量val,将其初始化为1,它仅在循环内部存在。
-
检测val是否小于等于10。如果检测成功,执行循环体。若失败,退出循环。
-
将val的值增加1。
-
重复第二个步骤。
读取数量不定的输入数据
使用这样的方法连续读入数据,直到遇到文件尾(Linux下,输入CTRL+D):
while (std::cin >> value)
statement
输入运算符返回其左侧对象,因此,此循环条件检测的是std::cin。
当使用一个istream对象作为条件时,其效果是检测流的状态。如果流是有效的,那么检测成功。当遇到文件结束符(end-of-file),或遇到一个无效输入时,istream对象的状态会变为无效。
if语句
if也对一个条件求值,书本里有一个完整的例子。
语法大致如此:
if (condition) {
statements
} else {
statements
}
类简介
在C++中,通过定义一个类(class)来定义自己的数据结构。一个类定义了一个类型,以及与其关联的一组操作。
类似使用标准库设施,我们也需要使用头文件来自己的类。习惯上,头文件根据类名来命名,使用.h作为头文件的后缀。标准库的头文件通常不带后缀。
初识成员函数
什么是成员函数?
有这样的检测条件:
item1.isbn() == item2.isbn()
调用名为isbn的成员函数(member function)。成员函数是定义为类的一部分的函数。
使用点运算符(.)来表达我们需要“名为item1的对象的isbn成员”。点运算符只能用于类类型的对象。其左侧运算对象必须是一个类类型的对象,右侧运算对象必须是该类型的一个成员名,运算结果为右侧运算对象指定的成员。
我们使用调用运算符(())来调用一个函数,它是一对圆括号,里面放实参列表(可能为空)。