11-20==c++知识点

11、宏定义和typedef区别?
  • 宏主要用于定义常量及书写复杂的内容;typedef主要用于定义类型别名。
  • 宏替换发生在编译阶段之前,属于文本插入替换;typedef是编译的一部分
  • 宏不检查类型;typedef会检查数据类型。
  • 宏不是语句,不在在最后加分号;typedef是语句,要加分号标识结束
  • 注意对指针的操作,typedef char * p_char和#define p_char char *区别巨大。
12、变量声明和定义区别?
  • 声明仅仅是把变量的声明的位置及类型提供给编译器,并不分配内存空间;定义要在定义的地方为其分配存储空间。声明不分配空间,定义分配空间
  • 相同变量可以在多处声明(外部变量extern),但只能在一处定义。
13、哪几种情况必须用到初始化成员列表?
  • 初始化一个const成员
  • 初始化一个reference成员。
  • 调用一个基类的构造函数,而该函数有一组参数。
  • 调用一个数据成员对象的构造函数,而该函数有一组参数。
14、strlen和sizeof区别?
  • sizeof是运算符,并不是函数,结果在编译时得到而非运行中获得;strlen是字符处理的库函数。
  • sizeof参数可以是任何数据的类型或者数据(sizeof参数不退化);strlen的参数只能是字符指针且结尾是’\0’的字符串。
  • 因为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、常量指针和指针常量区别?
  • 指针常量是一个指针,读成常量的指针,指向一个只读变量。如int const *p或const int *p。
  • 常量指针是一个不能给改变指向的指针。指针是个常量,不能中途改变指向,如int *const p。
16、a和&a有什么区别?
int a[10];
int(*p)[10]=&a;//a的地址就是函数指针p
  • a是数组名,是数组首元素地址,+1表示地址值加上一个int类型的大小,如果a的值就是0x00000001,加1操作后变为0x00000005。*(a+1)=a[1]。
  • &a等价于&a[0],即是数组的指针,其类型为 int(*) [10](就是前面提到的数组指针),其加1时,系统会认为是数组首地址加上整个数组的偏移(10个int型变量),值为数组a尾元素后一个元素的地址。
  • 若(int *)p ,此时输出 *p时,其值为a[0]的值,因为被转为int *类型,解引用时按照int类型大小来读取。
17、数组名和指针(这里为指向数组首元素的指针)区别?
  • 二者均可通过增减偏移量来访问数组中的元素
  • 数组名不是真正意义上的指针,可理解为常指针,所以数组名没有自增、自减等操作。
  • 当数组名当作形参传递给调用函数后,就失去了原有的特性,退化为一般指针(常量化为变量)。多了自增、自减操作,但sizeof运算符不能再得到原有数组大小了。
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 。此时再使用,编译器会直接保错。
  • 为此c++引入了智能指针,c++智能指针的本质就是避免悬空指针的产生。
  • 产生原因及解决办法:
    • 野指针:指针变量未及时初始化 => 定义指针变量及时初始化,要么置空。
    • 悬空指针:指针free或delete之后没有及时置空 => 释放操作后立即置空。
19、迭代器失效的情况
  • 造成失效的原因是因为内存的重新分配, 保留下来的迭代器不再指向容器中原来的元素。

  • 迭代器失效的两个层面:

    • ①无法通过迭代器进行自增与自减去操作遍历整个stl容器(第一层失效)
    • 法通过迭代器存取迭代器所指向的内存(第二层失效)
  • 失效函数:

    • insert(i, value)在迭代器i前插入一个元素value, 返回指向value的那个迭代器
    • erase(i) 删除迭代器i位置的元素, 返回指向i后面一个元素的迭代器
  • (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++的区别
  • C++中new和delete是对内存分配的运算符,取代了C中的malloc和free。
  • 标准C++中的字符串类取代了标准C函数库头文件中的字符数组处理函数(C中没有字符串类型(字符数组代替))。
  • C++中用来做控制态输入输出的iostream类库替代了标准C中的stdio函数库。
  • C++中的try/catch/throw异常处理机制取代了标准C中的setjmp()和longjmp()函数。
  • 在C++中,允许有相同的函数名,不过它们的参数类型不能完全相同,这样这些函数就可以相互区别开来。而这在C语言中是不允许的。也就是C++可以重载,C语言不允许。
  • C++语言中,允许变量定义语句在程序中的任何地方,只要在是使用它之前就可以;而C语言中,必须要在函数开头部分。而且C++允许重复定义变量,C语言也是做不到这一点的
  • 在C++中,除了值和指针之外,新增了引用。引用型变量是其他变量的一个别名,我们可以认为他们只是名字不相同,其他都是相同的。
  • C++相对与C增加了一些关键字,如:bool、using、dynamic_cast、namespace等等
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栋哥爱做饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值