Accelerated C++笔记
第0章
- cout:标准输出流 cin:标准输入流
- namespace(名字空间):其实就是为了方便重复使用变量名,给变量名设置的前缀
- 标准库由很多个部分组成,如:iostream、string。标准库的名字空间即为std(standard)
第1章
- <<和>>都是左结合
- 初始化一个变量时,变量名后面跟着一对“()”,“()”中包含若干个表达式。这种初始化方式实际上相当于调用了构造方法,然后再给变量赋值。例如:std::string spaces(10, ‘*’),这里相当于调用了string的构造器,传入两个参数,生成对象,然后赋值给spaces。另外string的这个构造方法中的第二个参数只能是字符,而不可以是字符串
- 假设is是输入流,s是字符串,is>>s,从is中读取到的字符会覆盖s中已有的字符
- std::cin >> v表达式会忽略标准输入流最开始的空白字符
- std::cin >> v 返回cin,std::cout << v 返回cout
第2章
- std::string::size_type size; 这里声明了一个名为size的变量,该变量的类型为std::string::size_type,这里std相当于Java的包名,string相当于Java的类名,size_type相当于Java的内部类(可以理解为size_type的外部类为string)。之所以用size_type定义size,而不使用int或long,是因为int或long的可存储的长度是有限的。size_type是C++为string定义的可以存储任意字符串长度的类。如果我们想保存特定数据结构的大小,就应该使用库为其准备的类型。
- 如果一个using出现在花括号中,那么它定义的名称的作用域会从定义的地方开始,到对应的结束花括号处结束。
- 算数值可以被转换成布尔值:0值可以被看成是false,其它值可以被看成是true
第3章
- 如果两个以上的字符串直接量仅仅是被空白符分割开的话,那么这些字符串直接量会被自动连接在一起。如下:
cout << "A""B"
等价于cout << "AB"
- 内部类型的局部变量如果没有被明确初始化的话,那么C++系统就会为它赋值一个随机值
- 头文件<ios>定义了一个类型
streamsize
,输入/输出库用这个类型表示精度(即有效位数) - 通过使用
setprecision
,我们可以改变出现在cout
中所有后继输出的精度 - 下面两段代码是等价的:
streamsize prec = cout.precision();
cout << setprecision(3) << 3.1415926 << setprecision(prec) << endl;
//设置精度为3,并返回原先的精度
streamsize prec = cout.precision(3);
cout << 3.1415926 << endl;
cout.precision(prec);
以下这两段代码也是等价的:
if(cin >> x){/** ...**/}
cin >> x;
if(cin){/**...**/}
用cin作为条件等价于检测最近的一次从cin读取数据是否成功。
在以下情况中,我们从流读取数据会以失败告终:
- 已经到了输入文件的结尾
- 我们碰到的输入与我们试图读取变量类型不一致;例如:我们想读一个整数,但是实际读取到的却不是一个整数
- 在输入装置中检测到一个硬件问题
一旦我们不能从流中成功读到数据,那么接下来所有从流中读数据的尝试都会以失败告终,除非我们重置了流。
6. 以下代码运行时,若输入连续的回车键,并不会跳出循环,因为这些回车键被视为输入最开始时的空白字符而被忽略掉。
while(cin >> x){
...
}
- typedef可以为指定类型设置一个代替名,例如:
vector<double> test;
typedef vector<double>::size_type vec_sz;
vec_sz size = test.size();
上述代码中vec_sz就相当于vector<double>::size_type
。所以与下面的代码是等价的:
vector<double> test;
vector<double>::size_type size = test.size();
其中size_type是用来表示vector的元素个数的类型。
8. sort函数定义在头文件<algorithm>
中,它把容器中的数据重新排序成非递减序列。
9.
#include <vector>
int main(){
vector<double> test;
test.push_back(3.1415926);
test.begin();//返回一个数值,这个数值指示了vector的第一个元素
test.end();//返回一个数值,这个数值指示了紧跟在vector的最后一个元素之后的位置
}
10.所有标准库的长度类型都是无符号整数类型。当普通整数与无符号整数在表达式中结合在一起时,普通整数就会被转换成无符号整数。因此,诸如vector.size()-100这样的表达式将产生无符号的结果,这也意味着结果不可能小于0——即使vector.size()<100。
第4章
- 以下代码是不合法的:
const vector<double>& vec1;
vector<double>& vec2 = vec1;
因为之前我们已经保证了不会去改变vec1的值,vec2 = vec1
相当于向vec1请求写访问。 - 如果某个函数的参数类型为
const vector<double>&
,那么该参数既可以接受常量也可以接受变量。 - 头文件
<stdexcept>
中定义的异常domain_error相当于“非法参数异常”。 - C++的函数不允许返回局部变量的地址和引用。
关于引用:
引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。C++的引用VS指针
- 不存在空引用。引用必须连接到一块合法的内存。
- 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
- 引用必须在创建时被初始化。指针可以在任何时间被初始化。
其中“引用是某个已存在变量的另一个名字”,规定了下面代码不合法:
void bar(string & s); bar("hello world");//这里的“hello world”是字符串常量,不是某个变量,所以这样传参,参数s无法成为某个变量的别名
“不存在空引用”规定了下面代码不合法:
string foo( ); void bar(string & s); bar(foo( ));//C++中函数的返回值是一个临时变量,这个临时变量会在函数执行结束后被销毁。这样传参,参数s即为函数foo返回的临时变量的别名,但是临时变量下个瞬间就会被销毁,导致s成为了“无所指”的引用。
如果改成这样就合法了:
string foo( ); void bar(string & s); string r = foo();//将函数foo返回的临时变量赋值给一个新的变量 bar(r);
setw可以设置下一个输出项的字符长度,当实际输出的字符数不满足该长度时,就往输出项前补空格来完成。
- 7.