C++ 知识点

1、指针和引用的区别
本质区别:指针有自己的一块空间(地址),而引用只是一个别名。

(1)指针:指针是一个变量,指向一块内存,它的内容是内存中的地址;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。

(2)可以有const指针,但是没有const引用;

(3)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)

(4)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;

(5)指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。

(6)"sizeof 引用"得到的是所指向的变量(对象)的大小,而"sizeof指针"得到的是指针本身的大小4(64位是8);

(7)指针和引用的自增(++)运算意义不一样;
 

2、数组和链表的区别

数组是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。

链表是一种上一个元素的引用指向下一个元素的存储结构,链表通过指针来连接元素与元素;

(1)数组是连续存储的,链表是散列存储的。数组随机访问性强(通过下标进行快速定位),所以数组的查询比链表要快,链表不能随机查找,必须从第一个开始遍历,查找效率低。(2)数组插入和删除效率低(插入和删除需要移动数据),链表插入删除速度快(因为有next指针指向其下一个节点,通过改变指针的指向可以方便的增加删除元素)

 C++中malloc/free, new/delete区别

1)malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。

2)对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。

3)因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。

4)C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。

C++创建类的对象(类的初始化)的方法区别new和不用new

https://blog.csdn.net/ytusdc/article/details/88621223

 C++中struct和class的区别

对于成员访问权限以及继承方式,class默认都是private,struct默认是public;class可以用于表示模板类型,struct不行;一般来说,用到继承时常用class,没用到继承时则使用struct。

struct和union有什么区别

①共用体和结构体都是由多个不同的数据类型成员组成, 但在任何同一时刻, 共用体只存放了一个被选中的成员, 而结构体的所有成员都存在。

②对于共用体的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构体的不同成员赋值是互不影响的。

C++里面vector、list、deque的区别

vector:vector是连续内存空间,支持高效的随机存取和尾部插入删除,对其他位置插入删除不方便,对比数组是可以自由动态增加空间。(伪动态,也是构造新一片内存空间,拷贝旧空间数据到新空间,释放旧空间)

deque:逻辑上的连续内存空间,支持高效的随机存取和头尾部双端插入删除。在中间进行插入删除也需要进行大量的数据移动。

List:双向循环链表,支持高效的插入和删除,对随机存取不方便。

如果想要高效的存取,不在乎插入和删除的效率,选用vector.

如果需要大量的删除和插入操作,不关心随机存取,选用list

如果需要高效的存取,同时在乎首尾的插入和删除,选用deque.

C++ static、const

Static:如果某个属性为整个类所共有,不属于任何一个具体对象,则采用 static 关键字来声明静态成员。

Const:常对象是这样的对象:它的数据成员值在对下岗的整个生存周期内不能被改变,也就是说,常对象必须进行初始化而且不能被更新!

什么时候用static:需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

static关键字的作用:常用来修饰变量。全局变量被static修饰后,就称之为静态全局变量;局部变量被static修饰后,就称之为静态局部变量。统称为静态变量。

-- static 作用

1、static在C和C++里各代表什么含义  https://www.cnblogs.com/shaozhuyong/p/5959760.html

2、C++中的static关键字的总结   https://www.cnblogs.com/BeyondAnyTime/p/2542315.html

3、C++中static关键字作用总结   https://www.cnblogs.com/songdanzju/p/7422380.html

4、static用法详解     https://www.cnblogs.com/heyonggang/p/3198431.html

1,修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在main函数运行钱就分配了空间,如果有初始值就用初始值初始化它,如果没有就用默认的值初始化。

2,修饰普通函数,表明函数的作用范围,尽在定义该函数的文件内才可以使用,在多人开发项目时候,为了防止与他人的命名空间利的函数重名,可以将函数定义为staic。

3,修饰成员变量,修饰成员变量使所有的对象只保存一个该变量,而且不需要生成对象就可以访问该成员。

4,修饰成员函数,修饰成员函数使得不需要生成对象就可以访问该函数,但是在static函数内不能访问非静态成员。

-- const 用法总结

1、C/C++中const关键字详解   http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html

2、const用法     https://www.cnblogs.com/timxgb/p/4104808.html

3、关于C++ const 的全面总结《转》 https://www.cnblogs.com/JiFfeiYu/p/6697195.html

4、C/C++的const区别  https://www.cnblogs.com/cthon/p/9166715.html

5、C++之const类成员变量,const成员函数  https://www.cnblogs.com/cthon/p/9178701.html

6、C++ const用法 尽可能使用const   https://www.cnblogs.com/xudong-bupt/p/3509567.html

1,修饰变量,说明该变量不可以被改变

2,修饰指针,分为指向常量的指针(pointer to const)和自身是常量的指针(常量指针,const pointer)

3,修饰引用,指向常量的引用(reference to const),用于形参类型,即避免了拷贝,又避免了函数对值的修改;

