本文为《C++ Primer》的读书笔记
C++ 源文件、头文件
- 源文件的后缀名可以为:
.cc
,.cxx
,.cpp
,.cp
- 标准库头文件一般不带后缀
- 建议:使用 C++ 版本的 C 标准库头文件
- C++标准库中除了定义C++语言特有的功能外,也兼容了C语言的标准库。C语言的头文件形如
name.h
,C++ 则将这些文件命名为cname
。也就是去掉了.h
后缀,而在文件名name
之前添加了字母c
, 这里的c
表示这是一个属于C语言标准库的头文件- 例如,
cctype
头文件和ctype.h
头文件的内容是一样的,只不过从命名规范上来讲更符合 C++ 语言的要求
- 例如,
- 特别的,在名为
cname
的头文件中定义的名字从属于命名空间std
, 而定义在名为.h
的头文件中的则不然
(如果引用name.h
头文件,则不需要使用using
声明或using
指示 也可以直接使用该头文件的名字) - 一般来说,C++程序应该使用名为
cname
的头文件而不使用name.h
的形式
- C++标准库中除了定义C++语言特有的功能外,也兼容了C语言的标准库。C语言的头文件形如
输入输出(IO)
- C++提供了
iostream
库来提供IO机制 iostream
库包含两个基础类istream
和ostream
,分别表示输入流和输出流。一个流就是一个字符序列,是从IO设备读出或写入IO设备的
标准输入输出对象
标准库定义了4个IO对象
- 标准输入(standard input):
istream
类的对象cin
- 标准输出(standard output):
ostream
类的对象cout
- 标准错误(standard error):
ostream
类的对象cerr
- 输出程序运行时的一般性信息:
ostream
类的对象clog
- 默认情况下, 写入到
clog
的数据是被缓冲的。clog
通常用于报告程序的执行信息, 存入一个日志文件中
- 默认情况下, 写入到
向流写入数据
std::endl
:被称为操纵符(manipulator)- 向
ostream
类型的对象写入endl
的效果是结束当前行,并将与设备关联的缓冲区(buffer)中的内容刷到设备中(读cin
/ 程序非正常终止 也会刷新cout
)
- 向
- 输出运算符
<<
<<
运算符接受两个运算对象:左侧的运算对象必须是一个ostream
对象,右侧的运算对象是要打印的值。此运算符将给定的值写到给定的ostream
对象中- 输出运算符的计算结果就是其左侧运算对象。因此输出语句可以连续使用
<<
将输出请求连接起来:std::cout << "Hello" << std::endl;
- 注意
cout
首先按从右向左的顺序计算出各输出项的值,然后再输出各项的值
int i = 10;
cout << i << "," << i++ << "," << i++; // output: 12,11,10
- 当向
cout
写入char
类型的变量时,cout
实际的执行结果是打印对应的ASCII码字符
unsigned char c = 0x31;
std::cout << c << std::endl; // output: 1
- 也可以直接输出字符数组:
char s[20]{"This is a string."}
cout << s;
从流读取数据
- 输入运算符
>>
- 接受一个
istream
作为其左侧运算对象,接受一个对象作为其右侧运算对象。它从给定的istream
读入数据,并存入给定对象中 - 与输出运算符类似,输入运算符返回其左侧运算对象作为其计算结果。因此,输入语句可以连续使用
>>
将输入请求连接起来:std::cin >> v1 >> v2;
- 接受一个
- 当我们使用一个
istream
对象作为条件时, 其效果是检测流的状态- 如果流是有效的, 即流未遇到错误,那么检测成功
- 当遇到文件结束符 (end-of-file), 或遇到一个无效输入时(例如右侧运算对象为
int
但读入的值不是一个整数) 时,istream
对象的状态会变为无效。 处于无效状态的istream
对象会使条件变为假。因此可用while (std::cin >> val)
来一直读取输入
在Windows系统中,文件结束符是敲Ctrl+Z。在UNIX系统中,文件结束符是Ctrl+D
int val;
int sum = 0;
while (std::cin >> val)
{
sum += val;
}
std::cout << "The sum is " << sum << std::endl;
// 字符数组作为一个特例,可以直接以数组为单位进行输入输出操作
char s[20];
cin >> s; // 读入字符串,存入字符数组
cout << s; // 输出字符数组中的字符串
文件重定向
$ Project1 <infile.txt >outfile.txt
变量
列表初始化
C++支持以下4种变量初始化方式
int u1 = 0;
int u2 = {0};
int u3{0};
int u4(0);
用花括号来初始化变量称为列表初始化
- 当用于内置类型的变量时,如果我们使用列表初始化且初始值存在丢失信息的风险,则编译器将报错:
double a = 3.14;
int b{a}; //编译器报错
int c(a); //正确
默认初始化
- 定义在任何函数体外的变量会被初始化为0
- 定义在函数体内部的变量不会被初始化
- 类的对象未被初始化,则初值由类决定
下面例子中的local_str
因为是std::string
类,因此未被初始化时,初值为空字符串
int main(int argc, char *argv[])
{
std::string local_str;
return 0;
}
标识符
- 由字母、数字和下划线组成,且必须以字母或下划线开头。
- C++为标准库保留了一些名字:用户自定义的标识符中不能连续出现两个下划线,也不能以下划线紧连大写字母开头。此外,定义在函数体外的标识符不能以下划线开头