面试题---C/C++与单片机
1,(正泰低压研究院与翼辉信息):MCU上电后 到 用户main函数运行 之间的过程?
MCU上电也就想到与重启复位,引起复位的原因有很多:
1,上电复位
2,外部产生的手动复位信号
3,执行复位指令
4,看门狗复位
5,and so on
复位原因不同,复位过程却是一样的。
==============================================================
首先了解中断服务子程序是如何被执行的:
单片机内部存储着一张中断向量表,它的每一个表项都存储了一个对应的中断服务子程序的入口地址。这些中断服务子程序包括了外部中断,定时中断等单片机给片上外设还有外部的设备使用的中断,还有MCU内部使用的中断,即异常,他们的优先级通常最高,排在最前面,如:复位(-3),NMI(-2),hard fault(-1),pendsv(可编程),systick(可编程)。
表中的第一项一般是N/A,他实际上存放的是MSP的地址。
上图中的__initial_sp表示的就是栈的结束地址(栈顶地址,栈由高到低生长)
根据上图,中断向量表中第一项存的是栈顶地址,第二项放的是复位的异常向量。
由此,可以解释复位过程:
1,将中断向量表中第一项(栈顶)的地址赋给MSP,栈顶地址。
2,将第二项的地址(复位)装入PC程序计数器
3,从PC寄存器指向的物理地址取出的第一条指令开始执行程序,也就是开始执行复位中断服务程序Reset_Handler
进入Reset_Hanlder后:
;Reset handler
Reset_Handler PROCEXPORT Reset_Handler [Weak]IMPORT __mainIMPORT SystemInitLDR R0,=SystemInit ;执行SystemInitBLX R0LDR R0,=__main ;执行_main子函数,C/C++标准实时库函数里的一个初始化子程序__main 的入口地址(初始化堆栈,初始化映像);最后跳转到 C 程序的 main函数中。BX R0ENDP
(翼辉信息)text段,data段,bss段的区别
1、bss(可读可写)
bss是英文Block Started by Symbol的简称,通常是指用来存放程序中未初始化的全局变量的一块内存区域,在程序载入时由内核清0。BSS段属于静态内存分配。它的初始值也是由用户自己定义的连接定位文件所确定,用户应该将它定义在可读写的RAM区内,源程序中使用malloc分配的内存就是这一块,它不是根据data大小确定,主要由程序中同时分配内存最大值所确定,不过如果超出了范围,也就是分配失败,可以等空间释放之后再分配。
2、text(只读)
text段是程序代码段,在AT91库中是表示程序段的大小,它是由编译器在编译连接时自动计算的,当你在链接定位文件中将该符号放置在代码段后,那么该符号表示的值就是代码段大小,编译连接时,该符号所代表的值会自动代入到源程序中。
3、data(可读可写)
data包含静态初始化的数据,所以有初值的全局变量和static变量在data区。段的起始位置也是由连接定位文件所确定,大小在编译连接时自动分配,它和你的程序大小没有关系,但和程序使用到的全局变量,常量数量相关。
(正泰电器/翼辉信息)结构体和联合体的字节对齐
1,结构体对其的原因:
硬件原因:经过内存对齐之后,CPU的内存访问速度大大提升。
平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据, 否则抛出硬件异常
2,对齐后:sizeof(struct)是内存对齐后所有成员长度的总和
sizeof(union)是内存对齐后最长数据成员的长度(联合体中最长变量的字节数必须可以整除最长变量类型)
举例子:
struct STUDENT
{char a;int b;
}data;sizeof(data)=8分析:char占1个字节,int占用4字节
存储方式以结构体成员中占内存最多的数据类型所占的字节数为标准,所有的成员在分配内存时都要与这个长度对齐。我们举一个例子:我们以上面这个程序为例,结构体变量 data 的成员中占内存最多的数据类型是 int 型,其占 4 字节的内存空间,那么所有成员在分配内存时都要与 4 字节的长度对齐。也就是说,虽然 char 只占 1 字节,但是为了与 4 字节的长度对齐,它后面的 3 字节都会空着|a | - | - | - ||b |
所谓空着其实也不是里面真的什么都没有,它就同定义了一个变量但没有初始化一样,里面是一个很小的、负的填充字。为了便于表达,我们就暂且称之为空好了。
==================================================================
typedef union {char s[9];//9 bytes
int n;//4 bytes
double d;//8 bytes
}U1;问:sizeof(U1)=_________?分析:
U1的最长变量类型为double,8个字节,但是U1的最长变量s[9]的字节数为9,
9不能整除8,为了保持字节对齐,sizeof(U1)=16。typedef union {char s[5];//5 bytes
int n;//4 bytes
double d;//8 bytes}U2;问:sizeof(U2)=_________?分析:
U2的最长变量类型为double,8个字节,但是U2的最长变量d的字节数为8
(雷赛智能)虚函数、纯虚函数
虚函数:虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数,是C++中多态性的一个重要体现。利用基类指针访问派生类中的虚函数,这种情况下采用的是动态绑定技术。
纯虚函数:纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”.纯虚函数不能实例化对象。
(星辰数科)STL库用过吗?常见的STL容器有哪些?算法用过几个?
STL包括两部分内容:容器和算法
容器即存放数据的地方,比如array, vector,分为两类,序列式容器和关联式容器
序列式容器,其中的元素不一定有序,但是都可以被排序,比如vector,list,queue,stack,heap, priority-queue, slist
关联式容器,内部结构是一个平衡二叉树,每个元素都有一个键值和一个实值,比如map, set, hashtable, hash_set
算法有排序,复制等,以及各个容器特定的算法
迭代器是STL的精髓,迭代器提供了一种方法,使得它能够按照顺序访问某个容器所含的各个元素,但无需暴露该容器的内部结构,它将容器和算法分开,让二者独立设计。
Vector是顺序容器,是一个动态数组,支持随机存取、插入、删除、查找等操作,在内存中是一块连续的空间。在原有空间不够情况下自动分配空间,增加为原来的两倍。vector随机存取效率高,但是在vector插入元素,需要移动的数目多,效率低下。
注意:vector动态增加大小时,并不是在原空间之后持续新空间(因为无法保证原空间之后尚有可供配置的空间),而是以原大小的两倍另外配置一块较大的空间,然后将原内容拷贝过来,然后才开始在原内容之后构造新元素,并释放原空间。因此,对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了。
(盛弘电器) KEIL编译输出信息中的ZI-data,RO-data,RW-data分别代表什么
见RT-Thread内存分布一章。
什么是内存泄漏?面对内存泄漏和指针越界,你有哪些方法?
动态分配内存所开辟的空间,在使用完毕后未手动释放,导致一直占据该内存,即为内存泄漏。
方法:malloc/free要配套,对指针赋值的时候应该注意被赋值的指针是否需要释放;使用的时候记得指针的长度,防止越界
头文件的作用、头文件如何来关联源文件?
把所有的函数声明全部放进一个头文件中,当某一个.cpp源文件需要它们时,它们就可以通过一个宏命令 “#include”包含进这个.cpp文件中,从而把它们的内容合并到.cpp文件中去。当.cpp文件被编译时,这些被包含进去的.h文件的作用便发挥了。
注意防卫式声明的重要性
#ifndef <标识>
#define <标识>
...
...
#endif
这个问题实际上是说,已知头文件“a.h”声明了一系列函数(仅有函数原型,没有函数实现),“b.cpp”中实现了这些函数,那么如果我想在“c.cpp”中使用“a.h”中声明的这些在“b.cpp”中实现的函数,通常都是在“c.cpp”中使用#include “a.h”,那么c.cpp是怎样找到b.cpp中的实现呢?
其实.cpp和.h文件名称没有任何直接关系,很多编译器都可以接受其他扩展名。
谭浩强老师的《C程序设计》一书中提到,编译器预处理时,要对#include命令进行“文件包含处理”:将headfile.h的全部内容复制到#include “headfile.h”处。
这也正说明了,为什么很多编译器并不care到底这个文件的后缀名是什么----因为#include预处理就是完成了一个“复制并插入代码”的工作。
程序编译的时候,并不会去找b.cpp文件中的函数实现,只有在link的时候才进行这个工作。我们在b.cpp或c.cpp中用#include “a.h”实际上是引入相关声明,使得编译可以通过,程序并不关心实现是在哪里,是怎么实现的。源文件编译后成生了目标文件(.o或.obj文件),目标文件中,这些函数和变量就视作一个个符号。在link的时候,需要在makefile里面说明需要连接哪个.o或.obj文件(在这里是b.cpp生成的.o或.obj文件),此时,连接器会去这个.o或.obj文件中找在b.cpp中实现的函数,再把他们build到makefile中指定的那个可以执行文件中。
在VC中,一帮情况下不需要自己写makefile,只需要将需要的文件都包括在project中,VC会自动帮你把makefile写好。
通常,编译器会在每个.o或.obj文件中都去找一下所需要的符号,而不是只在某个文件中找或者说找到一个就不找了。因此,如果在几个不同文件中实现了同一个函数,或者定义了同一个全局变量,链接的时候就会提示“redefined”.
(正泰电器) C++文件编译与执行的四个阶段
1)预处理:根据文件中的预处理指令来修改源文件的内容
2)编译:编译成汇编代码
3)汇编:把汇编代码翻译成目标机器指令
4)链接:链接目标代码生成可执行程序
C++的内存管理
在C++中,内存被分成五个区:栈、堆、自由存储区、静态存储区、常量区
栈:存放函数的参数和局部变量,编译器自动分配和释放
堆:new关键字动态分配的内存,由程序员手动进行释放,否则程序结束后,由操作系统自动进行回收
自由存储区:由malloc分配的内存,和堆十分相似,由对应的free进行释放
全局/静态存储区:存放全局变量和静态变量
常量区:存放常量,不允许被修改
(欣威视通)typdef和define区别
#define是预处理命令,在预处理是执行简单的替换,不做正确性的检查
typedef是在编译时处理的,它是在自己的作用域内给已经存在的类型一个别名
typedef (int*) pINT;
#define pINT2 int*
效果相同?实则不同!实践中见差别:pINT a,b;的效果同int *a; int *b;表示定义了两个整型指针变量。而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b。
(翼辉信息)volatile 关键字
A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.
volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。例如:
volatile int i=10;
int a = i;
...
// 其他代码,并未明确告诉编译器,对 i 进行过操作
int b = i;
volatile 指出 i 是随时可能发生变化的,每次使用它的时候必须从 i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在 b 中。而优化做法是,由于编译器发现两次从 i读数据的代码之间的代码没有对 i 进行过操作,它会自动把上次读的数据放在 b 中。而不是重新从 i 里面读。这样以来,如果 i是一个寄存器变量或者表示一个端口数据就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问。
面试题---C/C++与单片机相关推荐
- 51单片机c语言试题及答案,C51单片机期末试卷.doc
单片机期末试卷 一.填空题(36分) 1.C语言程序总是从__________ 函数开始执行的. 2.C语言程序注释有两种方式:__________ ? ,__________ ? . 3.定时/计数 ...
- 51单片机c语言试题及答案,最新单片机试题库分章节答案解析(C语言)
精品文档 器中. 三.选择题 1.51单片机在同一优先级的中断源同时申请中断时,首先响应( A ). A. 外部中断0 B. 定时器0中断 C.外部中断1 D. 定时器1中断 2.下列说法错误的是:( ...
- 电子科技大学现代电子信息系统综合实验课程设计代码(单片机+频率计)1
大家的点赞,关注是对博主最大的鼓励! 简介: 年级:大四 课程性质:必修 期末考核:开卷,现场编程,很难拿高分,两个题,一个单品机(个人认为简单一些),一个FPGA,博主完成了单品机的题,大部分人只能 ...
- 第jiu届蓝桥杯单片机省赛真题_第九届蓝桥杯单片机组省赛试题.pdf
第九届蓝桥杯单片机组省赛试题 "彩灯控制器"的程序设计与调试 (70 分) 一.基本要求 1.1 使用CT107D 单片机竞赛板,完成"彩灯控制器"功能的程序设 ...
- 第十一届 蓝桥杯 单片机设计与开发项目 省赛 程序设计试题及源码
一.试题 1. 基本要求 1.1 使用大赛组委会提供的国信长天单片机竞赛实训平台,完成本试题的程序设计 与调试. 1.2 选手在程序设计与调试过程中,可参考组委会提供的"资源数据包" ...
- 浙江计算机三级考试单片机试题,历年浙江省计算机三级单片机
历年浙江省计算机三级单片机 2007年春浙江省高等学校 计算机等级考试试卷(三级 单片机及嵌入式系统应用) 试题1 判断题 用√和×表示对和错(每小题1分,共10分) 1.满足控制对象的实时性要求是嵌 ...
- 单片机工程师面试题小计
单片机开发常见面试题 1.IIC协议时序图? 2.冒泡排序 下面是最基础的 3.宏定义MIN,得出两个数字的最小值 #define MIN(A,B) ((A) <= (B) ? (A) : (B ...
- 最新 2021年 第十二届 蓝桥杯 单片机设计与开发 省赛 客观试题 个人答案
第十二届蓝桥杯单片机设计与开发项目省赛 第一部分客观试题(30分) 不定项选择(3分/题) (1)MCS-51单片机外部中断1的中断请求标志是( B ). A.ET1 B.IE1 ...
- 计算机三级单片机考试试题及答案,2008秋计算机三级单片机试卷及部分答案
06年至08年共5分浙江省计算机三级考试单片机试卷及答案,试题模板系网上下载,并按照自己理解完成了判断题和选择题及部分解答题,更正了一部分答案,大多数是自己所学的不完全的知识所解答,故有错误之处难免, ...
最新文章
- python爬图片教程_python爬去妹子网整个图片资源教程(最详细版)
- 从CPU缓存看缓存的套路
- Rancher 2.0正式发布:简化、加速企业Kubernetes落地
- 安阳职业技术学院计算机录取分数线,安阳职业技术学院录取分数线2021是多少分(附历年录取分数线)...
- 数据结构之线段树入门(单点更新区间查询)
- 可做fft分析吗_小吃店生意好做吗,小吃业行情分析
- postgresql删除索引_PostgreSQL 13 发布,索引和查找有重大改进
- Postgre体系结构图
- 支付宝 android 2.3,app被拒记录-2.3-包含支付宝
- java代码解决的问题_java代码规范问题及解决方案
- SAP License:对不起,“下一代ERP”仍旧是现在的ERP
- 面向对象 —— 类设计(九) —— 类设计的内在一致性
- 经典的Fisher-Yates Shuffle算法
- AVOD-代码理解系列(四)
- 使用 Premiere 制作视频简介
- 初中计算机软件课后反思,信息技术的教学反思
- 【愚公系列】2021年12月 攻防世界-简单题-CRYPTO-005(Railfence)
- 手把手教你mockjs实际项目快速搭建
- (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
- 关于Vue中keep-alive的作用是什么?怎么使用?
热门文章
- 动态链接库、静态链接库
- Latex导入pgf图片
- PORIS门禁控制器
- python中plotly subplot的用法_matplotlib 中的subplot的用法
- python中去掉字符串中的空格
- SQL修改表结构写法
- uvalive_6528_Disjoint water supply(DAG)
- 开放式基金公司网上直销支持卡种及申购费率
- 七月学习之E6、ES7、ES8、ES9、ES10、ES11新特性
- “华为”和“荣耀”的区别,双品牌满足我和爸妈的不同需求