1. vector

1.1 erase

以前用vector时只是使用push_back(),pop_back(),begin(),end(),front(),back()等,没用过erase(), 今天搭配iterator用了一下, 才发现很神奇。比如删除一个vector上指定值为val的元素:

for(vector<int>::iterator it = nums.begin(); it != nums.end(); ) {
    if( nums[i] == val ) {
        nums.erase(it++);
    } else {
        it++;
    }
}

上面这段代码是错误的,而且只要改一处就可以正确。修改后为:

for(vector<int>::iterator it = nums.begin(); it != nums.end(); ) {
    if( nums[i] == val ) {
        nums.erase(it);
    } else {
        it++;
    }
}

区别就是erase之后it没有自增,也就是将nums某个元素erase之后,并不需要将iterator自增,nums会自动调整整个结构,将后一个元素放到当前指针指的位置。

1.2 iterator

iterator某种程度上可以当作指针来使用,上述程序还可以这样:

while( it != nums.end() ) {
    if( *it == val ) {
        nums.erase(it);
    } else {
        it++;
    }
}

1.3 初始化

我通常不初始化vector, 但如果需要初始化分配一定空间, 可以使用vector<int> num(100); vector<int> num(100,0),前者是包含100个值默认初始化值的元素,后者是包含100个0。
此外,C++11新增了一个array类,是固定长度的数组,使用起来可能更方便和安全,有兴趣可以再仔细看下。

2. GCC编译器的问题

在CodeBlocks里输入vector<vector<int>> s竟然会编译出错,**’>>’ should be ‘> >’ within a nested template argument list**,改成 vector< vector<int> > s才好, 而在VS里并没有问题, CodeBlocks自带的MinGW中的GCC编译器在某些方面还是比不上VS的编译器的

3. Console输入

C++中输入字符串我一般常用string str; cin >> str;,然而今天要输入一个字符串,中间带有空格,发现上述写法不对,会自动滤除所有空格,搜了下,使用getline(cin,str);即可。

4. Struct与Class

struct与class在C++者两者基本相同, 区别仅在以下几点:

  • struct的成员默认权限是public,而class的成员默认权限是private
  • struct的默认继承方式为public,而class的默认继承为private
  • 只有class可用模板template定义参数,而struct不可以

5. 关于sizeof

首先声明: sizeof不是函数,是操作符

  • sizeof是C/C++中的一个操作符(operator),其作用就是返回一个对象或者类型所占的内存字节数
  • sizeof的计算发生在编译时刻,所以它可以被当作常量表达式使用
  • 指针记录了另一个对象的地址,既然是来存放地址的,那么必然等于计算机内部地址总线的宽度,所以在32位计算机中,一个指针变量的返回值是4字节,在64位系统中指针变量的sizeof结果为8,当然与编译器的版本有关,如果在64位系统上运行32位编译器自然还是4。注意sizeof(NULL) = 4
  • 数组的sizeof值等于数组所占用的内存字节数
  • 每个类的实例,在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址,因此空类默认会占用1个字节。如:
    class a {};
    sizeof(a);      //为1