面试(五)

目录

1. 知道大顶堆小顶端吗,代码怎么区分大顶端小顶端

2. 计算机中栈地址与内存地址增长方向相反吗?

3. %p和%d输出指针地址

4. 为什么定义第二个变量时候,地址反而减了

5. 12,32,64位中数据的占字节?

6. IIC可以接入多少个设备

7. STM32的三级流水线

8. STM32F4中初始化硬件IIC代码

9. STM32启动流程:初始化确定启动方式->sp,pc指针->系统时钟初始化->初始化用户堆栈->跳到main()

10. STM32F4初始化蓝牙串口和蓝牙HC-05所有配置的代码

11. MCU/DSP

12. 学一个新板子,我们要先知道什么

13. STM32F4中函数怎么压栈到寄存器

14. STM32为什么中断会进入UART4_IRQHandler()

15. STM32收到串口数据时寄存器的状态

16. C++中链表的插入,删除


1. 知道大顶堆小顶端吗,代码怎么区分大顶端小顶端

(1)大顶端: 将数据的最高有效字节存储在起始地址,即高位字节在前。小顶端: 将数据的最低有效字节存储在起始地址,即低位字节在前。

假如现有一32位int型数0x12345678,那么其MSB(Most Significant Byte,最高有效字节)为0x12,其LSB (Least Significant Byte,最低有效字节)为0x78,在CPU内存中有两种存放方式:(假设从地址0x4000开始存放)[一个地址下存放一个字节]

(2) 代码区分大顶端和小顶端。

代码1:

#include <stdio.h>int main() {unsigned int x = 0x12345678;unsigned char *p = (unsigned char *)&x;if (*p == 0x78) {printf("小端");} else if (*p == 0x12) {printf("大端");} else {printf("未知");}return 0;
}

指针类型为char而不是int,是因为我们只关心内存中的最低有效字节(LSB),即最低位的字节。在这个例子中,我们想要检查一个整数的字节序,所以我们需要将整数的地址转换为一个字符指针,然后通过解引用这个指针来访问最低有效字节。这样我们就可以根据这个字节的值来判断整数的字节序是大端还是小端。

代码2:

#include <stdio.h>union {unsigned int i;unsigned char c[4];
} u;int main() {u.i = 0x12345678;if (u.c[0] == 0x78) {printf("小端");} else if (u.c[0] == 0x12) {printf("大端");} else {printf("未知");}return 0;
}
在这个例子中,我们使用了一个联合体,它包含一个整数和一个字符数组。我们将整数赋值给联合体的整型成员,然后通过访问字符数组的第一个元素来判断字节序。如果第一个元素的值是0x78,那么就是小端;如果第一个元素的值是0x12,那么就是大端;否则就是未知。

2. 计算机中栈地址与内存地址增长方向相反吗?

计算机内存地址增长的方向是自小到大。栈地址增长方向与内存地址增长方向相反。

3. %p和%d输出指针地址

是把指针变量p中存储的a的地址以十六进制形式输出,%d是吧p中存储的a的地址以十进制形式输出。输出的都是p的值,不要理解成%p,是把p的地址输出。

//3和4的代码
#include <stdio.h>int main()
{int a = 2;int b = 3;char c = 'a';int *p = &a;printf("%d\r\n",&a);printf("%p\r\n",&a);printf("%p\r\n",&b);printf("%p\r\n",&c);printf("%p\r\n",p);p++;printf("%p\r\n",p);return 0;
}

4. 为什么定义第二个变量时候,地址反而减了

因为栈向下增长,所以先声明的地址大,后声明的地址小。栈的这种向下增长的设计使得它在处理函数调用时非常高效。每次函数调用时,都会在栈顶创建一个新的栈帧,用来存放该函数的局部变量和返回地址。当函数执行完毕返回时,对应的栈帧会被自动清理,栈顶恢复到调用前的位置。

5. 12,32,64位中数据的占字节?

8位系统32位系统64位系统
字符型1字节1字节1字节
整型2字节4字节4字节

长整型

4字节4字节4字节

浮点型

无统一标准4字节4字节

双精度浮点型

