嵌入式面试题(8)

2019-03-29 12:37

预处理:预处理相当于根据预处理命令组装成新的C程 序,不过常以i为扩展名。 编译: 将得到的i文件翻译成汇编代码。s文件。

汇编:将汇编文件翻译成机器指令,并打包成可重定位目标程序的O文件。该文件是二进制文件,字节编码是机器指令。

链接:将引用的其他O文件并入到我们程序所在的o文件中,处理得到最终的可执行文件。

4、++i和i++的区别

(1)、整形数++i和i++的区别

[cpp] view plain copy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.

#include int main(void) {

int a, b, i = 7; i++; //等价于i = i + 1; ++i; //等价于i = i + 1;

a = i++; //等价于a = i; i = i + 1; b = ++i; //等价于i = i + 1; b = i; printf(\, a, b); return 0; } a = 9, b = 11

在例子中,第7和第8行的作用一样,仅仅是为变量i加1,这时i的值已经增加为9,接下来第10行变量a先获得i的值(即9),然后i加1,第11行变量i 先再加1,然后把得到的值赋给b,所以b的值为11。 (2)、(*p)++和++(*p)的区别

[cpp] view plain copy

1.

#include

2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.

int main(void) {

int a = 5; int *p = &a;

int b = (*p)++; //等价于b = a++; 即b = a; a = a + 1; int c = ++(*p); //等价于c = ++a; 即a = a + 1; c = a; printf(\, b, c);

printf(\, (*p)++, ++(*p)); return 0; }

例子输出结果: b = 5, c = 7 ; (*p)++ = 8, ++(*p) = 8

(3)、*p++和*++p的区别:

[cpp] view plain copy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.

#include int main(void) {

int arr[] = {1, 2, 3, 4}; int *p = arr;

int a = *p++; //等价于a = *(p++); 即a = *p; p = p + 1; int b = *++p; //等价于b = *(++p); 即p = p + 1; b = *p; printf(\, a, b); return 0; }

a = 1, b = 3

对于第8行的操作数p而言,*和++的优先级相同,但根据它们的右结合性可知,在这个表达式里可认为++的优先级高于*,即*p++等价于*(p++)。

而对于第10行的操作数p而言,它只有一个运算符++,所以先计算++p得出结果,然后间接运算。

5、二分法的实现过程和代码分析

二分查找算法是在有序数组中用到的较为频繁的一种算法,在未接触二分查找算法时,最通用的一种做法是,对数组进

行遍 历,跟每个元素进行比较,其时间为O(n).但二分查找算

法则更优,因为其查找时间为 O(lgn),譬如数组{1,2,3,4 ,5,6,7, 8,9},查找元素6,用二分查找的算法执行的话,其顺序为:

(1)、第一步查找中间元素,即5,由于5<6,则6必然在5之后的数组元素中,那么就在{6, 7, 8, 9}中查找,

(2)、寻找{6, 7, 8, 9}的中位数,为7,7>6,则6应该在7左边的数组元素中,那么只剩下6,即找到了。

代码:

[cpp] view plain copy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.

int binary_search(int* a, int len, int goal) {

int low =0; int high = len -1; while(low <= high) {

int middle = (low + high)/2; if(a[middle] == goal) return middle; //在左半边

elseif(a[middle] > goal) high = middle -1; //在右半边 else

low = middle +1; } //没找到 return-1; }

6、大端小端的转换

0x3132(0x32是低位,0x31是高位),把它赋值给一个short变量,那么它在内存中的存储可能有如下两种情况:

(1)、大端字节(Big-endian):

----------------->>>>>>>>内存地址增大方向 short变量地址

0x1000 0x1001 _____________________________ | |

| 0x31 | 0x32 |_______________|________________

高位字节在低位字节的前面,也就是高位在内存地址低的一端.可以这样记住(大端->高位->在前->正常的逻辑顺序)

(2)、小端字节(little-endian):

----------------->>>>>>>>内存地址增大方向 short变量地址

0x1000 0x1001 _____________________________ | |

| 0x32 | 0x31 |________________|________________

低位字节在高位字节的前面,也就是低位在内存地址低的一端.可以这样记住(小端->低位->在前->与正常逻辑顺序相反)

7、栈和堆的区别

栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

堆(操作系统):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

8、Volatile与Register修饰符的作用

Volatile与Register修饰符的作用volatile的作用是:

作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值,

volatile表示这个变量会被意想不到的改变,每次用他的时候都会小心的重新读取一遍,不适用寄存器保存的副本

1) 并行设备的硬件寄存器(如:状态寄存器)

2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3) 多线程应用中被几个任务共享的变量 register

建议编译器使用寄存器来优化对变量的存取

register修饰符暗示编译程序相应的变量将被频繁地使用,如果可能的话,应将其保存在CPU的寄存器中,以加快其 存储速度

9、char *a 与char a[] 的区别

char *a存放在常量区,是无法修的。而char a[] 是存放在栈中,是可以修改的

10、要求设置一绝对地址为0x67a9 的整型变量的值为0xaa66

int *ptr = (int *)0xaa66; *ptr = 0x67a9;

11、信号量与互斥锁的区别

(1)、互斥量用于线程的互斥,信号量用于线程的同步。

互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访 问顺序,即访问是无 序的。

同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已 经实现了互斥,特别 是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源

(2)、互斥量值只能为0/1,信号量值可以为非负整数。

也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个 同类资源的多线程 互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。

(3)、互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。

12、用C语言实现字符串倒序

[cpp] view plain copy

1. 2. 3. 4. 5. 6. 7. 8. 9.

int fun(char *w) {

char t, *s1,*s2; int n=strlen(w); s1=w; s2=w+n-1; while(s1


嵌入式面试题(8).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:实验室生物安全测试题

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: