嵌入式笔试题解析及答案解析

📜作者:不想脱发的基兄

📺专栏:《嵌入式面试》

📣格言:这个世界上肯定有另一个我,做着我不敢做的事,过着我想过的生活。

前言

2022年秋招我面试嵌入式MCU开发方向,经过了多场的笔试与面试,在准备的过程中看了非常多的资料,我的汇总的笔记一直写在有道云笔记中,没有分享出来。现在已经到了23年春招了,特此整理后分享出来。资料看过了觉得不错就保存下来了,如果有不对的地方,欢迎批评指正,侵权联删!

1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)

#define YEAR_SEC 365*24*3600UL 

2. 写一个“标准"宏MAX,这个宏输入两个参故并返回较大的一个

#define MAX(a,b) ((a)>(b))?(a):(b)

3. 已知一个数组 table,用一个宏建义,求出数据的元素个数

#define LEN(a) sizeof(a)/sizeof(a[0])

4. 如何在两个c文件中访间对方的静态变量和全局变量?

答:静态变量被修饰之后,能跨文件访问,普通的全局变量可以利用extern关键字做外部声明。静态变量可以通过使用定义函数的结构,跨文件获取静态变量的值。
例:

// utils.h
extern int getStaticVar();

// utils.c
#include "utils.h"

static int staticVar = 10;

int getStaticVar() {
    return staticVar;
}

// main.c
#include <stdio.h>
#include "utils.h"

int main() {
    int var = getStaticVar();
    printf("Static var is %d", var);
    return 0;
}

在这个例子中,utils.h 头文件声明了 getStaticVar() 函数。utils.c 实现了这个函数,并定义了一个静态变量 staticVar。这个静态变量不能通过在头文件中声明而直接访问,因此需要提供一个函数 getStaticVar() 来获取这个变量的值。在 main.c 文件中,我们包含了头文件并使用 getStaticVar() 函数来获取静态变量的值。

5. 关键字volatile有什么含意,并给出三个不同的例子?

答:
(1)含义:volatile是让处理器在访问修饰的变量时不能进行优化处理,需要小心访问该变量;
(2)使用方式

  • 某函数与中断函数共享全局变量时,需要使用volatile修饰;
  • 多线程操作时,多个线性共享一个全局变量,使用volatile修饰;
  • 裸机编程,变量指向某一地址,需要使用volatile修饰。
  • 6. 用变量a给出下面的定义

    (1)一个整型数
    (2) 一个指向整型数的指针
    (3)一个指向指针的指针,它指向的指针是指向一个整型数
    (4) 一个有10个整型数的数组
    (5)一个有10个指针的数组,该指针是指向一个整型数的
    (6)一个指向有I0个整型数数组的指计
    (7)一个指向函数的指针,该函数有一个整型参数并返回一个整型数
    (8)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数
    参考答案

        int a;				//整型数
        int *b = &a;		//指向整型数的指针
        int **c = &b;		//指向指针的指针
        int d[10];			//一个有10个整型数的数组
        int *e[10];			//一个有10个指针的数组
        int (*f)[10];		//一个指向有I0个整型数数组的指计
        int *g(int);		//一个指向函数的指针
        int (*h[10])(int);	//一个有10个指针的数组
    

    7. 函数fiunc输入参数为0x12345678时的返回值为多少?写出你对函数fune的理解。

    题目代码

    unsigned long func(unsigned long dat)
    {
        unsigned long t = 0;
        while(dat)
        {
            dat&=dat - 1;
            t++;
        }
        refurn t;
    }
    

    答:

    (1)返回值:返回dat转换为2进制有多少个1的个数。
    (2)功能:dat经过多少次与自己本身减1进行位与之后变为0,返回值是dat转换为二进制里面有多少个1的个数。

    8、用C语言设计一个函数,对指定的数组排序(从小到大,用2种方法)

    例1:冒泡排序

    void maopao(int a[],int len)
    {
        int i,j,t;
        for(i=0; i<len;i++)    
        {
            for(j=i+1; j<len;j++)
            {
                if(a[i]>a[j])
                {
                    t = a[i];
                    a[i] = a[j];
                    a[j] = t;
                }
    
            }
        }
    }
    

    例2:快速排序

    int partition(int numbers[], int len)    //递归实现
    {
        int tmp = numbers[0];
    
        int low = 0;
        int high= len-1;
    
        while(low < high)
        {
            while(low<high && tmp<=numbers[high]) high--;
            numbers[low] = numbers[high];
    
            while(low<high && numbers[low]<=tmp) low++;
            numbers[high] = numbers[low];
        }
    
        numbers[low] = tmp;
        return low;
    }
    
    void quick_sort(int numbers[], int len)
    {
        if(len <= 1)
            return;
    
        int pivot = partition(numbers, len);
    
        quick_sort(numbers, pivot);
        quick_sort(numbers+pivot+1, len-pivot-1);
    }
    

    9. 在嵌入式系统中串口数据接收时,通常会将接收到的字节数据顺序存入一个数组,有时也会顺序存入一片内存空间。

    (1)请用C语言实现串口接收中断服务程序,将接收到的数据依次存入绝对地址0x80000000开始的内存区,如果接收到0xC0,则将接收完成标识整形变量g_flagRxOk置1,以通知主函数做串口数据解析处理,并为下次接收做好准备。(注:串口接收数据寄存器地址为Oxa0000000)
    参考代码

    typedef unsigned char uint8_t; 
    typedef unsigned long uint32_t; 
    
    volatile uint32_t i = 0; 
    void USARTX_IRQHandler(void)   //x根据串口号改变为数字,串口1中断服务程序
    {
    
        //1个字节产生一次中断 
        uint8_t d;
        if(USART_GetITStatus(USARTX, USART_IT_RXNE) != RESET)  //接收数据寄存器非空中断
        {
            //接收串口数据
            d = *(volatile uint8_t*)0xa0000000;          //读取    
            *(volatile uint8_t*)(0x80000000+i) = d;    //写入 
            i++;                                     //全局变量,主函数做串口数据解析处理后值0
            if(d == 0xC0)
            {
            g_flagRxOk = 1;
    
            }            
            
                 //清空串口接收中断标志位
            USART_ClearITPendingBit(USARTX, USART_IT_RXNE);
            }              
    } 
    

    (2)在大端系统中,假设在0x80000000~0x80000003地址空间存储的数据分别为0x12,0x34,0x56和0x78,请问如果直接32位数据读取操作的读取结果值是多少?
    00010010 00110100 01011000

    答:大端:读取到0x12345678

    参考链接

    [1]超详细十大经典排序算法总结(java代码)c或者cpp的也可以明白
    [2]嵌入式系统数据存储的大端模式小端模式应用举例0x12345678存储到8000H

    本栏前文

    [1]【嵌入式面试】2022年嵌入式经典面试题汇总(C语言)
    [2]【嵌入式面试】2022年嵌入式经典面试题汇总(数据结构)
    [3]【嵌入式面试】2022年嵌入式经典面试题汇总(Linux | 文件IO)
    [4]【嵌入式面试】2022年嵌入式经典面试题汇总(系统编程)
    [5]【嵌入式面试】2022年嵌入式经典面试题汇总(网络编程)

    物联沃分享整理
    物联沃-IOTWORD物联网 » 嵌入式笔试题解析及答案解析

    发表评论