无统一标准8字节8字节

指针类型

无统一标准4字节8字节

6. IIC可以接入多少个设备

IIC最多可以接入2的7次方-1个设备,一共是127个。
第一个字节(为slave address)由7位地址和一位R/W读写位组成的,这字节是个器件地址。
首先,你要知道:常用IIC接口通用器件的器件地址是由种类型号,及寻址码组成的,共7位。
如格式如下: D7 D6 D5 D4 D3 D2 D1 D0
1-器件类型由:D7-D4 共4位决定的。这是由半导公司生产时就已固定此类型的了,也就是说这4位已是固定的。2-用户自定义地址码:D3-D1共3位。这是由用户自己设置的,通常的作法如EEPROM这些器件是由外部IC的3个引脚所组合电平决定的(用常用的名字如A0,A1,A2)。这也就是寻址码。
所以为什么同一IIC总线上同一型号的IC只能最多共挂8片同种类芯片的原因了。3-最低一位就是R/W位。这位不用我多说了

7. STM32的三级流水线

三个主要步骤:取值,译码和执行,取指阶段是从存储器中加载指令到指令寄存器;译码阶段是解释指令含义并准备执行所需的操作;执行阶段则实际完成指令的操作,并将结果写回寄存器。流水线允许多个指令在不同的阶段同时进行处理。例如,当第一条指令处于执行阶段时,第二条指令可能正在进行译码,而第三条指令则在取指阶段

8. STM32F4中初始化硬件IIC代码

#include "stm32f4xx.h"void I2C1_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;I2C_InitTypeDef I2C_InitStructure;// 开启I2C1时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);// 开启GPIOB时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);// 配置PB6和PB7为复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(GPIOB, &GPIO_InitStructure);// 连接PB6和PB7到I2C1的SCL和SDA引脚GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);// 初始化I2C1I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 100000; // 设置I2C时钟速率为100kHzI2C_Init(I2C1, &I2C_InitStructure);// 使能I2C1I2C_Cmd(I2C1, ENABLE);
}

9. STM32启动流程:初始化确定启动方式->sp,pc指针->系统时钟初始化->初始化用户堆栈->跳到main()

10. STM32F4初始化蓝牙串口和蓝牙HC-05所有配置的代码

#include "stm32f4xx.h"
#include "usart.h"
#include "bluetooth.h"void Bluetooth_Init(void)
{// 初始化USART1,用于蓝牙通信USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 9600; // 设置波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 设置数据位长度为8位USART_InitStructure.USART_StopBits = USART_StopBits_1; // 设置停止位为1位USART_InitStructure.USART_Parity = USART_Parity_No; // 不使用奇偶校验USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 设置为收发模式USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE); // 使能USART1// 初始化蓝牙模块Bluetooth_Config();
}void Bluetooth_Config(void)
{// 发送AT指令来配置HC-05模块// 设置蓝牙名称Bluetooth_SendCommand("AT+NAME=HC-05");// 设置蓝牙配对密码Bluetooth_SendCommand("AT+PSWD=1234");// 设置蓝牙工作模式为可连接模式Bluetooth_SendCommand("AT+MODE=0");// 开启蓝牙模块Bluetooth_SendCommand("AT+POWE=1");
}

11. MCU/DSP

MCU是将计算机的主体部分集成在一块半导体上的单片机。DSP是专门用于数字信号处理的微处理器,特别是擅长处理如离散余弦变换、快速傅里叶变换等复杂计算。

12. 学一个新板子,我们要先知道什么

  • 核心处理器:了解SOC使用的中央处理单元类型,如ARM Cortex系列,以及其基本参数,包括频率、核心数量等。
  • 存储选项:研究SOC的内存布局,包括RAM和FLASH的容量,及其对程序执行和数据存储的影响。
  • 输入输出端口:熟悉可用的GPIO数量及其配置选项,理解如何通过这些接口与外部设备进行交互

13. STM32F4中函数怎么压栈到寄存器

