嵌入式软件工程师笔试题.docx
《嵌入式软件工程师笔试题.docx》由会员分享,可在线阅读,更多相关《嵌入式软件工程师笔试题.docx(21页珍藏版)》请在冰豆网上搜索。
![嵌入式软件工程师笔试题.docx](https://file1.bdocx.com/fileroot1/2023-2/23/60b6d7fc-1bcd-4ae6-a50f-b50bc9190e04/60b6d7fc-1bcd-4ae6-a50f-b50bc9190e041.gif)
嵌入式软件工程师笔试题
嵌入式软件工程师笔试题
1、将一个字符串逆序
2、将一个链表逆序
3、计算一个字节里(byte)里面有多少bit被置1
4、搜索给定的字节(byte)
5、在一个字符串中找到可能的最长的子字符串
6、字符串转换为整数
7、整数转换为字符串
1、c51单片机的串口异步通信和同步通信的区别,说说他们的优缺点。
2、C51单片机的数据总线和地址总线是如何复用的,说明原理。
3、C51单片机的绝对寻址范围是多少k?
4、说明下面的寻址方式
(1)MOVA,#30H
(2)MOVA,@R0
(3)ADDA,R4 (4)MOV A+@DPTR
5、写出下面分别是什么指针?
(1)int*a[10];
(2)int (*a)[10];
(3)int (*P)(int) ; (4)int(*a[10])(int);
6、
voidswap(inta,intb)
{
inttemp;
temp=a;
a=b;
b=temp;
}
main(void)
{
intx="3",y=4;
swap(x,y);
}
问上面程序执行完后x=?
,y=?
7、typedefstruct test{
inti;
shorts;
charc;
union{
inta;
shortb;
}
}example;
inty;
y=sizeof(example);
请问在TC环境下,y=?
8、编程实现数组的逆置,例如,“hello,world!
” 逆置后为“!
dlrow,olleh”。
9、你认为嵌入式操作系统包括哪些部分?
说说实时操作系统有哪些特点。
10、冯诺依曼结构的计算机由哪几部分组成?
11、说说程序,进程,线程的区别。
12、说说你怎样理解
程序=数据+结构+算法
13、根据函数原型编程实现一个数组,按从大到小的冒泡排序。
voidtibbule(inta[],intn);//a[]为数组,n为数组长度
14、OSI有哪几层?
tcp/ip包括哪几层?
15、编程实现一个双链表的节点插入和删除。
5。
写一个数据类型:
一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个
整型数。
6。
嵌入式系统总是要用户对变量或寄存器进行位操作。
给定一个整型变量a,写两段代码,第一个设置a
的bit3,第二个清除a的bit3。
在以上两个操作中,要保持其它位不变。
7。
嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。
在某工程中,要求设置一绝对地址
为0x67a9的整型变量的值为0xaa66。
编译器是一个纯粹的ANSI编译器。
写代码去完成这一任务。
8。
字符串倒序。
9。
floata,b,c 问下列两个的值:
(a+b)+c==(b+a)+c
(a+b)+c==(a+c)+b
10。
关键字static的作用是什么?
关键字const有什么含意?
11。
关键字volatile有什么含意?
并给出三个不同的例子。
1)一个参数既可以是const还可以是volatile吗?
解释为什么。
2)一个指针可以是volatile吗?
解释为什么。
3)下面的函数有什么错误:
intsquare(volatileint*ptr)
{
return*ptr**ptr;
}
12。
嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。
在某工程中,要求设置一绝对地址
为0x67a9的整型变量的值为0xaa66。
编译器是一个纯粹的ANSI编译器。
写代码去完成这一任务。
13。
动态内存分配
下面的代码片段的输出是什么,为什么?
char*ptr;
if((ptr=(char*)malloc(0))==NULL)
puts("Gotanullpointer");
else
puts("Gotavalidpointer");
14。
Typedef在C语言中频繁用以声明一个已经存在的数据类型的同义字。
也可以用预处理器做类似的事。
例如,思考一下下面的例子:
#definedPSstructs*
typedefstructs*tPS;
以上两种情况的意图都是要定义dPS和tPS作为一个指向结构s指针。
哪种方法更好呢?
(如果有的话)
为什么?
15。
中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。
具
代表事实是,产生了一个新的关键字__interrupt。
下面的代码就使用了__interrupt关键字去定义了一个中断
服务子程序(ISR),请评论一下这段代码的。
__interruptdoublecompute_area(doubleradius)
{
doublearea=PI*radius*radius;
printf("\nArea=%f",area);
returnarea;
}
16。
下面的代码输出是什么,为什么?
voidfoo(void)
{
unsignedinta=6;
intb=-20;
(a+b>6)?
puts(">6"):
puts("<=6");
}
17。
评价下面的代码片断:
unsignedintzero=0;
unsignedintcompzero=0xFFFF;
/*1'scomplementofzero*/
18。
C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么?
inta=5,b=7,c;
c=a+++b;
19。
编写一个可重入的函数。
20。
编写ISR需要注意哪些地方?
21。
如何设计一个内存拷贝函数,考虑效率及强健性原则。
22。
怎样理解"地址对齐","内存分配","处理器字节序"的意义,应用上有什么需要注意的地方吗?
举例。
如何测试一个处理器的字节序?
23。
至少举两个例子从硬件和微码执行的角度说明CPU响应中断的过程。
24。
如何实现任务调度?
25。
如何避免优先级反转?
26。
任务锁和终端锁之间的区别,应用上应该怎么去选择?
27。
进程间通讯与同步的手段有哪些?
举例说明。
4 嵌入式系统相关问题
a) 对于整形变量A=0x12345678,请画出在little endian及big endian的方式下在内存中是如何存储的。
b) 在ARM系统中,函数调用的时候,参数是通过哪种方式传递的?
c) 中断(interrupt,如键盘中断)与异常(exception,如除零异常)有何区别?
定:
1)下面的测试题中,认为所有必须的头文件都已经正确的包含了
2)数据类型
char一个字节1byte
int两个字节2byte(16位系统,认为整型是2个字节)
longint四个字节4byte
float四个字节4byet
double八个字节8byte
longdouble十个字节10byte
pointer两个字节2byte(注意,16位系统,地址总线只有16位)
第1题:
考查对volatile关键字的认识
#include
staticjmp_bufbuf;
main()
{
volatileintb;
b=3;
if(setjmp(buf)!
=0)
{
printf("%d",b);
exit(0);
}
b=5;
longjmp(buf,1);
}
请问,这段程序的输出是
(a)3
(b)5
(c)0
(d)以上均不是
第2题:
考查类型转换
main()
{
structnode
{
inta;
intb;
intc;
};
structnodes={3,5,6};
structnode*pt=&s;
printf("%d",*(int*)pt);
}
这段程序的输出是:
(a)3
(b)5
(c)6
(d)7
第3题:
考查递归调用
intfoo(intx,intn)
{
intval;
val=1;
if(n>0)
{
if(n%2==1)val=val*x;
val=val*foo(x*x,n/2);
}
returnval;
}
这段代码对x和n完成什么样的功能(操作)?
(a)x^n(x的n次幂)
(b)x*n(x与n的乘积)
(c)n^x(n的x次幂)
(d)以上均不是
第4题:
考查指针,这道题只适合于那些特别细心且对指针和数组有深入理解的人
main()
{
inta[5]={1,2,3,4,5};
int*ptr=(int*)(&a+1);
printf("%d%d",*(a+1),*(ptr-1));
}
这段程序的输出是:
(a)22
(b)21
(c)25
(d)以上均不是
第5题:
考查多维数组与指针
voidfoo(int[][3]);
main()
{
inta[3][3]={{1,2,3},{4,5,6},{7,8,9}};
foo(a);
printf("%d",a[2][1]);
}
voidfoo(intb[][3])
{
++b;
b[1][1]=9;
}
这段程序的输出是:
(a)8
(b)9
(c)7
(d)以上均不对
第6题:
考查逗号表达式
main()
{
inta,b,c,d;
a=3;
b=5;
c=a,b;
d=(a,b);
printf("c=%d",c);
printf("d=%d",d);
}
这段程序的输出是:
(a)c=3d=3
(b)c=5d=3
(c)c=3d=5
(d)c=5d=5
第7题:
考查指针数组
main()
{
inta[][3]={1,2,3,4,5,6};
int(*ptr)[3]=a;
printf("%d%d",(*ptr)[1],(*ptr)[2]);
++ptr;
printf("%d%d",(*ptr)[1],(*ptr)[2]);
}
这段程序的输出是:
(a)2356
(b)2345
(c)4500
(d)以上均不对
第8题:
考查函数指针
int*f1(void)
{
intx=10;
return(&x);
}
int*f2(void)
{
int*ptr;
*ptr=10;
returnptr;
}
int*f3(void)
{
int*ptr;
ptr=(int*)malloc(sizeof(int));
returnptr;
}
上面这3个函数哪一个最可能引起指针方面的问题
(a)只有f3
(b)只有f1andf3
(c)只有f1andf2
(d)f1,f2,f3
第9题:
考查自加操作(++)
main()
{
inti=3;
intj;
j=sizeof(++i+++i);
printf("i=%dj=%d",i,j);
}
这段程序的输出是:
(a)i=4j=2
(b)i=3j=2
(c)i=3j=4
(d)i=3j=6
第10题:
考查形式参数,实际参数,指针和数组
voidf1(int*,int);
voidf2(int*,int);
void(*p[2])(int*,int);
main()
{
inta;
intb;
p[0]=f1;
p[1]=f2;
a=3;
b=5;
p[0](&a,b);
printf("%d\t%d\t",a,b);
p[1](&a,b);
printf("%d\t%d\t",a,b);
}
voidf1(int*p,intq)
{
inttmp;
tmp=*p;
*p=q;
q=tmp;
}
voidf2(int*p,intq)
{
inttmp;
tmp=*p;
*p=q;
q=tmp;
}
这段程序的输出是:
(a)5555
(b)3535
(c)5353
(d)3333
第11题:
考查自减操作(--)
voide(int);
main()
{
inta;
a=3;
e(a);
}
voide(intn)
{
if(n>0)
{
e(--n);
printf("%d",n);
e(--n);
}
}
这段程序的输出是:
(a)0120
(b)0121
(c)1201
(d)0211
第12题:
考查typedef类型定义,函数指针
typedefint(*test)(float*,float*)
testtmp;
tmp的类型是
(a)函数的指针,该函数以两个指向浮点数(float)的指针(pointer)作为参数(arguments)
Pointertofunctionofhavingtwoargumentsthatispointertofloat
(b)整型
(c)函数的指针,该函数以两个指向浮点数(float)的指针(pointer)作为参数(arguments),并且函数的返回值类型是整型
Pointertofunctionhavingtwoargumentthatispointertofloatandreturnint
(d)以上都不是
第13题:
数组与指针的区别与联系
main()
{
charp;
charbuf[10]={1,2,3,4,5,6,9,8};
p=(buf+1)[5];
printf("%d",p);
}
这段程序的输出是:
(a)5
(b)6
(c)9
(d)以上都不对
第14题:
考查指针数组的指针
voidf(char**);
main()
{
char*argv[]={"ab","cd","ef","gh","ij","kl"};
f(argv);
}
voidf(char**p)
{
char*t;
t=(p+=sizeof(int))[-1];
printf("%s",t);
}
这段程序的输出是:
(a)ab
(b)cd
(c)ef
(d)gh
第15题:
此题考查的是C的变长参数,就像标准函数库里printf()那样,这个话题一般国内大学课堂是不会讲到的,不会情有可原
#include
intripple(int,);
main()
{
intnum;
num=ripple(3,5,7);
printf("%d",num);
}
intripple(intn,)
{
inti,j;
intk;
va_listp;
k=0;
j=1;
va_start(p,n);
for(;j{
i=va_arg(p,int);
for(;i;i&=i-1)
++k;
}
returnk;
}
这段程序的输出是:
(a)7
(b)6
(c)5
(d)3
第16题:
考查静态变量的知识
intcounter(inti)
{
staticintcount=0;
count=count+i;
return(count);
}
main()
{
inti,j;
for(i=0;i<=5;i++)
j=counter(i);
}
本程序执行到最后,j的值是:
(a)10
(b)15
(c)6
(d)7
详细参考答案
第1题:
(b)
volatile字面意思是易于挥发的。
这个关键字来描述一个变量时,意味着给该变量赋值(写入)之后,马上再读取,写入的值与读取的值可能不一样,所以说它"容易挥发"的。
这是因为这个变量可能一个寄存器,直接与外部设备相连,你写入之后,该寄存器也有可能被外部设备的写操作所改变;或者,该变量被一个中断程序,或另一个进程
改变了.
volatile不会被编译器优化影响,在longjump后,它的值是后面假定的变量值,b最后的值是5,所以5被打印出来.
setjmp:
设置非局部跳转/*setjmp.h*/
Storescontextinformationsuchasregistervaluessothatthelomgjmpfunctioncanreturncontroltothestatementfollowingtheonecallingsetjmp.Returns0whenitisinitiallycalled.
Lonjjmp:
执行一个非局部跳转/*setjmp.h*/
Transferscontroltothestatementwherethecalltosetjmp(whichinitializedbuf)wasmade.Executioncontinuesatthispointasiflongjmpcannotreturnthevalue0.Anonvolatileautomaticvariablemightbechangedbyacalltolongjmp.Whenyouusesetjmpandlongjmp,theonlyautomaticvariablesguaranteedtoremainvalidarethosedeclaredvolatile.
Note:
Testprogramwithoutvolatilequalifier(resultmayvery)
更详细介绍,请参阅C语言的setjmp和longjmp
第2题:
(a)
结构题的成员在内存中的地址是按照他们定义的位置顺序依次增长的。
如果一个结构体的指针被看成它的第一个成员的指针,那么该指针的确指向第一个成员
第3题:
(a)
此题目较难.
这个程序的非递归版本
intwhat(intx,intn)
{
intval;
intproduct;
product=1;
val=x;
while(n>0)
{
if(n%2==1)
product=product*val;/*如果是奇数次幂,x(val)要先乘上一次,;
偶数次幂,最后返回时才会到这里乘以1*/
val=val*val;
n=n/2;
}
returnproduct;
}
/*用二元复乘策略*/
算法描述
(whilen>0)
{
ifnextmostsignificantbinarydigitofn(power)isone
thenmultiplyaccumulatedproductbycurrentval,
reducen(power)sequencebyafactoroftwousingintegerdivision.
getnextvalbymultiplycurrentvalueofitself
}
第4题:
(c)
a的类型是一个整型数组,它有5个成员。
&a的类型是一个整型数组的指针,所以&a+1指向的地方等同于a[6],所以*(a+1)等同于a[1]
ptr等同a[6],ptr-1就等同与a[5]
第5题:
(b)
题目自身就给了足够的提示
b[0][0]=4
b[1][0]=7
第6题:
(c)
考查逗号表达式,逗号表达式的优先级是很低的,比赋值(=)的优先级低.逗号表达式的值就是最后一个元素的值
逗号表达式的还有一个作用就是分割函数的参数列表..
E1,E2,...,En
上面这个表示式的左右是,E1,E2,...En的值被分别计算出来,En计算出来的结构赋给整个逗号表达式
c=a,b;/*yieldsc=a*/
d=(a,b);/*d=b*/
第7题:
(a)
ptr是一个数组的指针,该数组有3个int成员
第8题:
(c)
f1显然有问题,它返回一个局部变量的指针,局部变量是保存在stack中的,退出函数后,局部变量就销毁了,保留其指针没有意义,因为其指向的stack空间可能被其他变量覆盖了
f2也有问题,ptr是局部变量,未初始化,它的值是未知的,*ptr不知道指向哪里了,直接给*ptr赋值可能会覆盖重要的系统变量,这就是通常说的野指针的一种
第9题:
(b)
sizeof操作符给出其操作数需要占用的空间大小,它是在编译时就可确定的,所以其操作数即使是一个表达式,也不需要在运行时进行计算.(++i+++i)是不会执行的,所以i的值还是3
第10题:
(a)
很显然选a.
f1交换*p和q的值,f1执行完后,*p和q的值的确交换了,但q的改变不会影响到b的改变,*p实际上就是a
所以执行f1后,a=b=5
这道题考查的知识范围很广,包括typedef自定义类型,函数指针,指针数组void(*p[2])(int*,int);
定义了一个函数指针的数组p,p有两个指针元素.元素是函数的指针,函数指针指向的函数是一个带2个参数,返回voi