嵌入式面试八股文整理(持续更新)

一、C语言篇

1.typedef有什么作用

用于为现有数据类型创建别名。通过 typedef 可以简化复杂类型的声明,提高代码可读性和可维护性。

对于指针、结构体或函数指针等复杂类型,typedef 可以隐藏细节,使代码更清晰。例如

c 复制代码
typedef int (*FuncPtr)(int, int);  // 定义函数指针类型别名
FuncPtr add_func = &add;           // 使用别名声明变量
 
c 复制代码
typedef struct { int x, y; } Point;  // 隐藏结构体标签
Point p = {1, 2};
 

例如常见的 size_t,uint8_t等关键字。

2.static 有什么作用

在 C 语言中,static 关键字根据上下文的不同,可以用于变量或函数,主要作用是控制作用域和生命周期。

static 用于变量时,变量的作用域限制在当前文件或函数内,其他文件或作用域无法访问。这可以避免命名冲突。

static 用于函数时,函数的作用域限制在当前文件内,其他文件无法调用。这有助于封装和模块化代码。

!!注意,static修饰的变量,其核心逻辑是变量由栈区转移到了静态数据区。而修饰函数未改变其存储区域而是改变了函数的链接属性。

3.内联函数和宏函数的作用

宏函数是预处理阶段的文本替换,内联函数是编译阶段的代码嵌入

内联函数(inline函数)的主要作用是减少函数调用的开销,提升程序执行效率。其核心机制是通过编译器将函数体直接嵌入调用点,避免常规函数调用时的压栈、跳转和返回操作。

特性 宏函数(#define) 内联函数(inline)
处理阶段 预处理阶段(编译前) 编译阶段
本质 纯文本替换,无类型检查、无函数调用逻辑 编译器优化后的 "嵌入式函数",有完整函数特性
类型安全 无类型检查,容易因类型不匹配出隐蔽错误 严格的类型检查(参数、返回值),和普通函数一致
作用域 全局有效(除非用 #undef),无作用域限制 遵循函数作用域规则(如 static inline 仅限当前文件)
求值次数 传参参数会被多次求值,例如++a(易出逻辑错误) 参数仅求值一次,和普通函数一致
调试难度 无法调试(预处理后已替换,无函数调用栈) 可调试(部分编译器支持),有函数调用栈信息
递归支持 不支持递归(预处理阶段无法处理递归替换) 支持递归(但编译器可能拒绝内联递归函数)
内存开销 无函数调用栈开销,但重复替换易导致代码膨胀 编译器可自主决定是否内联,能平衡开销与性能
4.指针的大小

指针的大小和编译器的位数有关。在32bit位系统下指针的大小是4个字节(32bit = 4byte),64bit位系统下指针的大小则是8个字节(64bit = 8byte)。指针的大小是固定的,和指针的类型没有关系。

5.野指针

野指针定义:指向不可用内存的指针。

为什么会产生野指针?

1.当指针被创建时,没有给指针赋值。

2.当指针被free或delete后,没有把指针赋值为NULL,这个时候指针也为野指针。

3.当指针越界的时候也算野指针。

6.sizeof与strlen区别

属性:sizeof是C语言的运算符,结果在编译阶段就可以确定;strlen是C语言的库函数,需要在运行时才能计算出结果。

作用:sizeof 用于获取数据类型或变量占用的内存大小(以字节为单位);strlen用于计算字符串的长度(不包括结尾的空字符10')。

参数:sizeof的参数可以是数据的类型,也可以是变量;而strlen只能以结尾为'\0'的字符串作参数

7.volatile的作用

volatile 是 C 语言中的一个关键字,用于修饰变量,告诉编译器该变量可能被意外修改,避免编译器优化导致的问题。它通常用于以下场景:

  • 硬件寄存器或内存映射的 I/O。
  • 多线程或中断服务程序中共享的变量。
  • 被信号处理函数修改的变量。

!!volatile可以与const结合,表示变量不能被程序改变,但是可以比外部修改。多用于硬件寄存器的映射的变量。

8.左值和右值

左值(lvalue)和右值(rvalue)是C++中用于描述表达式类别的术语,其核心区别在于表达式能否被赋值或取地址。

  • 左值 :通常指可以出现在赋值语句左侧的表达式,具有持久的内存地址,能够被取地址(如变量、对象或解引用后的指针)。
  • 右值:通常指只能出现在赋值语句右侧的表达式,是临时对象或字面量,没有持久的内存地址(如字面量、临时对象或返回右值引用的函数调用)。

二、MCU硬件篇

1.字节对齐

字节对齐(Byte Alignment)是计算机系统中数据在内存中存储的一种优化方式,要求数据的起始地址必须是某个特定值(通常是其自身大小或系统字长的整数倍)。对齐的目的是提升内存访问效率,避免因未对齐访问导致的性能损失或硬件异常。

部分的性能紧张的mcu不支持字节不对齐的访问。

具体看我博客中的 字节对齐的总结。

2.数据总线和地址总线

数据总线根据地址总线中对应的地址,去获取地址中的数据。

数据总线的字节位数意味着这个芯片的最大带宽,即是一次性能够获取多少的数据。

地址总线的字节数则意味着芯片的最大地址长度。例如0x00;两位的带宽,意味着只能寻找最大0xFF的数据。

3.什么是大端模式和小端模式

计算机系统中以字节(8bit)为存储单元,也就是每个地址单元对应一个字节,C语言中的int、short等类型数据大小大于一字节,所以就要考虑到多字节类型数据在内存中的字节排序问题,也就是大端模式和小端模式,介绍如下:

小端模式:数据的低位存放在低地址中,数据的高位存放在高地址中。如存储0x12 34 56 78,小端存储时情况如下:

低地址 --------------------> 高地址

0x78 | 0x56 | 0x34 | 0x12

大端模式:数据的高位存放在低地址中,数据的低位存放在高地址中。如存储0x12 34 56 78,大端存储时情况如下:

低地址 --------------------> 高地址

0x12 | 0x34 | 0x56 | 0x78

4.中断和异常有什么区别

中断通常由外部硬件设备触发,例如键盘输入、定时器到期或网络数据到达。中断是异步的,意味着它可以在任何时候发生,与当前执行的指令无关。

异常通常由CPU执行指令时检测到的错误或特殊情况触发,例如除以零、非法指令或页错误。异常是同步的,意味着它与当前执行的指令直接相关。

三、数据结构篇

相关推荐
mit6.8242 小时前
ai五层结构
算法
F_D_Z2 小时前
最长连续序列的长度LongestConsecutive
算法·哈希表·最长连续序列
DeepModel2 小时前
【回归算法】广义线性模型(GLM)详解
人工智能·算法·回归
沪漂阿龙2 小时前
大模型采样策略终极指南:Top-k、Top-p与结构化输出最佳实践
人工智能·算法·机器学习
DeepModel2 小时前
【回归算法】局部加权回归(LWR)详解
人工智能·算法·回归
浅念-2 小时前
C++ STL list 容器
开发语言·数据结构·c++·经验分享·笔记·算法·list
重生之后端学习2 小时前
39. 组合总和
java·数据结构·算法·职场和发展·深度优先
Frostnova丶2 小时前
LeetCode 868. 二进制间距
算法·leetcode
nix.gnehc2 小时前
深入理解Go并发核心:GMP模型与Goroutine底层原理
开发语言·算法·golang