【C/C++】面经总结(一)

博客主页:@披星戴月的贾维斯
欢迎关注:点赞收藏留言
系列专栏: C/C++专栏
请不要相信胜利就像山坡上的蒲公英一样唾手可得,但是请相信,世界上总有一些美好值得我们全力以赴,哪怕粉身碎骨!
一起加油,去追寻、去成为更好的自己!

在这里插入图片描述

文章目录

  • 前言
  • 1、C++内存布局
  • 2、引用和指针
  • 3、C和C++/Python/Java的区别
  • 4、C++中const的用法
  • 5、C++中的static用法和意义
  • 6、介绍面向对象的三大特性,并且举例说明每一个
  • 总结

提示:以下是本篇文章正文内容,下面案例可供参考


前言

    又是一年金三银四,大家准备好了吗?在这里我和大家分享一下C/C++的面经,希望助大家一臂之力,这次的总结也涉及Linux/操作系统/网络等方面的知识,也希望大家收藏和支持一下!

1、C++内存布局

在这里插入图片描述
上面是我画的朴素版的内存区域划分,接下来和大家分享一下知乎别人画的详细内存区域划分。
【C/C++】面经总结(一)_第1张图片

1.2、为什么要分.data段和.bss段?

在程序编译的时候,不会给.bss段中的数据分配空间,只是记录数据所需空间的大小。在程序执行的时候,才会给.bss段中的数据分配内存。通过这种方式,可以节省一部分内存空间,进一步缩减可执行程序的大小。

1.3、堆和栈有什么区别
堆是由malloc和new动态开辟的一段内存,由程序员自己管理和释放。栈则是由编译器自己开辟和管理的内存,一般用来存放函数的传参和局部变量。

堆空间由于频繁开辟和释放,所以会产生内存碎片的问题。

堆的生长空间向上,地址越来越大,栈则是向下,地址越来越小。栈的空间很小只有8M,而堆有4G。

2、引用和指针

2.1、引用和指针的区别
首先指针是一个新的变量,这个变量叫做指针变量。它存储的是一个变量的地址或者一个函数的入口地址,我们可以通过这个地址来访问到该变量或者调用这个函数。引用则是对指针的封装,其底层实现是指针常量,相当于一个变量的别名。

指针可以有多级,并且可以为空。而引用不能够为空,并且只能被初始化一次。指针的大小一般为四个字节,引用的大小则是由被引用的对象大小决定。

指针在访问对象时需要解引用,也就是根据地址拿到地址中的数据。而引用由于编译器做了优化,类似于“语法糖”,不需要我们解引用,可以直接使用。

2.2、函数传参时,什么时候传指针,什么时候传引用
指针传参和引用传参都能够修改传入变量的值,因为底层。当你需要调用者确定所传入的对象必须存在的话,可以使用传引用。因为如果该对象不存在,则传引用会报错。由于调用者并不清楚函数会不会改变传入对象的数据,如果不希望改变,则可以用const修饰。在拷贝构造时,必须要传引用,不能够传值,否则会造成递归拷贝从而栈溢出的问题。

如果需要返回函数内部变量动态开辟的内存,则可以使用指针接收,但是用完以后要记得释放指针。

在C++中,类对象通常用使用引用传参。


3、C和C++/Python/Java的区别

3.1C和C++的区别
C是面向过程的语言,C++则是C语言的超集,增加了面向对象的特性,也就是封装、继承、多态。封装能够隐藏代码的实现细节,使得代码模块化,更加易于管理和扩展。继承则实现了子类重用父类的代码和属性。多态则是通过子类重写父类的虚函数实现同一个接口,多种执行动作。

C和C++管理内存的方式不同,C++主要是使用new和delete,除此之外,C++还加入了函数重载和引用等概念。

3.2C和Python的区别
Python是解释执行的脚本语言,C++则是编译语言,因此Python的跨平台比C++要好。

Python使用缩进来区分不同的代码块,C++则是使用花括号。

C++需要先定义变量的类型,而Python不需要。

Python库比C++多,用起来更方便。

