C++琐记二
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