当前位置:网站首页>嵌入式面试题(算法部分)
嵌入式面试题(算法部分)
2022-07-07 16:51:00 【树的编程知识屋】
嵌入式面试题算法部分
一、基础部分
1、数组与链表的区别?
(1)数组的元素个数在定义时就必须确定,且元素的类型必须一致;而链表的元素个数自由,且元素内可以有不同类型的数据。
(2)数组的元素在内存中是按顺序存储的,而链表的元素是随机存储的。
(3)要访问数组的元素可以按下标索引来访问,速度比较快;如果对它进行插入/删除操作的话,就得移动很多元素,所以对数组进行插入/删除操作效率很低。由于链表是随机存储的,如果要访问链表中的某个元素的话,那就得从链表的头逐个遍历,直到找到所需要的元素为止,所以链表的随机访问的效率就比数组要低;链表在插入/删除操作上有很高的效率(相对数组)。一句话总结就是:数组的访问效率高,而链表的插入/删除效率高。
2、C语言程序代码优化方法
(1)选择合适的数据结构与算法;
(2)使用尽量小的数据类型;
(3)使用自加、自减指令;
(4)用移位实现乘除法运算;
(5)求余运算用&(如a=a%8改为a=a&7);
(6)平方运算用*(如a=pow(a,2.0)改为a=a*a);
(7)延时函数的自加改为自减;
(8)switch语句中根据发生频率来进行case排序;
(9)减少运算的强度。
3、堆和栈的的区别?
C语言内存分配的堆和栈 | 栈是向下生长的,栈中分配函数参数和局部变量,其分配方式类似于数据结构中的栈。堆是向上生长的,堆中分配程序员申请的内存空间(一旦忘记释放会造成内存泄漏),其分配方式类似于数据结构中的链表 |
---|---|
数据结构的堆和栈 | 栈是一种先进后出的数据结构。堆是一种经过排序的树形数据结构(通常是二叉堆),每个结点都有一个值,根结点的值最小或最大,常用来实现优先队列,堆的存储是随意的 |
4、内联函数的优缺点和适用场景是什么?
(1)优点:内联函数与宏定义一样会在原地展开,省去了函数调用开销,同时又能做类型检查。
(2)缺点:它会使程序的代码量增大,消耗更多内存空间。
(3)适用场景:函数体内没有循环(执行时间短)且代码简短(占用内存空间小)
4、下面代码输出是什么?
#include<stdio.h>
void main()
{
int a[5] = {
1, 2, 3, 4, 5};
int *ptr = (int *)(&a + 1);
printf("%d, %d", *(a + 1), *(ptr - 1));
}
答案:输出为2, 5
解读: a是数组首元素地址,所以*(a + 1)就是第二个元素a[1]。&a是数组地址,所以&a +1是整个数组结尾的下一个地址,*(ptr - 1)就是a[4]。
5、结构体struct和联合体union的区别?
(1)两者最大的区别在于内存的使用。
(2)结构体各成员拥有自己的内存,各自使用且互不干涉,遵循内存对齐原则。
(3)联合体所有成员共用一块内存空间,并且同时只有一个成员可以得到这块内存的使用权。一个联合体变量的总长度应至少能容纳最大的成员变量,且需要进行内存补齐。
6、函数参数的传递方式有几种?
(1)两种:值传递、指针传递。
(2)严格来看,只有一种传递,值传递,指针传递也是按值传递的,复制的是地址。
7、堆和栈的的区别?
C语言内存分配的堆和栈 | 栈是向下生长的,栈中分配函数参数和局部变量,其分配方式类似于数据结构中的栈。堆是向上生长的,堆中分配程序员申请的内存空间(一旦忘记释放会造成内存泄漏),其分配方式类似于数据结构中的链表 |
---|---|
数据结构的堆和栈 | 栈是一种先进后出的数据结构。堆是一种经过排序的树形数据结构(通常是二叉堆),每个结点都有一个值,根结点的值最小或最大,常用来实现优先队列,堆的存储是随意的。 |
二、算法部分
1、如何判读一个系统的大小端存储模式?
(1) 方法一:int 强制类型转换为char ,用“[]”解引用
void checkCpuMode(void)
{
int c = 0x12345678;
char *p = (char *)&c;
if(p[0] == 0x12)
printf("Big endian.\n");
else if(p[0] == 0x78)
printf("Little endian.\n");
else
printf("Uncertain.\n");
}
(2)方法二:int *强制类型转换为char ,用“”解引用
void checkCpuMode(void)
{
int c = 0x12345678;
char *p = (char *)&c;
if(*p == 0x12)
printf("Big endian.\n");
else if(*p == 0x78)
printf("Little endian.\n");
else
printf("Uncertain.\n");
}
(3)方法三:包含short跟char的共用体
void checkCpuMode(void)
{
union Data
{
short a;
char b[sizeof(short)];
}data;
data.a = 0x1234;
if(data.b[0] == 0x12)
printf("Big endian.\n");
else if(data.b[0] == 0x34)
printf("Little endian.\n");
else
printf("uncertain.\n");
}
大端小端模式:
大端模式:是指一个数据的低位字节序的内容放在高地址处,高位字节序存的内容放在低地址处。
小端模式:是指一个数据的低位字节序内容存放在低地址处,高位字节序的内容存放在高地址处。
如:一个数0x12345678存放在一个4字节空间里
0x12345678中,1234属于高位,如果低地址的第一个字节存的0x12 则 是高位字节 存储在了低地址,是大端模式。
低地址 --------------------> 高地址
0x12 | 0x34 | 0x56 | 0x78
如:一个数0x12345678存放在一个4字节空间里
0x12345678中,1234属于高位,如果低地址的第一个字节存的0x12 则是高位字节 存储在了 高地址,是小端模式。
低地址 --------------------> 高地址
0x78 | 0x56 | 0x34 | 0x12
原文链接:https://blog.csdn.net/ALakers/article/details/116225089
2、验证回文串:给定一个字符串,验证它是否是回文串,只考虑字符和数字字符,可以忽略字母的大小写
(回文串即左右对称的字符串,如"A man, a plan, a canal: Panama")
思路:双指针法,一个指针指向字符串开头,另一个指向字符串结尾,两个指针都往中间
移动并寻找字符和数字,并将字母统一转为小写,然后比较是否相同,若不相同则返回false,若相同则继续寻找……如此循环,若直到两指针相遇都没返回false,则返回true。
bool isPalindrome(char * s)
{
char *left = s, *right = s + strlen(s) - 1;
if(strlen(s) == 0) return true;
while(left < right)
{
while(!((*left >= 'a' && *left <= 'z') || (*left >= 'A' && *left <= 'Z') || (*left >= '0' && *left <= '9')) && left < right) // 找到字母或数字
left++;
while(!((*right >= 'a' && *right <= 'z') || (*right >= 'A' && *right <= 'Z') || (*right >= '0' && *right <= '9')) && right > left) // 找到字母或数字
right--;
if(left < right)
{
if((*left >= 'A' && *left <= 'Z')) // 若为大写,则转为小写
*left = *left + 32;
if((*right >= 'A' && *right <= 'Z')) // 若为大写,则转为小写
*right = *right + 32;
if(*left == *right) // 比较
{
left++;
right--;
}
else
return false;
}
else
return true;
}
return true;
}
3、写一个程序, 要求功能:求出用1,2,5这三个数不同个数组合的和为100的组合个数。 如:100个1是一个组合,5个1加19个5是一个组合。
(1)最容易想到的算法是暴力解法 思路:设x是1的个数,y是2的个数,z是5的个数,number是组合数,注意到0 <= x <=> 100,0 <= y <= 50,0 <= z <= 20。
void count(void)
{
int x, y, z, number;
number = 0;
for (x = 0; x <= 100 / 1; x++)
{
for (y = 0; y <= 100 / 2; y++)
{
for (z = 0; z <= 100 / 5; z++)
{
if (x + 2 * y + 5 * z == 100)
number++;
}
}
}
printf("%d\t", number);
}
(2)上述暴力解法的时间复杂度为O(n³),程序有些冗余,对其进行优化如下
思路:注意到上面代码的第三个for循环其实不是必要的,因为当1和2的数目确定了之后,加上一定数目的5能不能组成100也就确定了,没必要用for循环一个个去尝试,直接计算即可,优化后时间复杂度变为O(n2)。
void count(void)
{
int x, y, z, number;
number = 0;
for (x = 0; x <= 100 / 1; x++)
{
for (y = 0; y <= 100 / 2; y++)
{
if (100 - x - y * 2 >= 0 && (100 - x - y * 2) % 5 == 0) // 判断能否5整除
number++;
}
}
printf("%d\t", number);
}
4、判断链表是否有环。
思路:双指针法,定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步。如果走得快的指针追上了走得慢的指针,那么链表就是环形链表;如果走得快的指针走到了链表的末尾(fast> == NULL)都没有追上第一个指针,那么链表就不是环形链表。
bool IsLoop(NODE *head)
{
if (head == NULL)
return false;
NODE *slow = head -> next; // 初始时,慢指针从第一个节点开始走1步
if (slow == NULL)
return false;
NODE *fast = slow -> next; // 初始时,快指针从第一个节点开始走2步
while (fast != NULL && slow != NULL) // 当单链表没有环时,循环到链表末尾结束
{
if (fast == slow) // 快指针追上慢指针
return true;
slow = slow -> next; // 慢指针走一步
fast = fast -> next; // 快指针走两步
if (fast != NULL)
fast = fast -> next;
}
return false;
}
边栏推荐
- 2022年理财有哪些产品?哪些适合新手?
- 能同时做三个分割任务的模型,性能和效率优于MaskFormer!Meta&UIUC提出通用分割模型,性能优于任务特定模型!开源!...
- 行业案例|数字化经营底座助力寿险行业转型
- Introduction de l'API commune de programmation de socket et mise en œuvre de socket, select, Poll et epoll
- Sports Federation: resume offline sports events in a safe and orderly manner, and strive to do everything possible for domestic events
- Nat address translation
- Redis
- [Tawang methodology] Tawang 3W consumption strategy - U & a research method
- Live broadcast software construction, canvas Text Bold
- Wireshark分析抓包数据*.cap
猜你喜欢
备份阿里云实例-oss-browser
Wireshark分析抓包数据*.cap
通过 Play Integrity API 的 nonce 字段提高应用安全性
清华、剑桥、UIC联合推出首个中文事实核查数据集:基于证据、涵盖医疗社会等多个领域
伺服力矩控制模式下的力矩目标值(fTorque)计算
Introduction de l'API commune de programmation de socket et mise en œuvre de socket, select, Poll et epoll
『HarmonyOS』DevEco的下载安装与开发环境搭建
Datasimba launched wechat applet, and datanuza accepted the test of the whole scene| StartDT Hackathon
AntiSamy:防 XSS 攻击的一种解决方案使用教程
AI defeated mankind and designed a better economic mechanism
随机推荐
coming! Gaussdb (for Cassandra) new features appear
“解密”华为机器视觉军团:华为向上,产业向前
Nat address translation
AntiSamy:防 XSS 攻击的一种解决方案使用教程
Wireshark分析抓包数据*.cap
[tpm2.0 principle and Application guide] Chapter 5, 7 and 8
[principle and technology of network attack and Defense] Chapter 1: Introduction
[network attack and defense principle and technology] Chapter 4: network scanning technology
[demo] circular queue and conditional lock realize the communication between goroutines
debian10编译安装mysql
小试牛刀之NunJucks模板引擎
线程池的拒绝策略
Five network IO models
小程序中实现付款功能
Reject policy of thread pool
idea彻底卸载安装及配置笔记
Is it safe to open an online futures account now? How many regular futures companies are there in China?
Discuss | frankly, why is it difficult to implement industrial AR applications?
nest.js入门之 database
Charles+Postern的APP抓包