面经二、牛客-嵌入式岗位笔试面试真题讲解

地址变量

内存是很多个空间组成的,空间中存放的数就是变量,每个空间都有一个自己编号属性就是地址

指针就是将某一个空间编号存放变量中,这个变量会执行一个新空间

struct book library;//把library设为一个可以使用book结构体的结构体变量,则library这个变量就包含了其book结构体中的所有元素

结构体

struct  是结构体关键字

book是结构体类型,结构体是一种数据类型

struct book 
{
    char title[MAXTITL];//一个字符串表示的titile 题目 ; 
    char author[MAXAUTL];//一个字符串表示的author作者 ; 
    float value;//一个浮点型表示的value价格; 
};//注意分号不能少,这也相当于一条语句; 

c语言与数据结构

12

1.7  如何使用c语言对寄存器进行操作

由于是寄存器地址、所以先将其强制类型转换为“volatile unsigned long*”,然后解引用地址获得空间地址指向的变量

#define  rBANKCON0  (*(volatile unsigned long *)0x48000004)  

直接解引用赋值

rBANKCON0 = 0x12;

1.12 关键字static的作用是什么?

1、修饰局部变量   ,使得生命周期变长了,存储位置也变了

2、修饰全局变量,使得只能在当前.c文件中使用,不能再其他.c中调用

3、修饰函数,使得只能在当前.c文件中使用,不能再其他.c中调用

1.13  const的作用

(1)const int a;           // a是一个整形常量  
   int const a;           // a是一个整形常量  
(2)const int *a;          // a是一个指向整型常量的指针变量  
   int * const a;         // a是一个指向整型变量的指针常量  
   int const * const a = &b;  // a是一个指向整型常量的指针常量  
(3)char *strcpy(char *strDest, const char *strSrc);  // 参数在函数内部不会被修改  
    const int strcmp(char *source, char *dest);     // 函数的返回值不能被修改

const放在*前是修饰指向的对象,放在*后则是修饰指针本身

1.15  define  与typedef

#define  dPS  struct s *  //简单替换 
dPS  p1, p2;  // struct s * p1, p2; 即定义p1为一个指向结构体的指针,p2为int类型





typedef  struct s *  tPS;
dPS  p1, p2;        //p1和p2都是指向struct s类型的指针变量

16 关键字sizeof的作用是什么?函数strlen()

sizeof   是计算数据的字节数

strlen  是计算数据的长度(不含有\0),也就是计算字符个数

18  extern c

extern "C" 是一个用于 C++ 语言的语法构造,用于指定以 C 语言的方式进行函数名和变量名的链接。

在 C++ 中,默认情况下会启用名称修饰(name mangling)机制,即编译器会修改函数和变量的名称,以包含类型信息等,以便支持函数重载和命名空间等特性。而在 C 语言中,没有名称修饰的概念。

使用 extern "C" 可以告诉编译器按照 C 语言的命名规则进行函数名和变量名的链接,以便实现 C++ 代码与 C 代码的互操作性。这对于在 C++ 代码中调用 C 语言编写的函数或与 C 语言库进行链接非常重要。

19  关键字auto的作用是什么

自动局部变量在进入声明该变量的语句时被建立,退出语句时被注销,仅仅在内部使用

13

2.1 各种指针

一重指针,变量中存放的是一个地址

二重指针,指针变量中存放的是一个指针的地址

指针数组时数组,里面存放的是很多指针  int *a[10]

数组指针是指针,指针指向一个数组的首地址   int (*a)[10]

函数指针是指针,指向一个函数:int (*a)(int)

2.2  有符号转成无符号

有符号 + 无符号  有符号会转换成无符号,正数的补码等于本身,负数的补码是反码加1(负数反码是一个大正数)

原码:为二进制的数,10的原码是0000 1010

反码: 正数的反码与原码相同,负数的反码是0变1,1变0

-10 的原码是 1000 1010  反码是 1111 0101

码:正数的补码与原码相同:如 10 原码为 0000  1010   补码 0000 1010 

          负数的补码为反码 +1    如 -10  反码是 1111 0101  补码是 1111 0110

2.3写出float x与“零值”比较的if语句

计算机在处理浮点数据的时候有误差,所以不能将浮点型变量用 "=="或者"!="与数字比较,应该转换成> 或 < 此类类型

2.4  关于字符串的两种创建形式

char *y = "hello";  字符串常量在内存中是只读的,因此不能修改这个字符串的内容

charz[] = "hello"  以修改数组中的内容

2.5  指针数据 + 普通数据

int 指针  +  int变量  = int指针的值 + 数值大小×int字节大小

2.6  char的数据范围超了就会开始循环

无符号char   0~255

有符号 char  -128 到 127

2.7  char数据范围超就会循环

char类型变量  -128~127,要是一直加下去就会一直循环

2.10  字节对齐

struct A   
{         
     char t : 4;        // 4位         
     char k : 4;        // 4位         
     unsigned short i : 8;  // 8位               
     unsigned long m;     // 4字节  
}; 

前两个一个字节 ,第三个一个字节,最后4个字节,内存对齐 1 + 1+填充+4 = 8
最大变量空间是4,正好8是4的倍数

2.11  字节对齐数

对齐数是1,因为设置了 #pragma pack(1),每个数据存放的地址是需要是1的倍数就可以

即按照成员变量的自然对齐方式来对齐,而采用按照 1 字节对齐的方式。因此,该结构体的各个成员变量会依次紧凑地分布在结构体内存空间中,没有填充字节。

2.12  数组首元素地址与数组地址的区别

int a[10]

&a                a 

数组地址 = 元素首地址

