"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调用。

 

  

posted @ 2019-06-06 10:29  LiaoQian1996  阅读(124)  评论(0编辑  收藏  举报