嵌入式软件笔试题.docx
《嵌入式软件笔试题.docx》由会员分享,可在线阅读,更多相关《嵌入式软件笔试题.docx(8页珍藏版)》请在冰豆网上搜索。
嵌入式软件笔试题
凹凸笔试题目(嵌入式软件开发)
2007-02-07
EmbeddedSoftwareDesignEngineer1读程序段,回答问题intmain(intargc,char*argv[]){intc=9,d=0;c=c++%5;d=c;printf("d=%d\n",d);return0;}a)写出程序输出b)在一个可移植的系统中这种表达式是否存在风险why?
#include""inta=0;intb;staticcharc;intmain(intargc,char*argv[]){chard=4;staticshorte;a++;b=100;c=(char)++a;e=(++d)++;printf("a=%d,b=%d,c=%d,d=%d,e=%d",a,b,c,d,e);return0;}a)写出程序输出b)编译器如果安排各个变量(a,b,c,d)在内存中的布局(eg.stack,heap,datasection,bsssection),最好用图形方式描述。
2中断是嵌入式系统中重要的组成部分,这导致了许多编译开发商提供一种扩展:
让标准C支持中断,产生了一个新的关键字__interrupt。
下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论以下这段代码。
__interruptdoublecompute_area(doubleradius){doublearea=PI*radius*radius;printf("nArea=%f",area);returnarea;}3C/C++基础知识问题a)关键字volatile在编译时有什么含义并给出三个不同使用场景的例子(可以伪代码或者文字描述)。
b)C语言中static关键字的具体作用有哪些?
c)请问下面三种变量声明有何区别请给出具体含义intconst*p;int*constp;intconst*constp;4嵌入式系统相关问题a)对于整形变量A=0x,请画出在littleendian及bigendian的方式下在内存中是如何存储的。
b)在ARM系统中,函数调用的时候,参数是通过哪种方式传递的?
c)中断(interrupt,如键盘中断)与异常(exception,如除零异常)有何区别?
5设周期性任务P1,P2,P3的周期为T1,T2,T3分别为100,150,400;执行时间分别为20,40,100。
请设计一种调度算法进行任务调度,满足任务执行周期及任务周期。
6优先级反转问题在嵌入式系统中是一中严重的问题,必须给与足够重视。
a)首先请解释优先级反转问题b)很多RTOS提供优先级继承策略(Priorityinheritance)和优先级天花板策略(Priorityceilings)用来解决优先级反转问题,请讨论这两种策略。
参考答案:
15存在风险,因为c=c++%5;这个表达式对c有两次修改,行为未定义,c的值不确定inta=0;
.);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这段程序的输出是:
(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:
设置非局部跳转/**/Storescontextinformationsuchasregistervaluessothatthelomgjmpfunctioncanreturncontroltothestatementfollowingtheonecalling0whenitisinitiallycalled.Lonjjmp:
执行一个非局部跳转/**/Transferscontroltothestatementwherethecalltosetjmp(whichinitializedbuf)wasmade.Executioncontinuesatthispointasiflongjmpcannotreturnthevaluenonvolatileautomaticvariablemightbechangedbyacalltoyouusesetjmpandlongjmp,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)isonethenmultiplyaccumulatedproductbycurrentval,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]=4b[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个参数,返回void的函数,所带的两个参数是指向整型的指针,和整型p[0]=f1;p[1]=f2containaddressoffunction.functionnamewithoutparenthesisrepresentaddressoffunctionValueandaddressofvariableispassedtofunctiononlyargumentthatiseffectedisa(addressispassed).Becauseofcallbyvaluef1,f2cannoteffectb第11题:
(a)
考查--操作和递归调用,仔细分析一下就可以了第12题:
(c)建议不会的看看C专家编程从左往有,遇到括号停下来,将第一个括号里的东西看成一个整体
第13题:
(c)
考查什么时候数组就是指针.对某些类型T而言,如果一个表达式是T[](T的数组),这个表达式的值实际上就是指向该数组的第一个元素的指针.所以(buf+1)[5]实际上就是*(buf+6)或者buf[6]
第14题:
(b)
sizeof(int)的值是2,所以p+=sizeof(int)指向argv[2],这点估计大家都没有什么疑问(p+=sizeof(int))[-1]指向argv[1],能理解吗,因为(p+=sizeof(int))[-1]就相当于(p+=2)[-1],也就是(p+2-1)第15题:
(c)
在C编译器通常提供了一系列处理可变参数的宏,以屏蔽不同的硬件平台造成的差异,增加程序的可移植性。
这些宏包括va_start、va_arg和va_end等。
采用ANSI标准形式时,参数个数可变的函数的原型声明是:
typefuncname(typepara1,typepara2,...)这种形式至少需要一个普通的形式参数,后面的省略号不表示省略,而是函数原型的一部分。
type是函数返回值和形式参数的类型。
不同的编译器,对这个可变长参数的实现不一样,中是内置函数.
关于可变长参数,可参阅
[url][url]
程序分析
va_listp;/*定义一个变量,保存函数参数列表的指针*/va_start(p,n);/*用va_start宏初始化变量p,va_start宏的第2个参数n,是一个固定的参数,必须是我们自己定义的变长函数的最后一个入栈的参数也就是调用的时候参数列表里的第1个参数*/for(;j当我们调用ripple函数时,传递给ripple函数的参数列表的第一个参数n的值是3.
va_start初始化p士气指向第一个未命名的参数(n是有名字的参数),也就是is5(第一个).
每次对va_arg的调用,都将返回一个参数,并且把p指向下一个参数.
va_arg用一个类型名来决定返回的参数是何种类型,以及在var_arg的内部实现中决定移动多大的距离才到达下一个参数
(;i;i&=i-1)k++/*计算i有多少bit被置1*/
5用二进制表示是(101)27用二进制表示(111)3所以k返回5(2+3),也即本题应该选c举个例子,就很好理解了
令i=9=1001i-1=1000(i-1)+1=i1000+11001
因为i与i-1的最右边的那位(最低位)肯定是不同,如果i1,i-1肯定是0,反之亦然.i&i-1这个运算,在二相补的数字系统中,将会消除最右边的1位
第16题:
(b)答案是(b)相传高斯小学一年级的时候就会做这类等比数列的题目了.这道题考查的是静态变量的知识,当每次调用完函数之后,静态变量的值不会丢失,这与栈中的临时局部变量明显不同的地方.所以,第一次调用counter(0)之后,count=0第二次调用counter
(1)后count=0+1;第三次调用counter
(2)count=1+2;/*count=count+i*/第四次调用counter(3)count=3+3;第五次调用counter(4)count=6+4;第六次调用counter(5)count=10+5;
命题人信息AshokK.Pathakamember(ResearchStaff)atBharatElectronicsLimited(CRL),Ghaziabad.Hehasbeendevelopingembeddedapplicationforthepastfiveyears.Ashokholdsaincomputerscienceandengineering.Ashokrecentlycompletedabookabout'"AdvancedTestinCandEmbeddedSystemProgramming",PublishedbyBPB,ND.