开始
源程序文件命名约定
程序文件通常被称为源文件
(source file)。不同编译器使用不同的后缀命名C++程序,最常见的包括:.cc
、.cxx
、.cpp
、.cp
和.C
。
使用命令运行编译器
$ CC prog1.cc
——
CC
是编译器的名字,$
是系统提示符。编译器生成一个可执行文件。
- Windows系统会将这个可执行文件命名为 prog1.exe
- Unix系统中的编译器会将可执行文件命名为 a.out
- 访问 main 的返回值的方法都依赖于系统。在 UNIX 和 Windows 系统中,执行完一个程序后,都可以通过 echo 命令获得其返回值。
- 在UNIX系统中,使用
$ echo $?
- 在Windows系统中,使用
$ echo %ERRORLEVEL%
输入输出
C++并没有定义任何输入输出(IO)语句,取而代之包含了一个全面的标准库
(standard library)来提供IO机制(以及很多其他设施)。
iostream库包含两个基础类型,istream
和 ostream
,分别表示输入流和输出流。
标准输入输出对象
标准库定义了4个IO对象。
- 使用了一个名为
cin
的istream类型的对象,这个对象被称为标准输入(standard input) - 使用了一个名为
cout
的ostream类型的对象,这个对象被称为标准输出(standard output) cerr
来输出警告和错误信息clog
来输出程序运行时的一般性信息
使用IO库的程序
// 告诉编译器要使用iostream库,<>表示是头文件
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
/* endl,这是一个被称为操纵符的特殊值。写入endl的效果是结束当前行,并将于设备关联的缓冲区(buffer)中的内容刷到设备中。
缓冲刷新操作可以保证到目前为止程序所产生的所有输出都真正写入输出流中,而不是仅停留在内存中等待写入流。
使用标准库中的名字,命名空间(namespace)可以帮助我们避免不经意的名字冲突,以及使用库中相同名字导致的冲突。 */
std::cout << "The sum of" << v1 << " and " << v2
<< " is " << v1 + v2 << std::endl;
return 0;
}
注释界定符不能嵌套
两种注释方式:
- 单行注释 //
- 注释界定符 /* */
for 和 while,两种循环形式的优缺点
- for循环更适用于循环次数已知的情况。
- while循环比较适用于循环次数不易预知的情况。
- 但它们在功能上是等价的,可以相互转换。
读取数量不定的输入数据
#include <iostream>
int main()
{
int sum = 0, value = 0;
// 读取数据直到遇到文件尾,计算所有读入的值的和
while (std::cin >> value)
sum += value; // 等价于 sum = sum + value
std::cout << "Sum is :" << sum << std::endl;
return 0;
}
从键盘输入文件结束符
- windows:
Ctrl + Z
- UNIX:
Ctrl + D
常见的错误类型
- 语法错误(syntax error)
- 类型错误(type error)
- 声明错误(declaration error):两种常见的错误:1. 对来自标准库的名字忘记使用std::、2. 标识符名字拼写错误
类简介
类机制是C++中最重要的特性之一。在C++中,我们通过定义一个类(class)来定义自己的数据结构。
实际上,C++最初的设计焦点就是能定义使用上像内置类型一样自然的类类型(class type)。
为了使用类,我们需要了解三件事情:
- 类名是什么?
- 它是在哪里定义的?
- 它支持什么样的操作?
下面通过一个简单的例子来解决这些问题:
对于一个书店程序来说,我们假定类名为Sales_item
,在头文件Sales_item.h
中定义这个类。
如此可见,为了使用标准库设施,我们必须包含相关的头文件。类似的,我们也需要使用头文件来访问自己的应用程序所定义的类。习惯上,头文件根据其中定义的类的名字来命名。我们通常会使用.h
作为头文件的后缀,但也有一些程序猿习惯使用.H
、.hpp
、.hxx
。标准库头文件通常不带后缀。编译器一般不关心头文件名的形式,但有的IDE对此有特殊的要求。
如:Sales_item类
Sales_item类的作用是表示一本书的总销售额、售出册数和平均售价。
每个类实际上都定义了一个新的类型,其类型名就是类名。因此,我们的Sales_item类定义了一个名为Sales_item的类型。与内置类型一样,我们可以定义类类型的变量。
Sales_item item;
定义了一个Sales_item类型的变量之后,我们还可以:
- 提取其中的ISBN书号
- 用输入
>>
、输出<<
运算符,来读写该对象 - 使用复制运算符
=
将一个Sales_item类型的值赋予给另一个Sales_item类型对象 - 用加法运算符
+
将两个Sales_item对象相加,这两个对象必须是表示同一本书(相同的ISBN)。加法运算的结果就是一个新的Sales_item对象,其ISBN与两个运算对象相同,而其总销售额和售出册数则是两个运算对象的对应值之和。
使用#include "Sales_item.h"
来引入自定义的类。
文件重定向
$ addItems <infile > outfile
- $ 是操作系统的提示符,我们加法程序已经编译为名为addItems.exe的可执行文件,则上述命令会从一个名为
infile
的文件中读取销售记录,并将输出结果写入到一个名为outfile
的文件中,两个文件都位于当前目录中。
成员函数
item1.isbn()
- 调用isbn的成员函数(member function)。成员函数是定义为类的一部分的函数,有时也被称为方法(method)。
- 通过点运算符号(.)调用。