嵌入式超高频八股:C C++语法部分
面试了这么多场,个人感觉面试中对语法部分的考察其实占比非常少,而且基本问来问去就这么几个问题,所以本着用20%的力气,产生80%的效益的目的,只把问到的问题记录下来,这些一定一定要都搞懂!!被问到的几率非常大!
C
被const修饰的变量可以改变么
如果是局部的const(栈),可以通过指针的方式改变,如果是全局的会报错(rodata)
//可以运行 但不要这样
int main{
const int a = 1;
int *p = &a;
*p = 2;
}
-----------------------
// 错
const int a = 1;
int main{
int *p = &a;
*p = 2;
}
static 和 const
static
- 局部变量:放到data中,初始化一次不被释放
- 全局变量:当前文件可见
- 函数:当前文件可见
- 成员函数:全类共用,只能访问静态变量
- 成员变量:全类共用
const
- 常量:定义时初始化以后不能更改
- 形参:
- 修饰类成员函数:该函数对成员变量只能进行只读操作
volatile
- 作用:
- 防止编译器优化:
- 通常,编译器会进行优化,将变量值存储在寄存器中,以减少内存访问次数,提高程序运行效率。但是,对于
volatile
变量,编译器会放弃这种优化,每次访问都直接从内存读取或写入。
- 通常,编译器会进行优化,将变量值存储在寄存器中,以减少内存访问次数,提高程序运行效率。但是,对于
- 确保可见性:
- 在多线程编程或硬件编程中,某些变量可能由多个线程或外部硬件设备修改。使用
volatile
关键字可以确保这些变量的最新值在每次访问时都能被正确读取。
- 在多线程编程或硬件编程中,某些变量可能由多个线程或外部硬件设备修改。使用
- 使用场景
- 硬件寄存器
- 多线程共享变量:每次都获得最新的值
volatile const
使用场景:
- 只读寄存器,放置被优化并且从寄存器里读值,寄存器不准改写
野指针和悬空指针
野指针是定义出来没有初始化的指针,其内容是随机无意义的。 悬空指针是指向已经被释放内存的地址。
危害:访问到无效的内存区域:可能编译失败、执行不正确、崩溃、也有小概率执行正确。
避免方法:用智能指针、Santilazer、静态分析工具
sizeof 和strlen
复杂度
sizeof是编译时计算,所以是O(1) strlen是运行时函数,所以是O(n)
区别
strlen 运行时计算、只能看字符串、不算'\0' sizeof 编译时计算、都可以、算'\0'
C++
lambda表达式
\[捕获列表\](参数列表) {执行体}
[=] 全部值捕获 [&] 全部引用捕获 [=, &b] b引用捕获其余都值捕获 [&, b] b值捕获其余都引用捕获
拷贝构造和拷贝赋值
假设A中有new的 _data
以及长度 _length
class A;
//拷贝构造
A(const A& other):_data(new int[other._length]) {
//拷贝一些成员
copy(other._data, other._data + other._length , _data);
...
}
//拷贝赋值
A& operator=(const A& other) {
//注意要先把自己里的释放掉
delete[] _data;
_length = other._length;
_data = new int[other._length];
copy(other._data, other._data + other._length , _data);
...
}
移动构造和移动赋值
class A;
// 移动构造
A(A&& other):_data(nullptr), _length(0) {
_data = other._data;
_length = other._length;
//注意不是释放掉而是赋一个空
other._data = nullptr;
...
}
//移动赋值
A& operator=(A&& other) {
delete[] _data;
_data = other._data;
_length = other._length;
other._data = nullptr;
other._length = 0;
...
}
从上面两个可以看出来:
- 赋值重载,都需要先把new的delete掉后,将other的直接赋值过来(拷贝需要重新new,移动可以直接赋值)
- 移动最后都需要将其设置成nullptr,防止重复释放
- 拷贝需要用到拷贝函数,进行值拷贝
为什么析构函数可以为virtual型,而构造函数则不能?
虚函数的主要意义在于被派生类继承从而产生多态。派生类的构造函数中, 编译器会加入构造基类的代码,如果基类的构造函数用到参数,则派生类在其构造函 数的初始化列表中必须为基类给出参数,就是这个原因。虚函数的意思就是开启动态 绑定,程序会根据对象的动态类型来选择要调用的方法。然而在构造函数运行的时 候,这个对象的动态类型还不完整,没有办法确定它到底是什么类型,故构造函数不 能动态绑定。(动态绑定是根据对象的动态类型而不是函数名,在调用构造函数之 前,这个对象根本就不存在,它怎么动态绑定?)
智能指针
C++提供了三种主要的智能指针:std::unique_ptr
、std::shared_ptr
和 std::weak_ptr
。它们的主要作用是管理动态内存的生命周期,避免手动调用 delete 引发的内存泄漏或未定义行为。以下是对它们的详细介绍:
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
1. 自我介绍:高通、Oppo(sp)、vivo(sp)、小米(ssp)、荣耀(26k*12+80k)、华子(报批中)、美团、韶音、经纬恒润、乐鑫、中兴、TP 2. 内容: 1.嵌入式学习的资料和路径 2.所有面试的题目和解答(持续更新)、对评论的快速解答 3.各种碎碎念 3.整理不易,buy me coffee☕️,为了回馈牛客和各个粉丝,文章都会先试读几天,热度过了再收录~