在STM32F4中,函数压栈到寄存器涉及对特定寄存器的保存与恢复,确保程序的正常运行和中断处理的正确返回。具体来说,当进行函数调用或响应中断时,处理器自动把PSR, PC, LR, R12, R3, R2, R1, R0等寄存器的内容按照一定顺序压入栈中.手动需要压栈的寄存器包括R11, R10, R9, R8, R7, R6, R5, R4.

14. STM32为什么中断会进入UART4_IRQHandler()

原因是在于STM32微控制器的中断处理机制,该机制通过硬件触发和自动执行预定义的中断服务程序来响应特定的事件。

中断初始化和配置:在STM32中,要使能串口的中断功能,首先要正确配置相关的控制寄存器和中断向量。这包括启用UART4时钟,配置UART4的工作模式(如波特率、数据位等),以及设置中断优先级和使能特定类型的中断源(例如接收中断、发送完成中断等)

中断向量表的角色:启动文件startup_stm32f4xx.s中包含了一个中断向量表,该表为每个中断源指定了一个处理函数。对于UART4,这个向量表中会包含DCD UART4_IRQHandler这样的指令,直接指向了UART4_IRQHandler()函数的内存地址。当UART4的中断条件满足时,处理器会自动跳转到这个地址执行中断服务程序。

硬件自动压栈操作:响应中断时,Cortex-M内核将自动进行压栈操作,保存被中断的程序执行状态,包括程序计数器(PC)、状态寄存器(PSR)、以及一些关键的寄存器如R0-R3、R12、LR、PC、xPSR的值。这一过程完全由硬件自动完成,确保了中断处理完成后能够恢复到原来被打断的程序继续执行。

中断服务程序的执行:一旦处理器响应了中断并进入了UART4_IRQHandler(),它就会执行该函数中的代码来处理具体的中断事件。这包括读取UART4的数据寄存器以获取接收到的数据,或者根据设置处理其他类型的UART中断事件。

从中断返回:处理完中断事件后,UART4_IRQHandler()函数执行结束,内核会自动恢复之前保存的寄存器值,并从中断发生前的指令继续执行。这个过程称为异常退出处理,确保了程序的正确流程和数据的完整性。

错误处理和调试:如果中断处理过程中遇到问题,如硬件错误或配置不当,可能会触发额外的错误处理机制。在这种情况下,开发人员应检查配置是否正确,以及硬件连接是否稳定可靠。

15. STM32收到串口数据时寄存器的状态

STM32的USART是用于处理串口通信的外设,具备发送和接收数据的能力。而串口接收时,主要是状态寄存器和数据寄存器发生变化。

状态寄存器(USART_SR):此寄存器用于检测USART的当前状态,其中包括多个状态位,如发送寄存器空位、发送完成位、读数据寄存器非空位等。其中最重要的两位是RXNE(读数据寄存器非空)和TC(发送完成)

