美文网首页
《C++ Primer》第I部分读书笔记(第1~7章)

《C++ Primer》第I部分读书笔记(第1~7章)

作者: 十月石榴2013 | 来源:发表于2017-12-11 15:38 被阅读15次
C++ Primer.png

第二章

1. 引用与指针
引用见上一篇文章;

// 执行完后,a和b的值都变成c
// 相当于b是a的小名
int a = 5;
int &b = a;
int c = 3;
b = c;

指针例子如下:

int x = 42;
int *ip = &x; // ip指向x的地址。

2. const
2.1 const与define的区别
摘自 helmsgao:http://blog.csdn.net/love_gaohz/article/details/7567856
(1) const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。
(2) 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。、
(3) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
2.2 顶层const
顶层const(top-lever const)表示指针本身是一个常量;底层const(low-lever const)表示指针所指对象是一个常量。例子:

int i = 0
int *const p1 = &i;        // 不能改变p1的值,这是一个顶层const
const int ci = 42;          // 不能改变ci的值,这是一个顶层const
const int *p2 = &ci;      // 允许改变p2的值,这是一个底层const

2.3 constexpr
允许将变量声明为constexpr类型,以便由编译器来验证变量的值是否是一个常量表达式。

3. 类型别名
方法一: typedefine
方法二:类型别名

// 方法一
typedef double wages;
wages w;

// 方法二
using SI = Sales_item; 

作用:避免引用类的版本差异带来的程序大规模变化(来自python2、python3的经验)。

4. auto
auto的用法: qq_32541007(http://blog.csdn.net/qq_32541007/article/details/52424721
(1)自动帮助推导类型
(2)类型冗长
(3)使用模板技术时,如果某个变量的类型依赖于模板参数,不使用auto将很难确定变量的类型(使用auto后,将由编译器自动进行确定)。
(4)返回值占位

    // 2. 类型冗长  
    map<int, map<int,int> > map_;  
    map<int, map<int,int>>::const_iterator itr1 = map_.begin();  
    const auto itr2 = map_.begin();  
    auto ptr = []()  
    {  
        std::cout << "hello world" << std::endl;  
    };  
// 3. 使用模板技术时,如果某个变量的类型依赖于模板参数,  
// 不使用auto将很难确定变量的类型(使用auto后,将由编译器自动进行确定)。  
  template <class T, class U>  
  void Multiply(T t, U u)  
  {  
      auto v = t * u;  
  }  

5. 绑定(bind)
令某个名字与给定实体关联在一起,使用改名字也就是使用该实体。例如,引用就是将某个名字与某个实体绑定在一起。

第三章

1. string
① string与string之间可以通过“+”连起来,但不能这样:string s = "hello"+"world"; 得这样: string s = "hello"+ str1 +"world"; 即中间得有一个str变量。
② for( auto c : str ) 取str中的每个字符。例子:

string s = "hello";
for(auto &c : s)        // 注意c是引用
    c = toupper(c);
cout << s << endl;

2. vector
也被称为“容器(container)”
关于使用vector还是数组,知乎上最高票的回答:https://www.zhihu.com/question/21760520
vector的大小是动态的,而且支持泛型,但执行效率数组>向量(https://www.cnblogs.com/love-yh/p/7410666.html)。
PS:只能对确知已存在元素执行下标操作!例子:

// 总之,就是可以把向量当做一种可扩容的数组来用。

vector<int> invec;
cout<<ivect[0];  // 错误,ivec不包含任何对象

vector<int> invec2(10);
cout<<ivect2[10];  // 错误,ivec2元素合法索引是0到9

3. 迭代器
之后会细讲,这里有一个用迭代器做二分搜索的例子:

auto beg = text.begin() ;
auto end = text.end() ;
auto mid = text.begin() + (end - beg)/2 ;
while ( mid != end && *mid != sought ){
   if( sought < *mid)
        end = mid ;
    else
        beg = mid + 1 ;
    mid = beg + (end - beg)/2 ; 
}

第四章

1.
位操作的操作数都会自动转化成int型(32位)。
【&】位与,【&&】逻辑与;
【|】位或,【||】逻辑或;
【^】位求反,【!】逻辑非。
【<<】左移位,【>>】右移位。
【sizeof】返回一个类型或一条表达式所占的字节数。
2.运算符优先级表

1. 2. 3.

第六章

1. 函数技巧
① 使用引用(避免拷贝+传递多个参数)
因为拷贝大型类或容器对象比较低效,甚至有的类本身不支持拷贝操作,函数智能通过引用形参访问该类的对象。
例子:

// 比较两个string对象的长度
bool isShorter(const string &s1, const string &s2 )
{
    return s1.size() < s2.size(); 
}

② 尽量使用常量引用
参考资料:stpease http://blog.csdn.net/stpeace/article/details/40871801
当函数无须修改引用形参的值时,最好使用常量引用。常量引用可接受参数范围比单纯的引用大。

2. main函数的命令行处理选项

int main(int argc, char *argv[]) {......}

第一个参数argc表示argv[]中字符串的数量,即在命令行中输入了几个参数。第二个参数argv[0]表示命令行的第一个输入的字符串(就是可执行文件名即程序名),argv[1]表示输入的第一个参数,argv[2]表示输入的第二个参数……
3. 返回值
不要反回局部对象的引用或指针,因为函数结束后,局部对象被释放,指针将指向不存在的对象。
4. 静态成员
静态成员能用于某些场景而普通成员不能。
静态成员独立于任何对象。静态成员可以作为默认实参,而非静态成员不行,因为它的值本身属于对象的一部分。
PS:印象里可以使用类的静态成员作为全局变量。

相关文章

网友评论

      本文标题:《C++ Primer》第I部分读书笔记(第1~7章)

      本文链接:https://www.haomeiwen.com/subject/tlchixtx.html