C++ primer 读书笔记
第一章
-
STL( standard library)是c++最常用的标准库
-
命名空间可以帮助我们避免不经意的名字定义冲突,以及使用库中相同名字导致的冲突。
-
c++ 的注释为 /* ~~~ */ ,但是为了方便,每一行开头都加上星号。另一种注释为 // 一般用于单行注释
-
在c++中,通过定义一个类来定义自己的数据结构,一个类定义了一个类型以及相关联的一组操作。类特性是c++最重要的特性之一。
-
成员函数
- 成员函数是定义为类的一部分函数,有时候也被称为方法。
- item.isbn() 名为item的对象的 isbn 成员
第二章
2.1 内置基本类型
-
大多数计算机以2的整数次幂个比特作为块来处理内存,可寻址的最小内存块成为 字节(byte) ,存储的基本单元称为 字(word) 通常由几个字节组成,
-
c++中,一个字节要能至少容纳机器基本字符集中的字符,大多数机器的字节由8比特构成。字则由32或64比特构成,也就是4或8字节。
-
符号类型
-
带符号(signed) 可以表示正数,负数,0 无符号(unsigned) 表示大于等于0的值。
-
int, short long ,long long都是带符号的。但是可以通过前面加 unsigned 可以变成无符号类型
-
字节型符号有三种:char、signed char、unsigned char。具体含义看编译器所以不安全。一般要人为指定。
-
不同数据类型会影响运算速度。所以程序员应该尽可能明确的指定变量的数据类型。
-
程序可以完成类型转换。例如将 0 转化为 true ,但是这样会依赖环境和编译器。并不建议使用
-
切记混用带符号类型和无符号类型。因为带符号数回自动的转化为无符号数。从而影响程序运行。
-
字符 和 字符串 字面值。 字符:"A", 字符串:"hello world",字符串实际上一个数组(array)。在末尾有一个空字符作为转义符。
-
2.2 变量
-
声明和定义
-
声明(declaration) 使得名字为程序所知道,一个文件如果想使用别处定义的名字,则必须包含对那个名字的声明
-
定义(definition) 创建与名字关联的实体
-
声明只是让程序知道这个名字,定义则会开辟一块内存空间,或者赋一个初始值,定义只能出现在一个文件中,但是声明可以在多个地方
-
-
作用域
-
一般是指一个函数或者变量作用的地方。通常以花括号为分割。
-
同一个名字在不同的作用域中可能指向不同的实体
-
建议在使用变量的附近定义变量,能够规避作用域冲突的问题。
-
嵌套作用域: 作用域中一旦声明了某个名字,则所有嵌套的作用域都能访问。同时也允许内层作用域中重新定义已有的名字
-
2.3 复合类型
-
引用(reference)
-
int ival = 1024; int &refVal = ival; // refVal 指向了 ival -
引用是为对象起了另一个名字。通常用 &d 来定义。 d 是变量名
-
引用必须被初始化 因为定义引用的时候,是将 引用 初始值绑定在一起,而不是 拷贝 一份。如果没有初始化就没有初始值。没得绑
-
引用只是名字不是对象。不可有 引用的引用
-
-
指针(pointer)
-
int *ip1, *ip2; // ip1是int型指针 int ival=42; int *p = &ival; // p存放ival的地址, p是指向ival的指针。 -
指针和引用类似但是并不相同
- 指针本身也是对象,可以赋值和拷贝,所以有 指针的指针 这种操作。
- 指针定义的时候可以不用赋初值,同样不初始化也会有一个不确定的值。
- 一般来说指针是存放变量的地址,所以用 & 取址符来得到变量的地址。
-
指针的状态
- 指向一个对象
- 指向紧邻对象所占据空间的下一个位置
- 空指针,没有指向任何对象
- 无效指针,其他情况
-
利用指针访问对象
-
与取址符对应的是 解引用符(*)
-
int a = 42; int *p = &a; // 指针p, 存放着变量 a 的地址 cout << *p; // 由解引用符 * , 解析指针的地址找到变量a,输出a的址。 -
// & 和 * 的多重含义 int i = 42; int &r = i; // & 紧随着类型名出现,r是一个引用 int *p; // * 紧随这类型名出现,p是一个指针 p = &i; // & 出现在表达式中,是一个取址符 *p = i; // * 出现在表达式中,是一个解引用符 int &r2 = *p; // & 是生命的一部分, *是一个解引用符
-
-
空指针
-
int *p = nullptr; //c++11 新引入 int *p2 = 0; // p2被初始化,但是没有指向任何对象 -
指针一定要初始化。最好先定义了变量再定义它的指针,最次也要是定义为空。 不要她成为野指针,不然内存有东西会让人很苦恼
-
-
void*
- 是一个特殊的空指针。只代表一个内存对象,不清楚内存里的数据是什么类型
-
2.4 const限定符
-
常量的定义 const int i = 2
-
默认情况下,const对象被设定仅在文件内有效。当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。
如果想在多个文件之间共享const对象,必须在变量的定义之前添加 extern 关键字
-
指针和const
-
如果想定义一个 指向常量的指针(pointer to const) ,只能使用常量指针
-
const double pi = 3.14; double *ptr = π // 错误:ptr只是一个普通的指针 const double* cptr = π // 正确: cptr也是个常量指针 double* const cur = π // cur一直指向pi constexpr int *q = a // constexpr 限定符只对指针有效 // 疑惑 上面两句有什么区别呢
-
-
顶层const TODO
-
// TODO
2.5 处理类型
-
类型别名:让复杂的类型起一个简单的名字。有两种写法
-
// 传统方法 typedef typedef doubel wages; // wages 是 doubel 都同义词 typedef wages base, p; // base 是 double 的同义词,p 是 double* 的同义词 // 新标准方法 别名声明 using using SI = Sales_item; // SI 是 Sales_item 的同义词
-
-
auto类型
- 让编译器决定一个变量的类型
- TODO:留着进阶 第二遍的时候再看
-
decltype 类型指示符:希望从表达式的类型推断出要定义的变量的类型。但是不想用该表达式的值初始化变量
decltype(f()) sum = x; // sum的类型就是函数 f 的返回类型- TODO:留着进阶
2.6 自定义数据结构
-
定义 Sales_data 类型
-
struct Sales_data{ std::string bookNO; unsigned units_sold = 0; double revenue = 0.0; }; Sales_data accum, trans, *saplesptr;
-
-
使用 Sales_data 类
-
编写自己的头文件
- 一般不在函数体内定义类,而是在函数体外。
- 类通常被定义在头文件中,且头文件的名字应该与类名一样
- 头文件通常包括那些只被定义一次的实体。如 类、const、constexpr等
- 头文件之间可以互相包含
-
预处理器
- 头文件保护符,用于解决多次重复包含的问题
- #defin 和 #ifdef TODO:进阶内容
第三章:字符串、向量和数组
3.1 命名空间的using声明
-
使用不同命名空间的一种方法 using
-
using namespace std; // from std import * using std::cin; // from std inmport cin -
头文件不应该包含 using 声明,头文件的内容会拷贝到所有引用他的文件中去。
3.2 标准库类型 string
-
string 表示可变长的字符序列。
-
定义和初始化 string 对象。 string是一个类,实例一个string有多种方式
-
string 对象上的操作
-

