"C++ Primer"读书笔记 第五章 表达式
- 操作数、操作符表达式的概念;每个表达式总要返回一个结果,且结果是一个右值
- 二元操作符作用于一对操作数,要求两个操作数的数据类型相同,或者可以被强制转换为相同类型
- 位操作符将整型操作数看作是二进制数的集合
~ 位求反
<< >> 左移/右移
& ^ | 按位与/异或/或
int型有32位bit,因此可以用一个int变量存储长度为32的bool hash map,但更建议用标准库<bitset>对一系列二进制位进行操作
#include<iostream> #include<bitset> #include<vector> using namespace std; int main(){ vector<int> res = {0,2,8,10,19,30,31}; bitset<32> a; unsigned long b = 0; for(int i = 0; i < res.size(); i++){ a.set(res[i]); b = b | 0x1U << res[i]; // 将相应位上设为1 } for(int i = 0; i < 32; i++){ cout << a[i] << ' '; } cout << endl; for(int i = 0; i < 32; i++){ cout << (b >> i)%2 << ' '; } system("pause"); return 0; }
- 自增/自减操作符通常前置, ++i(返回自增之后的值)而不是i++
- sizeof也是操作符,将sizeof应用到表达式上,将返回表达式的结果的类型的字节长度
- char类型返回1
- 对引用类型返回引用的对象的大小
- 注意数组的sizeof结果与元素个数有关,而vector的sizeof结果与元素个数无关
#include<iostream> #include<vector> using namespace std; class my_class0{ }; class my_class1{ public: int num; vector<int> li; }; int main(){ int a = 1; long b = 2; int &c = a; cout << sizeof(1) << endl; // 4 cout << sizeof(a) << endl; // 4 cout << sizeof(b) << endl; // 4 cout << sizeof(&a) << endl; // 8 cout << endl; vector<int> d; cout << sizeof(d) << endl; // ? d.push_back(1); cout << sizeof(d) << endl; // ? d.push_back(1); cout << sizeof(d) << endl; // ? cout << endl; cout << sizeof(my_class0) << endl; // ? cout << sizeof(my_class1) << endl; // ? system("pause"); return 0; }
-
sizeof(vector<int>)为什么是24?32?
一个指针代表vector开始位置,两个指针分别表示capacity与size,还有一个Allocator对象
- new/delete表达式动态创建/释放对象
- 隐式类型转换通常向更宽的类型转换/转换为左操作数的类型
- 不建议使用强制类型转换
第六章 语句
首先我们回顾一下const关键字与指针。通常,使用const限定符表示这个对象一经初始化就不被修改,只能访问。
// 指向const对象的指针。即指针指向的地址可以改变,但解引用后的值不能改变 const double *ptr; // const指针,指针本身不能被修改 double *const ptr = &double_num; // 既然是const量,必然需要初始化
关于语句,需要注意这么些:
- 单个分号;作为空语句需要注释
- switch语句注意加break语句,否则代码会执行满足某个case之后所有的代码(包括其他case)
- 不建议使用goto语句
- 了解异常处理,throw, try, catch与标准异常
使用预处理器进行调试
我们已经了解了如何用预处理变量写头文件保护符,避免重复包含头文件。开发阶段我们希望程序能够输出调试信息,而发布版本关闭调试部分代码,用#ifndef NDEBUG预处理语句可以方便地实现这样的功能。
利用带参数的预处理宏,以及__FILE__,__LINE__等内置宏可以打印程序运行中的调试信息和异常信息。assert宏用于调试,检测一个表达式,如果为false,则输出错误信息并终止程序运行;加#define NDEBUG可以禁止assert调用。