C++ Primer 第三版 读书笔记

时间:2022-07-29 04:18:52


前言

  《C++ Primer》第三版这本书还是去年做Window Mobile 6开发时看完的,看完后做了一些笔记到本子后就没管了。今天偶尔翻出来赶紧写一篇文章备份一下,据说每次重读这本书都有新的收获,正所谓温故而知新,可见这本书之经典。

 

声明

  欢迎转载,但请保留文章原始出处:)

    博客园:http://www.cnblogs.com

    农民伯伯: http://over140.cnblogs.com

 

正文

 

  1.  如果一个变量是在全局定义的,系统会保证给它提供初始化值0。如果变量是局部定义的,或是通过new表达式动态分配的,则系统不会向它提供初始值0

 

  2.  一般定义指针最好写成:" string *p; " 而不是 " string* p; "

 

  3.  试图将一个非const对象的指针指向一个常量对象的动作将引起编译错误

 

  4.  引用类型主要作用于函数的形式参数  P/89

 

  5.  枚举成员的值不必唯一

  

  6.  一个数组不能被另外一个数组初始化,也不能被赋值给另一个数组。而且,C++不允许声明一个引用数组(即由引用组成的数组)  P/95

 

  7.  volatile修饰符的主要目的是提示编译器,该对象的值可能在编译器未检测到的情况下被改变,因此编译器不能对引用这些对象的代码作优化处理。

 

  8.  逗号表达式的结果是最右边表达式的值(从左向右)  P/135

 

  9.  关于位操作符的详细介绍和使用方法参见P/136,讲得很透彻

 

  10.  容器

    10.1  关联容器

      10.1.1  map  P/247

        "键/值"对:键用来索引map,而值用来存储数据。

        插入单个元素最好用insert(不使用下标方式)   P/248 - P/249

      10.1.2  set  P/256

      10.1.3  比较  P/247

        如果只想知道一个值是否存在时,用set最有用,希望存储(也可能修改)一个相关的值时,map最有用

    10.2  顺序容器

      10.2.1  list

        非连续内存区域,允许双向遍历,插入、删除效率高,对随机访问支持不好,需要遍历,且每个元素有两个指针的额外空间开销。

      10.2.2  vector

        表示一段连续的内存区域,每个元素被顺序存储在这段内中。随机访问效率很高,但是插入、删除效率低(除非是最后一个元素),右边的元素都要重新拷贝一次。(deque也是一端连续内存,但是支持高效的在首部插入和删除元素。它通过两级数组结构来实现。)

        vector自增长方式:分配两倍于当前容器的存储区,把当前的值拷贝到新分配的内存中,并释放原来的内存。

      10.2.3  list与vector比较 (vector还是list? P/213)

 

  11.  调用函数比直接计算条件操作符要慢得多——inline机制用来优化小的、只有几行的、经常被调用的函数  P/303

 

  12.  头文件不应该含有非inline函数或对象的定义

 

  13.  在函数中频繁使用的自动变量可使用register声明为寄存器自动对象。出现在循环语句中的数组索引和指针是寄存器对象的很好例子:

      for( register int ix = 0; ix < sz; ++ix )

      如果所选择的变量被频繁使用,则寄存器变量可以提高函数的执行速度。

      注意:关键字register对编译器来说只是一个建议,有些编译器可能忽略该建议,而是使用寄存器分配算法找出最合适的候选放到机器可用的寄存器中。  P/337

 

  14.  如果操作数被设置为0,则C++会保证delete表达式不会调用操作符delete(),没有必要测试是否为0。 P/340

      if( pi != 0 )  //没必要写这行

        delete pi;

 

  15.  delete pi 之后,pi成为空悬指针,建议设置指针为0  P/340

 

  16.  自动指针auto_ptr  见P/341

 

  17.  C++支持从C语言继承而来支持显式初始化表的机制,类似于用在初始化数组:

      Data local1 = { 0, 0 };

      //相当于local1.ival = 0; local1.ptr = 0;

      根据数据成员被声明的顺序,这些值按位置被解析。  P/566

 

  18.  explict关键字用于关闭编译器隐式转换

 

  19.  每个return语句之间,内联析构函数都必须被展开(编译时),所以建议函数内尽量少return,可用其它变量代替的就代替。

 

  20.  int a = b + c ;  //是对a的初始化

      int a;

      a = b + c ;    //赋值操作,前面比后面高效

 

  21.  "::"、".*"、"."、"?:"四个操作符不能被重载

 

  22.  typeid用于获取对象/变量的实际类型,用法:typeid(type).name()

 

  23.  函数介绍

      sizeof  作用是返回一个对象或类型名的字节长度。  P/132

      isalpha  判断是不是一个英文字母

    #include <cstring>

      int strlen( const char* )  //返回字符串的长度

      int strcmp( const char*, const char* )  //比较两个字符串是否相等

      char* strcpy( char*, const char* )  //把第二个字符串拷贝到第一个字符串中

    #include <assert.h>

      assert  通用预处理宏(断言 P/12)

    #include <algorithm>    //包括各种数据结构的元素检索、替换、逆序等等通用的算法。sort/find/max

    #include <iomanip>

      setw()          //功能与scanf类似,它读入的字符数最多为传递给它的参数减1  P/112