3.3C++、Java的联系与区别,包括语言特性、垃圾回收、应用场景等(java的垃圾回收机制)
C++和Java都是面向对象的语言,C++需要编译成可执行文件才能运行,java编译之后运行在jvm虚拟机上,所以Java的跨平台特性比较好,但执行效率不如C++。

C++的内存需要程序员手动管理,Java则可以有虚拟机完成,使用标记-回收算法。

C++有指针,Java没有,Java只有引用。

Java和C++都有构造函数,C++有析构函数,Java没有。


4、C++中const的用法

const修饰成员变量,表示该成员变量为常量,不能被修改。

const修饰类的成员函数,表示该函数不会修改类中的成员数据,不会调用其他非const成员函数,并且和同名的非const成员函数形成函数重载。

当然也可以用来定义常量,全局常量存储在代码段中,局部常量存储在栈中。

define 和const的联系与区别(编译阶段、安全性、内存占用等)
他们都是用来定义常量的一种方法。

主要的区别为:define定义的常量没有类型,只是在预处理阶段进行了文本替换,没有类型检查,由于是替换,这就导致了会有多个拷贝,占用内存较多。const定义的全局常量是有类型的,并且存储在代码段中,而局部常量则会被放在栈中。

define是在预处理阶段进行替换,而const在编译阶段确定它的值。

const可以定义成员函数,意味着该函数不会修改成员变量。

const会做类型安全检查,define不会。


5、C++中的static用法和意义

static用来修饰变量、函数和类成员。

被static修饰的变量是静态变量,它会在程序运行过程中一直存在,会被放到静态存储区,也就是数据段。

局部静态变量的作用域是函数体,但它的生命周期则是全局生命周期。对于内置类型的局部静态变量,会在编一阶段进行初始化,对于自定义类型的静态局部变量,会在第一次进入函数体时初始化并调用构造函数。并且它们只会被初始化一次。

全局静态变量的作用域是当前整个文件。相当于缩小了全局变量的作用域。

被static修饰的函数是静态函数,静态函数只能在本文件中使用,相当于缩小了函数的作用域。

在类中,被static修饰的成员变量是类的静态成员,这个静态成员会被多个类共享。被static修饰的成员函数也是所有成员共享的静态函数。他们都需要通过类名来访问。由于静态成员函数缺少this指针,所以无法访问类的非静态成员,除非传入特定的对象指针或引用。

注意static和const的区别,const强调值不能被修改,而static强调唯一的拷贝,所有类的对象都共享static变量。


6、介绍面向对象的三大特性,并且举例说明每一个

面向对象的三大特性:封装、继承、多态。

封装主要是隐藏了子类的实现细节和成员数据,实现了代码的模块化,比如类里面的private的特性就可以避免成员数据在类外被访问。

继承则增加了代码的复用,使得子类可以复用父类的成员和方法。

多态则是一个接口,多种实现,通过父类的指针或者引用调用指向的子类的成员函数。起到了晚绑定的效果。父类也可以是抽象类,使得子类强制重写父类的纯虚函数。

多态的实现
多态包括编译时多态和运行时多态,编译时多态主要体现在函数中再和函数模板上面。

运行时多态主要由虚函数实现。

虚函数时在基类的函数前面加上virtual关键字,在派生类中重写该虚函数。

虚函数是通过虚函数表来实现的,虚函数表是每个类中存放虚函数地址的指针数组,每个类的对象中都有一个虚函数表指针(vptr)指向虚函数表,因此每个类可以通过虚函数表指针找到虚函数表,拿到指针数组里面虚函数的地址,然后调用虚函数。如果子类覆盖了父类的虚函数,则子类的虚函数表中就会指向子类实现的虚函数地址,否则指向父类的虚函数地址。

如果是多继承的情况,比如C继承了A和B,A和B都是基类,则C中就会有两个虚函数表指针。

总结

    本文向大家介绍了几个C/C++面试中可能会被问到的问题,希望对读者能有所帮助!

你可能感兴趣的:(C++初阶,c++,c语言)