嵌入式超高频八股: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

  1. 作用:
  • 防止编译器优化
    • 通常,编译器会进行优化,将变量值存储在寄存器中,以减少内存访问次数,提高程序运行效率。但是,对于volatile变量,编译器会放弃这种优化,每次访问都直接从内存读取或写入
  • 确保可见性:
    • 在多线程编程或硬件编程中,某些变量可能由多个线程或外部硬件设备修改。使用volatile关键字可以确保这些变量的最新值在每次访问时都能被正确读取。
  1. 使用场景
  • 硬件寄存器
  • 多线程共享变量:每次都获得最新的值

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_ptrstd::shared_ptrstd::weak_ptr。它们的主要作用是管理动态内存的生命周期,避免手动调用 delete 引发的内存泄漏或未定义行为。以下是对它们的详细介绍:

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

1. 自我介绍:高通、Oppo(sp)、vivo(sp)、小米(ssp)、荣耀(26k*12+80k)、华子(报批中)、美团、韶音、经纬恒润、乐鑫、中兴、TP 2. 内容: 1.嵌入式学习的资料和路径 2.所有面试的题目和解答(持续更新)、对评论的快速解答 3.各种碎碎念 3.整理不易,buy me coffee☕️,为了回馈牛客和各个粉丝,文章都会先试读几天,热度过了再收录~

全部评论

相关推荐

01-22 17:31
C++
点赞 评论 收藏
分享
评论
4
21
分享

创作者周榜

更多
牛客网
牛客企业服务