4 !的优先级

! > + - * /

cout << !3-1 << endl << !(3-1);

//output -1(0-1)   0(!2)

5 迭代器的理解

就拿 string 类举例来说,其

string str("abcdefg");
//删除第一个字符
str.erase(str.begin());
//删除第一个字符
str.erase(str.begin(),str.begin()+1);
//删除全部字符
str.erase(str.begin(),str.end());
//保留最后一个字符
str.erase(str.begin(),str.end()-1);

从以上的代码,我们可以对迭代器做这样的理解,迭代器不同于普通的下标,而是一种类似于“隔板”一样的东西,str.begin() 返回的迭代器位于第一个字符前面,而 str.end() 返回的迭代器位于最后一个字符的后面,所以叫做”超尾迭代器“,如果成员函数的参数是首尾两个迭代器,那么删除的部分就位于这两个"隔板“之间。

注: 另外,string 类中的erase可以用int pos 作为参数,而其他的 STL 容器的 erase 好像只能用迭代器作为参数

6 NULL 和 nullptr

首先看一下 NULL 的定义

#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif

也就是说 NULL 在 C++ 中被 define 为 0. 而在 C 中 被 define 为 (void *)0。 这在某些情况下是会出问题的

void f(int i){
cout << "take integer" << endl;
}
void f(int *p){
cout << "take pointer" << endl;
}

这两个重载函数,如果通过f(NULL)来调用 将调用第一个以 int 为参数的函数,而如果通过f(nullptr)来调用则会调用第二个函数 nullptr 是一个关键字 不存在上述问题

7 关于 cin 输入流

首先 关于 循环 while(cin) 的终止, 似乎只能通过 EOF 也就是键盘上的 Ctrl + Z 来实现,如果你想对一段输入按空格拆分的时候如果是自己用键盘输入还好,可以输入 Ctrl + Z ,但是如果是测试题,那就没有机会输入 EOF 了。

解决方法是

while(cin){
    cin >> str;
    if (cin.get()=='\n')
    break;
}

cin.get() 和 cin.getline() 的区别是 cin.get 不会丢弃换行符而是留在输入流里,而 cin.getline 会读取并丢弃换行符。

8 const 和指针

const 只要不和指针混在一起,那么其表达的意思是很清楚的,但是只要和指针混在一块,通常对于 const 到底是修饰指针本身还是指针所指向的对象就要费一番周折了。

实际上,判断 const 修饰的对象最简单的方法就是看 const 位于 * 的左边还是右边。如果 const 位于星号的左侧,则 const 就是用来修饰指针所指向的变量,即指针指向为常量;如果 const 位于星号的右侧,const 就是修饰指针本身,即指针本身是常量。

int b = 500;
const int* a = &b; //[1]
int const *a = &b; //[2]
int* const a = &b; //[3]
const int* const a = &b; //[4]

[1]和[2]的情况相同,都是指针所指向的内容为常量(const放在变量声明符的位置无关).[3]为指针本身是常量,而指针所指向的内容不是常量.[4]为指针本身和指向的内容均为常量。