11、宏定义和typedef区别?
12、变量声明和定义区别?
13、哪几种情况必须用到初始化成员列表?
14、strlen和sizeof区别?
int main(int argc,char const* argv[])
{
const char* str="name";
sizeof(str);//取的是指针str的长度,是8
strlen(str);//取得是这个字符串得长度,不包含结尾的\0.大小是4
return 0;
}
/*
char* p="nameqaz";
char q[]="qwere";
sizeof(p);//8 带结束标志位
strlen(p);//7
15、常量指针和指针常量区别?
16、a和&a有什么区别?
int a[10];
int(*p)[10]=&a;//a的地址就是函数指针p
int(*) [10](就是前面提到的数组指针)
,其加1时,系统会认为是数组首地址加上整个数组的偏移(10个int型变量),值为数组a尾元素后一个元素的地址。17、数组名和指针(这里为指向数组首元素的指针)区别?’
18、野指针和悬空指针
int main(void)
{
int* p;//指针p没有被初始化
std::cout<<*p<<std:endl;//未初始化p就被使用
return 0;
}
//因此,为了防止出错,对于指针初始化时都是赋值为 nullptr ,
//这样在使用时编译器就会直接报错,产生非法内存访问。
int main(void)
{
int* p=nullptr;
int* p2=new int;
p=p2;
delete p2;//需要设置为 p=p2=nullptr;
}
//此时 p和p2就是悬空指针,指向的内存已经被释放。继续使用这两个指针,行为不可预料。需要设置为 p=p2=nullptr 。此时再使用,编译器会直接保错。
19、迭代器失效的情况
造成失效的原因是因为内存的重新分配, 保留下来的迭代器不再指向容器中原来的元素。
迭代器失效的两个层面:
失效函数:
(1)对于序列式容器(比如vector):删除当前的iterator会使后面所有元素的iterator都失效。这是因为顺序容器内存是连续分配(分配一个数组作为内存),删除一个元素导致后面所有的元素会向前移动一个位置。(删除了一个元素,该元素后面的所有元素都要挪位置,所以,iter++,已经指向的是未知内存).但是erase方法可以返回下一个有效的iterator。所以代码做如下修改,就OK了。
void vectorTest()
{
vector<int> container;
for(int i=0;i<10;i++)
container.push_back(i);
vector<int>::iterator iter;
for(iter=container.begin();iter!=container.end();){
if(*iter>3)
iter=container.erase(iter);//删除迭代器i位置的元素, 返回指向i后面一个元素的迭代器
else
iter++;
}
for(iter=container.begin();iter!=container.end();iter++)
cout<<*iter<<endl;
}
对于关联容器(如map, set,multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,**只要在erase时,递增当前iterator即可。**这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。
for(iter=container.begin();iter!=container.end();)
{
(*iter)->doSomething();
if(shouldDelete(*iter))
container.erase(iter++);//删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可
else
++iter;
}
20、C和C++的区别