【秋招】嵌入式面试八股文-C语言02篇
本文为C语言部分,具体整篇目录可以看前言!
第一部分(纯八股)
1 C语言/C++
1.1-1.5.9 内容见此篇文章【秋招】嵌入式面试八股文-C语言01篇
1.6 C++部分
1.6.1 C++中类成员的访问权限?
无论成员被声明为 public、protected 还是 private,都是可以互相访问的,没有访问权限的限制。在类的外部 (定义类的代码之外),只能通过对象访问成员,并且通过对象只能访问 public 属性的成员,不能访问 private、protected 属性的成员。
(a)protected:受保护的,类内和子类可直接访问,也就是说,基类中有protected成员,子类继承于基类,那么也可以访问基类的protected成员,要是基类是private成员,则对于子类也是隐藏的,不可访问。
(b)private:私有的,只有类内的成员函数才可以访问。
1.6.2 什么是构造函数?
构造函数是一种特殊的函数,用于创建和初始化对象。它在创建对象时被调用,用于设置对象的初始状态和属性。构造函数的名称通常与类的名称相同,且没有返回类型声明。
构造函数可以有多个重载版本,每个版本允许接受不同类型和数量的参数。通过调用不同的构造函数,可以根据需要创建不同种类的对象。
构造函数的主要功能包括:
(a)分配内存空间:构造函数负责为对象分配足够的内存空间,以存储对象的数据成员。
(b)初始化对象:构造函数可以对对象的数据成员进行初始化,确保对象的属性处于正确的初始状态。
(c)设置默认值:构造函数可以为对象的属性设置默认值,以避免对象在创建时出现未定义的行为。
在C++中,构造函数名称与类名称相同,没有返回类型声明,并且可以是公有、私有或受保护的。当创建对象时,会自动调用适当的构造函数来初始化对象。如果未明确定义构造函数,编译器将提供一个默认的无参数构造函数。
1.6.3 构造函数的分类是怎样的?
(1)无参构造 Person( ) {}
(2)有参构造 Person(int a) {}
(3)拷贝构造函数 Person( const Person& p) {}
1.6.4 构造函数的调用规则是怎样的?
C++编译器至少给一个类添加3个函数
(a)默认构造函数(无参)
(b)默认析构函数(无参)
(c)默认拷贝构造函数,对属性进行值拷贝
如果用户定义了有参构造函数,C++不再提供默认无参构造,但是会提供默认拷贝构造;如果用户定义拷贝构造函数,C++不会再提供其他构造函数。
1.6.5 什么是析构函数?
需要自己定义构造函数和析构函数的情况有以下几种:
(a)当需要在对象创建时进行一些初始化操作时,可以定义构造函数来实现。比如,需要在对象创建时给成员变量赋初值或者打开一些资源。
(b)当需要在对象销毁时进行一些清理操作时,可以定义析构函数来实现。比如,需要在对象销毁时释放一些资源或者关闭一些文件。
(c)当需要控制对象的生命周期时,可以定义构造函数和析构函数来实现。比如,需要在对象创建时进行一些操作,在对象销毁时进行一些清理操作,这样可以确保对象的正确使用。
总之,需要自己定义构造函数和析构函数的情况主要是为了实现一些特定的需求,比如初始化、清理、控制对象的生命周期等。
注意:构造函数可以有参数,因此可以重载,析构函数不能有参数,因此不可以发生重载。
1.6.6 引用注意事项?
引用格式: 数据类型 &别名 = 原名
引用必须初始化;引用在初始化后不可以改变;函数传参时,可以利用引用让形参修饰实参;引用可以作为函数的返回值,但是不要返回局部变量。引用的本质在C++内部实现一个指针常量。
1.6.7 函数重载是什么?
重载满足条件:同一个作用域下;函数名称相同;函数参数类型不同或者个数不同或者顺序不同。
1.6.8 什么是深拷贝与浅拷贝?
浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作
当在类里面涉及到指针操作时,如果采用浅拷贝,则执行拷贝构造函数后。会导致拷贝出两个指针指向同一个内存空间,则进行析构函数时,就会对该空间释放两次,然后导致报错。因此需要进行深拷贝,对于指针重新再开辟一段空间。
1.6.9 静态成员归纳
(a)静态成员变量:
所有对象共享同一份数据; 在编译阶段分配内存;类内声明,类外初始化
(b)静态成员函数:
所有对象共享同一个函数;静态成员函数只能访问静态成员变量
(c)关于两者内存:
如果只声明了类而未定义对象,则类的一般成员变量是不占用内存空间的,只有在定义对象的时候,才为对象的成员变量分配空间。
静态成员不占用类内空间;静态成员函数在类内声明,类外初始化。
1.6.10 继承是什么?
语法: class 子类 : 继承方式 父类 比如:class A :public B
多继承语法:
class 子类 : 继承方式 父类1,继承方式 父类1
继承过程中,父类中的私有成员也被子类继承,只是由编译器隐藏后访问不到。
继承同名成员处理方式:
子类对象可以直接访问到子类中同名成员
子类对象加作用域可以访问到父类同名成员
当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数。
1.6.11 菱形继承是什么?
两个派生类继承同一个基类;又有某个类同时继承了两个派生类;这种继承称为菱形继承。
羊继承了动物数据;马继承了动物数据;草泥马继承了羊和马的数据,则动物数据被继承了两份。
采用虚继承的方法解决该问题。
1.6.12 虚函数是什么?
虚函数只能是类的成员函数, 而不能将类外的普通函数声明为虚函数. 虚函数的作用是允许在派生类中对基类的虚函数重新定义 (函数覆盖), 只能用于类的继承层次结构中.
虚函数能有效减少空间开销. 当一个类带有虚函数时, 编译系统会为该类构造一个虚函数表 (一个指针数组), 用于存放每个虚函数的入口地址.
什么时候应该使用虚函数:
判断成员函数所在的类是不是基类, 非基类无需使用虚函数
成员函数在类被继承后有没有可能被更改的功能, 如果希望修改成员函数功能, 一般在基类中将其声明为虚函数;
我们会通过对象名还是基类指针访问成员函数, 如果通过基类指针过引用去访问, 则应当声明为虚函数。
1.6.13 静态函数和虚函数的区别?
多态分为两类:静态多态和动态多态
静态多态:函数重载和运算符重载属于静态多态、
虚函数因为用了虚函数表机制,调用的时候会增加一次内存开销。
1.6.14 什么是多态?
多态是指不同继承关系的类对象,去调用同一函数,产生了不同的行为。在继承中要想构成多态需要满足两个条件:
(a)必须通过基类的指针或者引用调用虚函数。
(b)被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
1.6.15 纯虚函数是什么?
纯虚函数不需要在父类中实现,必须在子类中实现
在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容,因此可以将虚函数改为纯虚函数。
纯虚函数语法:
virtual 返回值类型 函数名 (参数列表) = 0
当类中有了纯虚函数,这个类也称为抽象类
抽象类特点:
无法实例化对象
子类必须重写抽象类中的纯虚函数,否则也属于抽象类。
1.6.16 重载和覆盖有什么区别?
(a)覆盖是子类和父类之间的关系,垂直关系;重载同一个类之间方法之间的关系,是水平关系。
(b)覆盖只能由一个方法或者只能由一对方法产生关系;重写是多个方法之间的关系。
(c)覆盖是根据对象类型(对象对应存储空间类型)来决定的;而重载关系是根据调用的实参表和形参表来选择方法体的。
1.6.17 析构函数可以为 virtual 型,构造函数则不能,为什么?
虚函数的主要意义在于被派生类继承从而产生多态。派生类的构造函数中,编译器会加入构造基类的代码,如果基类的构造函数用到参数,则派生类在其构造函 数的初始化列表中必须为基类给出参数,就是这个原因。虚函数的意思就是开启动态绑定,程序会根据对象的动态类型来选择要调用的方法。然而在构造函数运行的时候,这个对象的动态类型还不完整,没有办法确定它到底是什么类型,故构造函数不能动态绑定。
1.6.18 数组下标可以为负数吗
可以,因为下标只是给出了一个与当前地址的偏移量而已,只要根据这个偏移量能定位得到目标地址即可。
1.6.19 结构体和类的区别
#嵌入式##嵌入式秋招##秋招##校招##秋招提前批,你开始投了吗#我打算把自己整理的八股文笔记、面试经验、项目经验、简历修改经验等等,分享给大家。之前准备找工作那会,很多付费的东西,质量参差不齐,我打算在牛客创建一个免费的专栏,分享整理的这些内容,今天这个是第一篇文章,对于找工作的人提供一份帮助就行。