嵌入式_复习
函数指针与指针函数
1 |
|
指针大小
指针大小与操作系统的位数有关,32位指针大小是4个字节,64位指针大小是8个字节
1 |
|
sizeof与strlen的区别
- sizeof是一个运算符,strlen是一个函数,需要包含string.h头文件
- sizeof计算的是所占内存的大小,strlen计算的是字符串的长度。字符串以\0结尾,\0是不需要计算长度的
- sizeof可以计算其他类型int,float等,strlen一般用于字符串的长度
1 |
|
C语言内存分配方式
- 静态存储器分配,例如全局变量,静态变量。
- 栈上分配,函数中定义的局部变量
- 堆上分配,malloc, new
数组指针和指针数组
- 数组指针指的是指向数组的指针,本质是一个指针
- 指针数组本质是一个数组,里面的每个元素都是指针
1 |
|
struct结构体和union联合体
- union共享一块内存地址,大小 = 成员中占内存最大的成员的大小
- 结构体不同成员放在不同的内存地址。大小 = 所有成员大小之和(字节对齐)
野指针
野指针是指向不可用内存的指针
当指针被创建的时候,没有赋值这个时候指针就成为了野指针
当指针被free或者delete后如果没有把指针赋值为NULL,这个时候也是野指针
当指针越界的时候也是野指针
数组和链表的区别
- 数组的地址空间是连续的
- 链表的地址空间是不连续的
- 数组的访问速度比较快,数组直接通过下标就能访问,链表需要遍历
- 链表增删改的速度比较快
define与typedef的区别
define是一个预处理指令,typedef是关键字
define不会做正确性检查,直接进行替换,typedef会做正确性检查
define没有作用域的限制,typedef有作用域的限制
Static的作用
定义一个静态变量或者静态函数
在函数中定义变量,变量只会初始化一次
定义的静态变量或者函数只能在当前文件中使用,作用域的限制
在函数内部定义的静态变量无法被其他函数使用
内存泄露
内存泄露指的是在程序运行的时候,动态分配的空间没有被回收或者正常释放,导致这个内存空间还占据着系统资源
内存对齐
内存对齐是在储存数据时,将数据按照一定的规则放置在内存中的过程
数组名和指针的区别
数组名就是数组首元素的地址,也可以看做一个常量指针,这个是不能修改指向的
使用指针访问数组的时候需要使用到解引用*,使用指针访问数组是间接访问,使用数组名访问数组是直接访问
使用sizeof对指针和数组名进行计算的时候是不同的,指针的大小和编译器的位数有关,sizeof数组名是整个数组的大小
指针常量和常量指针
常量指针是指向一个常量的指针,这个指针无法修改所指向的数据,但是可以修改指向
1 |
|
指针常量是指针是一个常量,指针所指向的地址是固定的 ,但是可以修改地址中的值
1 |
|
堆和栈的区别
创建方式不同,栈是系统自动创建(栈主要用于保存局部变量),当函数执行完成,栈被销毁
堆是程序员手动创建和释放的,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++中的类有几个访问权限
公有的,私有的,受保护的
程序分为几个段
代码段,用于储存程序的可执行指令,一般是只读的,防止被修改
数据段,用于储存已经初始化的全局变量和静态变量
bss段,储存没有初始化的全局变量和静态变量
堆,malloc和free进行管理
栈,储存局部变量,系统申请和释放
队列和栈的区别
访问的方式,栈是先进后出,队列先进先出
栈,只能在栈顶进行操作,队列,在队尾进行插入,在对头进行删除
栈主要用于函数调用,表达式求值,队列,任务调度,广度优先搜索
c文件执行流程
预处理,将头文件宏定义进行展开,生成没有注释的源代码,.i文件
编译,将预处理得到的源代码转为汇编代码 .s文件
汇编,将汇编代码转为机器码 生成 .o文件
链接 ,将全部的.o文件链接为可执行程序
SPI和IIC的寻址区别
SPI MISO MOSI SCLK CS 通过cs线片选引脚,选择对应的设备进行通信
IIC SDA SCL 通过从机地址进行寻址7位和10位方式
进程间通信有几种方式,哪几种需要借助内核
管道,命名管道,共享内存,信号量,消息队列,套接字,信号
什么是DMA
DMA是一种无需cpu参与就可以让外设和系统之间的数据进行双向数据传递,可以提高效率
进程有几个状态
创建状态 当调用fork进入创建状态
就绪状态
运行状态
阻塞状态
终止状态
僵尸进程,孤儿进程,守护进程
僵尸进程,使用fork子进程后,如果子进程退出,父进程并没有调用wait或者waitpid函数获取子进程的退出状态,那个子进程的信息还保存在系统中,这个时候子进程就叫做僵尸进程
父进程异常结束,子进程就会变成孤儿进程,会被init1号进程收养
在父进程创建出子进程后故意把父进程结束,那个这个子进程就是守护进程
FreeRTOS的调度算法
抢占式调度,高优先级的任务可以打断低优先级任务的执行,适用于优先级不同的任务
时间片轮转,相同优先级的任务具有相同大小的时间片
协作式调度,让出cpu,通过信号量等切换任务
RTOS中任务同步的方式
队列,信号量,互斥量,事件组,任务通知
FreeRTOS任务的状态
就绪态,运行态,阻塞态,挂起态
RS232和RS485的区别
RS232是全双工通信,tx,rx,gnd
rs485是半双工通信 只有两根信号线。差分传输
抗干扰能力,rs485抗干扰能力比rs232更强,使用双绞线将2根信号线缠绕在一起
rs232一般用于点对点通信,rs485多对多,一对多,工业控制
485传输距离1.5km 232只有15m
232传输速率比较低,485传输速率比较高
析构函数与构造函数
构造函数,初始化对象,设定初始值, 没有返回值,多个重载版本
析构函数 释放资源,清理操作,没有参数也没有返回值,不能重载
大小端
多字节的数据在内存中的存储顺序方式,在不同的计算机中使用不同的字节序来表示数据
大端储存,高字节在低地址,低字节在高地址
小端存储,低字节在低地址,高字节在高地址
0x12345678, 假设第一个字节是0x78,那么为小端存储,第一个字节为0x12,是大端存储
系统调用
用户和内核之间的接口,通过接口可以使用用户空间访问到内核空间,直接访问内核空间是非常不安全的,导致内核崩溃
软件IIC和硬件IIC的区别
软件,通过控制gpio来模拟scl和sda信号来产生iic的时序
硬件,mcu内部的专用硬件模块来产生时序,软件只负责发出命令
Linux驱动分类
字符设备驱动,用于处理顺序数据的读写操作,适用于终端,串口,led,蜂鸣器
块设备驱动,主要用于处理以块为单位的数据读写操作,硬盘。ssd
网络设备驱动,网卡设备
Linux与RTOS的区别
应用场景,linux桌面计算机,服务器,嵌入式系统, rtos嵌入式系统
linux不保证实时性,rtos提供严格的实时性保证,任务的调度和执行时间非常可预测,任务的响应都非常快
linux占用资源多,rtos轻量级操作系统
linux有虚拟内存,内核空间和用户空间,rtos没有虚拟内存,也没有用户空间和内核空间
linux的扩展非常高