嵌入式八股文——领绿100题
/ 13 min read
面试八股——领绿100题
type: Post status: Published date: 2025/07/31 summary: 2131 tags: 开发 category: 技术分享
-
什么是函数指针?什么是指针函数?
- 函数指针:指向一个函数的指针
- 指针函数:一个函数的返回值是一个指针的函数
-
指针的大小
- 指针的大小和编译器的位数有关,在32位系统上,指针大小是4个字节。在64位系统上,指针是8个字节。
-
sizeof和strlen的区别
- sizeof是一个运算符;strlen是一个函数,需要包含string.h
- sizeof计算的是所占内存的大小,strlen计算的是字符串的长度(字符串以\0结尾,\0是不需要计算长度的)
- strlen一般用于计算字符串的长度,sizeof可以计算int float
-
数组指针和指针数组的区别
- 数组指针:是指向数组的指针,本质是一个指针。
- 指针数组:是包含指针的数组,本质是一个数组。
int (*p)[10];//数组指针int* p[10];//指针数组 -
c语言内存分配的方式有几种
- 静态存储区分配,全局变量、静态变量
- 栈上分配,函数中定义处的局部分类
- 堆上分配,malloc、new
-
struct和union的区别
union联合体 struct结构体 所有成员共享一块地址 不同成员放在不同的地址中 联合体大小 = 成员中占内存最大的成员的大小 结构体大小 = 所有成员大小之和 -
野指针
- 野指针是指向不可用内存的指针
- 当指针被创建的时候,没有数值这个时候指针就成为了野指针。
- 当指针被free或者delete后如果没有把指针赋值为NULL,这个时候指针也是野指针
-
数组和链表的区别
- 数组的地址空间是连续的,链表的地址空间是不连续的
- 数组的访问的速度比较快,数组直接通过下表访问,访问链表的时候需要遍历链表
- .链表增删查改的速度比数组快
-
写一个宏,这个宏返回输入参数比较小的一个
#define MIN(a,b) ((a) <= (b) ? a : b) -
使用#include<>和使用include“”的区别
- <>编译器会从标准库的路径里面去搜索,对于搜索标准库的文件速度会比较快
- “”编译器会从用户的工作路径去搜索,对于自己定义的文件会比较快
-
全局变量和局部变量的区别
- 作用域,全局变量的作用域为程序块,局部变量的作用域是当前函数内部
- 生命周期,全局变量的生命周期是整个程序,局部变量的生命周期是当前的函数
- 存储方式不同,局部变量是存储在栈里面的,全局变量是存储在全局数据区中
- 使用方式不同,全局变量在程序的各个部分都可以使用,局部变量的话只能在函数的内部去使用
-
#define和typedef的区别
- define是一个预处理指令,typedef是一个关键字
- define不会做正确性检查;typedef会做正确性检查,主要用于类型重命名
- define没有作用域的限制,typedef是有作用域的限制
- 对指针的操作不同
-
static的作用
- 定义一个静态变量或者静态函数
- 在函数体中使用static去定义变量,那么这个变量只会被初始化一次。
- 定义的静态函数或者静态变量只能在当前文件夹中使用(作用域的限制)
- 在函数内部定义的静态变量无法被其他函数使用
-
什么事内存泄漏
- 内存泄漏指的是在程序运行的时候,动态分配的空间没有被回收或者正确释放,导致了这个内存空间仍然占据系统的资源
- 使用malloc创建内存空间结束,需要使用free/delete删除内存
-
什么是内存对齐
- 内存对齐是存储数据时,将数据按照一定的规则放置在内存中的过程
- 内存分配规则,以最大的变量所占据的内存,来进行分配内存空间
-
数组名和指针的区别
- 数组名就是数组首元素的地址,也可以看做一个常量指针,这个指针是不能修改指向的,内存访问为4个字节
- 使用指针访问数组的时候需要使用到解引用使用*,使用指针访问数组是间接访问,使用数组名访问数组是直接访问
- 使用sizeof对指针和数组名进行计算的时候是不同的,指针的大小和编译器的位数有关,使用sizeof计算数组名是整个数组的大小
-
指针常量和常量指针
- 常量指针是指向一个常量的指针,这个指针无法修改所致想到数据,但是可以修改指向
- 指针常量是指针是一个常量,指针所指向的地址是固定的,但是可以修改地址中的值
const int* p = &a; //常量指针int * const p1 = &a; //指针常量 -
堆和栈的区别
-
创建方式不同,栈是系统自动创建(栈主要用于保存局部变量),当函数执行完成,栈被销毁;
堆事程序员手动进行创建和释放的,malloc进行创建,free进行释放
-
空间大小的区别,栈的空间是比较小的,堆的空间是比较大的
-
访问速度,栈的访问速度是比堆要快的
-
生命周期,栈当使用完成后会自动被销毁,堆事要考程序员自己进行手动销毁
-
-
malloc和new的区别
- malloc是c语言中的标准库函数,new是C++中的操作符
- malloc分配内存后,返回的是void*类型的指针。new分配内存后返回的是对应对象类型的指针
- 使用malloc分配内存的时候需要进行制定分配内存的的大小,使用new进行内存分配时,不需要指定
- 使用malloc分配内存的时候不会调用到构造函数,使用new分配内存时会调用到构造函数
-
struct和class在C++中的区别
- struct成员默认是公有的,class默认的成员是私有
- 继承方面,struct默认的是公有继承,class默认的是私有继承
- 使用场景,struct一般在用于做简单的数据结构,class一般用于封装和继承
-
C++中的类有几个访问权限
- 公有public,当成员声明为public时就可以在类外部进行访问
- 私有private,当成员声明为private时只能在类的内部进行访问
- 受保护protected,当成员声明为protected时只能在类内部货子类中进行访问
-
什么是内联函数,为什么要有内联函数
- 是一种特殊的函数声明方式,通过在函数前面加上inline关键字,来指示编译器在调用这个函数的时候将他展开,而不是直接进行调用
- 减小函数调用的开销
- 提高执行的效率
- 允许编译器进行优化
-
使用c语言实现strcpy函数
- 作用,实现字符串拷贝
- 明确参数和返回值
char* mystrcpy(char* dest,char* src){char* temp = dest;while((*dest++ = *src++));return temp;}- 程序分为几段
- 代码段,用于存储程序的可执行指令,一般是只读的,防止被修改
- 数据段,Data,存储已经初始化的全局变量和静态变量
- BSS,存储没有初始化的全局变量和静态变量
- 堆,使用malloc和free进行管理
- 栈,存储局部变量,栈的申请和释放,是由操作系统来决定的
- 队列和栈的区别
- 访问的方式,栈的是先进后出,队列的是先进先出
- 栈,只能在栈顶进行操作;队列在队尾进行插入,队首进行删除
- 应用场景,栈用于函数调用、表达式求值;队列用于任务调度,广度优先搜索
- 一个.c文件中怎么转换为可执行程序
- 预处理:将头文件、宏定义进行展开,生成没有注释的源代码 .i
- 编译:将预处理得到的源代码转换为汇编代码 .s
- 汇编:将汇编的代码转换为机器码生成对应的目标文件 .o
- 链接:将全部的.o文件链接成一个可执行程序 .exe
- SPI和IIC的寻址区别
- SPI寻址方式:MISO、MOSI、SCLK、CS,通过片选引脚,选的对应的设备进行通讯
- IIC寻址方式:SDA、SCL,通过从机地址进行寻址7位、10位
- 什么是交叉编译
- 交叉编译是指在一个平台上编译出另一个平台的可执行文件
- UART,IIC,SPI的区别
- 串口,异步通讯,没有时钟线;TX输出 RX输入;一对一通讯;传输速率由波特率决定 115200 9600;全双工,半双工
- IIC,同步通讯,SCL;SDA数据线,SCL时钟线;多对多通讯;传输速度,标准模式100kbps,快速模式400kbps,高速模式3.4Mbps;半双工
- SPI,同步通讯,SCLK;SCLK时钟线 CS 片选 MOSI主机输出从机输入MISO主机输入从机输出;一对多通讯;全双工
- SPI有几根线,可以去除那些线
- SCLK:时钟线,用于同步数据传输时的时序控制
- MOSI:主设备输出,从设备输入
- MISO:主设备输入,从设备输出
- CS:片选先,用于选择对应的从机设备
- 不需要进行双向通讯,去除输入/输出线
- 不需要选择设备,即一对一通讯,可以去除CS
- TCP和UDP的区别
- 数据的可靠性:TCP提供的是可靠的数据传输,三次握手,UDP无连接的,不可靠的数据通讯
- 通信方式,TCP是面向连接的通信方式,UDP是不需要进行连接