-
使用 getline 读取一整行。使用ciny读取时遇到空格就停止了,getline遇到换行符才停止
-
string line; // 实例化一个string对象 line line.size(); // 返回 line 的长度 line::size_type // 疑问 -
string 比较
-
string 赋值
-
string 相加
-
字面值和 string 对象相加
-
字面值和string可以想加,因为c++自动转化了类型。但是字面值和字面值不能想加。为了兼容c,字面值不是string类型
-
string s1 = "hello", s2 = "world"; string s3 = s1 + "," + s2 + "\n"; // 当string和字符字面值相加时,确保每个加号(+)两侧运算对象至少一个是string string s4 = s1 + ","; // 正确 string s5 = "hello" + ","; // 错误 string s6 = s1 + "," + "world"; //正确 string s7 = "hello" + "," + s2; // 错误 -
如何处理 string 中的每个字符?
-
for (declaration : expression) statement // expression 是一个对象,表示一个序列。 // declaration 定义一个变量,用于访问序列中的基础元素 string str("hello world!"); for (auto c : str) cout << c << endl;
-
-
! 使用for语句改变字符串中的字符
-
我们想改变字符串中的值,要把循环变量定义成引用类型才行。引用则意味着这个变量被绑定到了序列的每个元素上。
-
string str("hello world"); for (auto &c : s) c = toupper(c); cout << s << endl;
-
-
部分字符 下标运算符([ ]) eg: str[0]。必须大于0,小于s.size() 不然会超出内存
-
浙公网安备 33010602011771号