数据寄存器(USART_DR这是一个双向寄存器,分为发送数据寄存器(TDR)和接收数据寄存器(RDR)。向USART_DR写入数据时,数据会被存储在TDR内,用于后续的发送操作;从USART_DR读取数据时,会自动从RDR提取数据。

16. C++中链表的插入,删除

#include <iostream>
using namespace std;struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};// 在链表头插入节点
void insertAtHead(ListNode* &head, int val) {ListNode* newNode = new ListNode(val);newNode->next = head;head = newNode;
}// 在链表尾部插入节点
void insertAtTail(ListNode* &head, int val) {ListNode* newNode = new ListNode(val);if (head == NULL) {head = newNode;return;}ListNode* temp = head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;
}// 在指定位置插入节点
void insertAtPosition(ListNode* &head, int position, int val) {if (position == 0) {insertAtHead(head, val);return;}ListNode* newNode = new ListNode(val);ListNode* temp = head;for (int i = 1; i < position && temp != NULL; i++) {temp = temp->next;}if (temp == NULL) {cout << "Invalid position!" << endl;return;}newNode->next = temp->next;temp->next = newNode;
}// 删除指定值的节点
void deleteNode(ListNode* &head, int val) {if (head == NULL) {return;}if (head->val == val) {ListNode* temp = head;head = head->next;delete temp;return;}ListNode* temp = head;while (temp->next != NULL && temp->next->val != val) {temp = temp->next;}if (temp->next == NULL) {cout << "Value not found!" << endl;return;}ListNode* toDelete = temp->next;temp->next = temp->next->next;delete toDelete;
}// 删除指定位置的节点
void deleteAtPosition(ListNode* &head, int position) {if (head == NULL) {return;}if (position == 0) {ListNode* temp = head;head = head->next;delete temp;return;}ListNode* temp = head;for (int i = 1; i < position && temp != NULL; i++) {temp = temp->next;}if (temp == NULL || temp->next == NULL) {cout << "Invalid position!" << endl;return;}ListNode* toDelete = temp->next;temp->next = temp->next->next;delete toDelete;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/846579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

物质的量质量,它们可不是一个概念

物质的量&质量&#xff0c;它们可不是一个概念。 物质的量&质量 乍一听物质的量&#xff0c;还以为是和质量有什么关系&#xff0c;是不是&#xff1f;其实物质的量和质量没什么直接的联系。 物质的量是国际单位制中7个基本物理量之一&#xff0c;其符号为n&#xf…

Aras Innovator-Team(群组)的使用方法

当Aras Innovator在处理权限时&#xff0c;在不使用Team的情况下&#xff0c;系统的权限配置可以满足大部分业务场景&#xff0c;如&#xff1a;常见的按照组织架构&#xff0c;成员和角色分配权限&#xff0c;按照生命周期分配权限等。 如果遇到比较复杂的权限需求&#xff0c…

AltiumDesigner/AD添加数据库连接

1.首先确保本机电脑有无对应的数据库驱动&#xff0c;例如我这边要添加MySQL的数据&#xff0c;则需要首先下载MySQL数据驱动&#xff1a;MySQL :: Download MySQL Connector/ODBC (Archived Versions) 2.运行“odbcad32.exe”&#xff0c;如下图添加对应的数据库配置&#xf…

【C/C++】C/C++车辆交通违章管理系统(源码+数据文件)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

面试题:useEffect的Clean Up 什么时候触发?

​ useEffect作为做常用的Hook&#xff0c;以下三个知识点你有必要了解下~ 防止写出奇怪的代码祸害队友&#xff0c;而我不幸就是这个受害者&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; useEffect的依赖项为空 useEffect的dependencyList作为一个可选参数…

Pytest框架中用例用例执行常用参数介绍

pytest 支持通过命令行参数来定制测试运行的方式。以下是一些常用的 pytest 执行参数介绍。 学习目录 -q 或 --quiet: 安静模式&#xff0c;只显示进度和摘要 -s : 选项允许在测试的输出中捕获 stdout 和 stderr。 -v : 选项会使 pytest 的输出更加详细。 -k &#xff1a;…

Git 恢复已删除的branch

六一节晚上改了点code, 做完之后commit, 然后误删了这个branch, 并且新建了branch. 那么怎样恢复已删除的branch呢&#xff1f; 网上查询一番&#xff0c;找到了答案&#xff1a; 1. git reflog 找到被删的branch中最后一笔commit, 记录它的SHA1。 怎么看SHA1是被删除的bra…

鸿蒙应用Stage模型【应用/组件级配置】

应用/组件级配置 在开发应用时&#xff0c;需要配置应用的一些标签&#xff0c;例如应用的包名、图标等标识特征的属性。本文描述了在开发应用需要配置的一些关键标签。 应用包名配置 应用需要在工程的AppScope目录下的[app.json5配置文件]中配置bundleName标签&#xff0c;…

Python PyInstaller打包方法介绍

为了将开发好的Python工具交付给其他人使用&#xff0c;除了在目标电脑部署Python编译环境以外&#xff0c;我们还可以将它打包成可执行文件&#xff0c;这样目标电脑不需要安装Python环境就可以运行。将Python程序打包成可执行文件的方法有多种&#xff0c;比如Nuitka、PyInst…

微博增强-tampermonkey脚本实现网页管理悄悄关注

不是很明白微博为什么不出个x的列表功能&#xff0c;毕竟现在信息洪流&#xff0c;有些东西只是要看要了解&#xff0c;但不希望天天在首页轰炸眼睛&#xff0c;扰乱心智。 这个tampermonkey脚本适配了pc web和手机pwa版本&#xff08;weibo.com/m.weibo.cn&#xff09;,解决了…

golang map部分原理源码个人走读-附个人理解过程图解

近期再写map的demo时出现了下面一段报错&#xff0c;于是带着疑惑去看了一下源码 目的&#xff1a;主要想知道为啥map不让并发读写 fatal error: concurrent map read and map write 一.map的数据结构 先有个印象&#xff0c;后续会详细介绍 // A header for a Go map. ty…

NDIS Filter开发-OID 请求

NDIS 定义对象标识符 (OID) 值来标识适配器参数&#xff0c;其中包括操作参数&#xff0c;例如设备特征、可配置的设置和统计信息。 Filter驱动程序可以查询或设置基础驱动程序的操作参数&#xff0c;或过滤/覆盖顶层驱动程序的 OID 请求。 NDIS 还为 NDIS 6.1 及更高版本的Fi…

Informer

I n f o r m e r Informer Informer 摘要&#xff1a; 长序列时间序列的预测 i n f o r m e r informer informer优点&#xff1a; P r o b s p a r e Probspare Probspare自关注机制&#xff0c;在时间复杂度和内存使用方面达到 O ( N l o g N ) O(NlogN) O(NlogN),在序列依…

IP协议1.0

基本概念&#xff1a; • 主机: 配有IP地址, 但是不进⾏路由控制的设备; • 路由器: 即配有IP地址, ⼜能进⾏路由控制; • 节点: 主机和路由器的统称; IP协议的报头 • 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4. • 4位头部⻓度(header length): IP头部的⻓…

mybatis增删改查模板设置及设置调用

mybatis增删改查模板设置 系统配置文件完成以及连接好数据之后&#xff0c;就可以用这个mybatis了&#xff0c;首先写这个数据库的增删改查模板StashMapper.xml&#xff0c;这个东西是要放在DAO层中的奥&#xff0c;切记。 1.编写mybatis对应数据库的增删改查模板 在我的Sta…

DKTCDR:Domain-Oriented Knowledge Transfer for Cross-Domain Recommendation

Domain-Oriented Knowledge Transfer for Cross-Domain Recommendation IEEE(CCF B.SCI 1)-Guoshuai Zhao, Xiaolong Zhang, Hao Tang, Jialie Shen, and Xueming Qian-2024 思路 在CDR中,构建连接两个域的桥梁是实现跨域推荐的基础。然而现在的CDR方法往往在连接两个域时忽…

软件测试进阶

目录 一、自动化测试 1.概念 2.Selenium 2.1 概念 2.1.1 Selenium是什么&#xff1f; 2.1.2 Selenium特点 2.1.3 工作原理 2.2 SeleniumJava环境搭配 2.3 定位元素 2.3.1 CSS语法 2.3.2 XPath语法 2.4 应用 2.4.1 点击提交文本 2.4.2 模拟输入 2.4.3 清除文本 2…

统信UOS桌面操作系统1070上使用notepad--文本编辑器

原文链接&#xff1a;统信UOS桌面操作系统1070上使用notepad–文本编辑器 Hello&#xff0c;大家好啊&#xff01;今天我要向大家推荐一款在统信UOS桌面操作系统1070上非常好用的文本编辑器软件——“notepad–”。这款软件功能强大、操作简便&#xff0c;特别适合开发人员和日…

车载软件架构 - AUTOSAR 的信息安全框架

车载软件架构 - AUTOSAR 的信息安全架构 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗…

Nginx企业级负载均衡:技术详解系列(17)—— 长连接优化策略与下载服务器高效搭建

你好&#xff0c;我是赵兴晨&#xff0c;97年文科程序员。 今天咱们来聊聊Nginx的两个知识点&#xff1a;Nginx的长连接优化、如何将Nginx配置成下载服务器。 长连接配置详解 在Nginx的配置中&#xff0c;长连接是一个重要的性能优化手段。它允许一个TCP连接上发送多个请求和…