4,修饰成员函数,说明该成员函数内不能修改成员变量。

宏定义时, const与 #define 的区别

https://blog.csdn.net/ytusdc/article/details/88621754

C++中include时如何保证不重复加载头文件

#ifndef方式、#pragma once方式

什么时候要进行动态内存申请?

当无法事先确定对象需要使用多少内存(这些对象所需的内存大小只有在程序运行的时候才能确定)时就要申请动态内存,比如维护一个动态增长的链表或树。

C++内存泄漏和野指针怎么解决

内存泄漏:①访问已经释放的内存②访问没有权限的内存。

野指针:指向内存被释放的内存或者没有访问权限的内存的指针。

野指针可以使用shared_ptr和weak_ptr结合使用来尽量规避,释放内存后把指针指向NULL,防止指针在后面不小心又被解引用了。

内存泄漏的解决:使用智能指针。因为智能指针可以自动删除分配的内存。

堆和栈的区别

https://blog.csdn.net/K346K346/article/details/80849966

http://emb.hqyj.com/Column/9257.html

为什么不建议使用全局变量

使用全局变量的优点是:

可以减少变量的个数,减少由于实际参数和形式参数的数据传递带来的时间消耗。

但是,使用全局变量也有许多缺点:

(1)全局变量保存在静态存贮区,程序开始运行时为其分配内存,直到程序结束才能释放该内存。与局部变量的动态分配、动态释放相比,生存期比较长,因此过多的全局变量会占用较多的内存单元。

(2)全局变量破坏了函数的封装性能。函数象一个黑匣子,一般是通过函数参数和返回值进行输入输出,函数内部实现相对独立。但函数中如果使用了全局变量,那么函数体内的语句就可以绕过函数参数和返回值对全局变量直接进行操作,这种情况破坏了函数的独立性,使函数对全局变量产生依赖。同时,也降低了该函数的可移植性。

(3)全局变量使函数的代码可读性降低。由于多个函数都可能使用全局变量,如果修改了全局变量,都有可能影响到其他函数,同时函数执行时全局变量的值可能随时发生变化,对于程序的查错和调试都非常不利。因此,如果不是万不得已,最好不要使用全局变量

重载、重写、重定义、多态

1、C++继承中重载、重写、重定义的区别:https://www.cnblogs.com/weizhixiang/articles/5760286.html

2、C++重载重写和多态区别   https://www.cnblogs.com/zhaodun/p/6984479.html

3、C++继承中重载、重写、重定义的区别:https://blog.csdn.net/qq_37791134/article/details/81512043

4、C++中重载、重写(覆盖)和隐藏的区别 :https://www.cnblogs.com/zhangjxblog/p/8723291.html

5、浅谈C++多态性  :https://www.cnblogs.com/yxwkf/p/3901578.html

构造函数、析构函数、虚析构函数、纯虚析构函数等

构造函数、析构函数、虚析构函数、纯虚析构函数要点 : https://www.cnblogs.com/qiaoconglovelife/p/5128459.html

C++中基类的析构函数为什么要用virtual虚析构函数 : https://www.cnblogs.com/liushui-sky/p/5824919.html

在C++中为什么构造函数不能是虚函数,而析构函数可以 : https://blog.csdn.net/cainiao000001/article/details/81603782

虚析构函数(√)、纯虚析构函数(√)、虚构造函数(X)  : https://www.cnblogs.com/chio/archive/2007/09/10/888260.html

C++中基类的析构函数为什么要用virtual虚析构函数   https://www.cnblogs.com/liushui-sky/p/5824919.html

虚函数表,虚指针

https://blog.csdn.net/ytusdc/article/details/85842072

C++对象内存模型2 (虚函数,虚指针,虚函数表): https://www.cnblogs.com/wangxiaobao/p/5850949.html

C++类构造函数和析构函数

构造函数是一个特殊的公共成员函数,它在创建类对象时会自动被调用,用于构造类对象。

类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。

类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

构造函数和析构函数的作用

构造函数的作用:用于新建对象的初始化工作。

析构函数的作用:用于在撤销对象前,完成一些清理工作,比如:释放内存等。

每当创建对象时,需要添加初始化代码时,则需要定义自己的构造函数;

而对象撤销时,需要自己添加清理工作的代码时,则需要定义自己的析构函数。

C++中虚析构函数的作用

虚析构函数是为了避免内存泄露,而且是当子类中会有指针成员变量时才会使用得到的。也就说虚析构函数使得在删除指向子类对象的基类指针时可以调用子类的析构函数达到释放子类中堆内存的目的,而防止内存泄露的。

虚函数和纯虚函数的区别