不同之处是 a + 1  就是下一个元素地址,&a+1 是移动一个数组的地址空间大小

2.13

指针 - 变量 = 指针地址移动变量类型空间大小 

2.14  字符数组与字符串数组和字符指针数组

字符数组,数组中存放的是字符也可以存放字符串但是只能放一个

字符串数组,数组中存放的是字符串,char str[2][3] 是字符串数组 char str[2]是字符数组

char *str[] = {"Hello", "World", "C"}; 字符指针数组

2.15

p指向a[1],p[6]表示p向后移动六个数字

2.16

char *str[]   定义一个指针数组
char str[2][3]  定义一个字符串数组

14

3.1  C语言内存分布

全局区(静态区)

.data

初始化不为0的全局变量和静态变量、const型常量在一块区域

.bss段

未初始化的、初始化为0的全局变量和静态变量在相邻的另一块区域

3.2 判断一个系统的大小存储模式

函数中的变量在函数结束后机会注销 

3.7 野指针

指针没有初始化,任何刚创建的指针不能自动创建成为NULL

指针被free或者delete,没有置NULL

指针操作超越了变量的作用范围

3.9  malloc的底层实现

操作系统有一个可用内存块连接成的空闲链表,调用malloc时,它将遍历该链表寻找足够大的内存空间,将该块一分为二(一块系统使用,剩下的一块返回链表),调用free函数,内存块重新接回链表

malloc 是在虚拟内存中申请内存

3.13 内存溢出(内存泄漏的太多了,导致程序运行的内存大于系统提供的内存)

堆内溢出:堆的尺寸设置过小,动态申请的内存没有释放

栈内溢出:栈的尺寸过小、递归层数太深、函数调用层次过深,局部变量分配过大

ARM裸机

17

1.2 cpu、内存、虚拟内存、硬盘

cpu要调用的程序和数据来自硬盘,但是cpu不能直接读写硬盘中数据,所以需要将硬盘中的内存存放在内存中,才能被读写

虚拟内存就是将部分硬盘空间模拟成内存空间,将暂时不运行或者不使用的数据存放在硬盘中,需要的时候再将其存储到内存中

1.19 处理器中断的过程

中断请求 ->中断响应->保护现场->中断服务->恢复现场->中断返回 

中断上下文

  1. 寄存器状态:包括通用寄存器、程序计数器(PC)和堆栈指针(SP)等寄存器的值。保存这些寄存器的值是为了确保中断服务程序执行完毕后,能够正确恢复原来的执行状态。

  2. 栈:保存中断发生时的堆栈信息,以便在中断服务程序执行期间能够正确使用和操作栈。

  3. 硬件状态:保存和恢复与中断相关的硬件状态,例如中断使能位、中断屏蔽位等

1.11 复位中断与其他中断有什么不同

复位中断立即中止当前指令去执行中断、其他中断是等执行完当前指令再响应其他中断

1.12 什么是中断向量,什么是中断嵌套

中断向量:中断服务子程序的入口地址

中断嵌套;中断系统正在运行一个中断服务程序时,有一个优先级更加高的中断源提出请求,这时会暂停当前正在执行的级别低的中断源的程序,去执行优先级更加高的中断源的程序
 

应用编程与网络编程

20

1.1 异步IO和同步IO

同步io:程序需要进行I/O操作的时候会等待该操作执行结束再进行后续

异步io:程序需要进行I/O操作的是时候会继续执行下面的代码,等I/O操作结束才会处理该操作的结果

1.2  进程间通信方式

管道(pipe): 半双工   父子进程之间通信

有名管道:半双工   允许非亲缘进程之间的通信

信号量:是一个计数器,通常作为一个同步机制,用于进程和线程之间的同步

消息队列:是一个消息链表,存放内核中并且由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限的问题

共享内存:一段可以被多个进程共同访问的内存,由一个进程创建。共享内存是最快的ipc

套接字:用于不同主机进程通信

信号:用于通知接收进程某个事件已经发生,是一种比较复杂的通信方式

1.6 什么是进程上下文、中断上下文

1、进程上文:是指进程由用户态切换到内核态是需要保存用户态的cpu寄存器的值,进程状态以及堆栈上的内容。

进程下文:是指切换到内核态后执行的程序,即进程运行内核执行的程序

2、中断上文:硬件通过中断触发信号,导致内核调用中断处理函数,进入内核空间。这个过程中硬件的一些参数需要传递,这些参数就是中断上文

     中断下文:执行在内核空间的中断服务程序

1.13线程间通信和同步方式有哪些?

信号、信号量、互斥锁、条件变量、自旋锁、读写锁

21

2.2   三次握手与四次挥手

2.8 select、poll、epoll

select、poll都是使用轮询调度来。epoll会申请一个epollfd文件,对监管对象进行同一管理,会将哪个流发生了什么事情通知我们

驱动开发与操作系统

22

内核申请函数的时候使用的函数是什么,应用申请内存

kmalloc:申请小块内存,连续的

kzalloc:小块内存连续但是内存块会被初始化为0

vmalloc:大块内存

malloc 应用程序申请内存

自旋锁和信号量使用的注意

1、自旋锁的进程不会睡眠,信号量会睡眠

2、中断就是自旋锁

写一个中断服务程序需要注意什么

1、中断服务程序需要断、尽可能将任务放在底半部

2、中断服务程序不能有阻塞,因为中断期间cpu是完全占据cpu、不存内核调度

3、中断服务程序的返回值要用操作系统定义的宏,不能用自己定义的

mmu

死锁

死锁是指多个进程因为竞争资源而造成的一种僵局,若无外力作用,这些进程将无法向前推进

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值