含有纯虚函数的类称为抽象类,只含有虚函数的类不能称为抽象类。虚函数可以直接被使用,也可以被子类重载以后以多态形式调用,而纯虚函数必须在子类中实现该函数才可使用,因为纯虚函数在基类中只有声明而没有定义。虚函数必须实现,对虚函数来说父类和子类都有各自的版本。

基类指针和派生类指针

派生类对象也“是”基类对象,但两者不同。

派生类对象可以当做基类对象,这是因为派生类包含基类的所有成员。

但是基类对象无法被当做成派生类对象,因为派生类可能具有只有派生类才有的成员。

所以,将派生类指针指向基类对象的时候要进行显示的强制转换,否则会使基类对象中的派生类成员成为未定义的。

总结:基类指针和派生类指针指向基类对象和派生类对象的4中方法:

1.  基类指针指向基类对象。(正常使用)
2.  派生类指针指向派生类对象。(正常使用,不管是不是虚函数,调用的都是派生类的函数)
3.  基类指针指向派生类对象是安全的,因为派生类对象“是”它的基类的对象。(多态的体现,虚函数的话调用的是派生类的,非虚函数的话调用的是基类的)
       但是要注意的是,这个指针只能用来调用基类的成员函数。如果试图通过基类指针调用派生类才有的成员函数,则编译器会报错。
       为了避免这种错误,必须将基类指针强制转化为派生类指针。然后派生类指针可以用来调用派生类的功能。这称为向下强制类型转换,这是一种潜在的危险操作。
      注意:如果在基类和派生来中定义了虚函数(通过继承和重写),并同过基类指针在派生类对象上调用这个虚函数,则实际调用的是这个函数的派生类版本。
4.  将派生类指针指向基类对象,会产生编译错误。“是”关系只适用于从派生类到它的直接(或间接)基类,反过来不行。(一般不要这么用)
       基类对象并不包含派生类才有的成员,这些成员只能通过派生类指针调用。

基类与派生类的指针和成员函数调用原理
1.如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联编)

2.如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合生活习惯,在程序设计上也会给程序员带来困扰。(一般不会这么去定义)

3.如果基础类和衍生类定义了相同名称的成员函数(非虚函数),那么通过对象指针调用成员函数时,到底调用哪个函数要根据指针的类型(基类指针or派生类指针)来确定,而不是根据指针实际指向的对象类型确定。

4.如果基础类和衍生类定义了相同名称的成员函数(虚函数virtual),那么通过对象指针调用成员函数时,到底调用哪个函数要根据指针实际指向的对象类型(基类对象or派生类对象)来确定,而不是根据指针的类型确定。
 

python和C的区别

①语言类型:Python是一种基于解释器的语言,解释器会逐行读取代码;首先将Python编译为字节码,然后由大型C程序解释。C是一种编译语言,完整的源代码将直接编译为机器代码,由CPU直接执行。

②内存管理:Python使用自动垃圾收集器进行内存管理。在C语言中,程序员必须自己进行内存管理。

③应用:Python是一种通用编程语言,一个多范式。它主要支持面向对象编程,程序编程,函数编程。C是结构化编程语言。允许使用函数,选择(if / else等),迭代(循环)。它主要用于硬件相关的应用程序。

④速度:Python编程语言因为历史原因,有一个GIL锁,导致其对多线程支持不够好,运行速度较慢;而C语言很快,C语言是比较底层的语言,运行效率上要优于Python。

⑤复杂度不一样:在Python中,不需要声明变量类型。而在C中,必须声明变量类型。Python程序更易于学习,编写和阅读。而C程序语法比Python更难。Python中的测试和调试更容易;而在C中测试和调试更难。

inline 内联函数的特征

  • 相当于把内联函数里面的内容写在调用内联函数处;
  • 相当于不用执行进入函数的步骤,直接执行函数体;
  • 相当于宏,却比宏多了类型检查,真正具有函数特性;
  • 编译器一般不内联包含循环、递归、switch 等复杂操作的内联函数;
  • 在类声明中定义的函数,除了虚函数的其他函数都会自动隐式地当成内联函数。

优点
内联函数同宏函数一样将在被调用处进行代码展开,省去了参数压栈、栈帧开辟与回收,结果返回等,从而提高程序运行速度。内联函数相比宏函数来说,在代码展开时,会做安全检查或自动类型转换(同普通函数),而宏定义则不会。在类中声明同时定义的成员函数,自动转化为内联函数,因此内联函数可以访问类的成员变量,宏定义则不能。内联函数在运行时可调试,而宏定义不可以。

缺点
代码膨胀。内联是以代码膨胀(复制)为代价,消除函数调用带来的开销。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。inline 函数无法随着函数库升级而升级。inline函数的改变需要重新编译,不像 non-inline 可以直接链接。是否内联,程序员不可控。内联函数只是对编译器的建议,是否对函数内联,决定权在于编译器。

其他链接

C++经典面试题(最全,面中率最高)

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值