您的位置:首页 > 其它

考查嵌入式C开发人员的最好的16道题

2010-03-23 09:58 447 查看
考查一个初级嵌入式系统开发人员的C基本功,附有答案题目由资深嵌入式系统专家拟定,目的是考查入门级的嵌入式软件开发人员,GavinShaw提供详细解答.编者按:非常基本关于C语言的问题,一个信息类(计算机,资讯工程,电子工程,通信工程)专业的本科毕业生应该达到的水平,如果你有3道以上的题目不能答对,基本上我们都不好说什么了....题目不难,全部都能快速地答完,当然也需要一定的知识储备.约定:1)下面的测试题中,认为所有必须的头文件都已经正确的包含了2)数据类型char一个字节1byteint两个字节2byte(16位系统,认为整型是2个字节)longint四个字节4bytefloat四个字节4byetdouble八个字节8bytelongdouble十个字节10bytepointer两个字节2byte(注意,16位系统,地址总线只有16位)第1题:考查对volatile关键字的认识
#include<setjmp.h> 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)以上均不是第1题:(b)volatile字面意思是易于挥发的。这个关键字来描述一个变量时,意味着给该变量赋值(写入)之后,马上再读取,写入的值与读取的值可能不一样,所以说它"易变"的.这是因为这个变量可能是一个寄存器,直接与外部设备相连,你写入之后,该寄存器也有可能被外部设备的写操作所改变;或者,该变量被一个中断程序,或另一个进程改变了.volatilevariableisn'taffectedbytheoptimization.Itsvalueafter
thelongjumpisthelastvaluevariableassumed.blastvalueis5hence5isprinted.setjmp:Setsupfornonlocalgoto/*setjmp.h*/Storescontextinformationsuchasregistervaluessothatthelomgjmp
functioncanreturncontroltothestatementfollowingtheonecallingsetjmp.Returns0whenitisinitiallycalled.Lonjjmp:longjmpPerformsnonlocalgoto/*setjmp.h*/Transferscontroltothestatementwherethecalltosetjmp(which
initializedbuf)wasmade.Executioncontinuesatthispointasiflongjmpcannotreturnthevalue0.Anonvolatileautomatic
variablemightbechangedbyacalltolongjmp.Whenyouusesetjmpandlongjmp,theonlyautomaticvariables
guaranteedtoremainvalidarethosedeclaredvolatile.Note:Testprogramwithoutvolatilequalifier(resultmayvery)第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第2题:(a)
(int*)pt指向结构体的第一个成员的地址,pt指向结构体Themembersofstructureshaveaddressinincreasingorderoftheirdeclaration.
Ifapointertoastructureiscasttothetypeofapointertoitsfirstmember,
theresultreferstothefirstmember.
第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(b)x*n(c)n^x(d)以上均不是第3题:(a)Nonrecursiveversionoftheprogram相当于下面的程序:intwhat(intx,intn){intval;//intproduct;//product=1;val=x;while(n>0){//if(n%2==1)//product=product*val;n=n/2;val=val*val;}
returnval;}/*Coderaiseanumber(x)toalargepower(n)usingbinarydoublingstrategy*/Algorithmdescription(whilen>0){ifnextmostsignificantbinarydigitofn(power)isonethenmultiplyaccumulatedproductbycurrentval,reducen(power)sequencebyafactoroftwousingintegerdivision.getnextvalbymultiplycurrentvalueofitself}
第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)以上均不是

第4题:(c)&a+1将指向数组的结尾处

typeofaisarrayofint

typeof&aispointertoarrayofint



Takingapointertotheelementonebeyondtheendofanarrayissuretowork.

第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)以上均不对

第5题:(b)




第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

第6题:(c)c=a,b;//将a赋于c,b不变d=(a,b);//将逗号运算的值b赋于d

Thecommaseparatestheelementsofafunctionargumentlist.Thecommaisalso

usedasanoperatorincommaexpressions.Mixingthetwousesofcommaislegal,

butyoumustuseparenthesestodistinguishthem.theleftoperandE1isevaluated

asavoidexpression,thenE2isevaluatedtogivetheresultandtypeofthe

commaexpression.Byrecursion,theexpression:E1,E2,...,En

resultsintheleft-to-rightevaluationofeachEi,withthevalueandtypeof

Engivingtheresultofthewholeexpression.c=a,b;/*yieldsc=a*/

d=(a,b);/*d=b*/

第7题:考查指针数组

[code]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)以上均不对

第7题:(a)




/*ptrispointertoarrayof3int*/

[/code]
第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

第8题:(c)

f1显然有问题,它返回一个局部变量的指针,局部变量是保存在stack中的,退出函数后,局部变量就销毁了,

保留其指针没有意义,因为其指向的stack空间可能被其他变量覆盖了

f2也有问题,ptr是局部变量,未初始化,它的值是未知的,*ptr不知道指向哪里了,直接给*ptr赋值可能

会覆盖重要的系统变量,这就是通常说的野指针的一种


第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第9题:(b)sizeof操作符给出其操作数需要占用的空间大小,它是在编译时就可确定的,所以其操作数即使是一个表达式,也不需要在运行时进行计算.(++i+++i)是不会执行的,所以i的值还是3

第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第10题:(a)f1交换*p和q的值,f1执行完后,*p和q的值的确交换了,但q的改变不会影响到b的改变,*p实际上就是a,所以执行f1后,a=b=5这道题考查的知识范围很广,包括typedef自定义类型,函数指针,指针数组[code]void(*p[2])(int*,int):定义了一个函数指针的数组p,p有两个指针元素.元素是函数的指针,函数指针指向的函数是一个带2个参数,返回void的函数,函数所带的两个参数是指向整型的指针p[0]=f1;p[1]=f2;containaddressoffunction.functionnamewithoutparenthesisrepresentaddressoffunctionValueandaddressofvariableispassedtofunctiononlyargumentthatiseffectedisa(addressispassed).Becauseofcallbyvaluef1,f2cannoteffectb

[/code]
第11题:考查自减操作(--)[code]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第11题:(a)下载
(24.89KB)2010-1-308:12考查--操作和递归调用,仔细分析一下就可以了[/code]
第12题:考查typedef类型定义,函数指针[code]typedefint(*test)(float*,float*)testtmp;

tmp的类型是(a)函数的指针,该函数以两个指向浮点数(float)的指针(pointer)作为参数(arguments)Pointertofunctionofhavingtwoargumentsthatispointertofloat(b)整型(c)函数的指针,该函数以两个指向浮点数的指针作为参数,并且函数的返回值类型是整型Pointertofunctionhavingtwoargumentthatispointertofloatandreturnint(d)以上都不是第12题:(c)[/code]
建议不会的看看C专家编程,从左往有,遇到括号停下来,将第一个括号里的东西看成一个整体第13题:数组与指针的区别与联系main(){char*p;charbuf[10]={1,2,3,4,5,6,9,8};p=(buf+1)[5];printf("%d",p);}这段程序的输出是:(a)5(b)6(c)9(d)以上都不对第13题:(c)考查什么时候数组就是指针.对某些类型T而言,如果一个表达式是T[](T的数组),这个表达式的值实际上就是指向该数组的第一个元素的指针.所以(buf+1)[5]实际上就是*(buf+6)或者buf[6]第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第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的变长参数,就像标准函数库里printf()那样,这个话题一般国内大学课堂是不会讲到的,不会也情有可原呵呵,#include<stdarg.h>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<n;++j){i=va_arg(p,int);for(;i;i&=i-1)++k;}returnk;}这段程序的输出是:(a)7(b)6(c)5(d)3第15题:(c)在C编译器通常提供了一系列处理可变参数的宏,以屏蔽不同的硬件平台造成的差异,增加程序的可移植性。这些宏包括va_start、va_arg和va_end等。采用ANSI标准形式时,参数个数可变的函数的原型声明是:typefuncname(typepara1,typepara2,...)这种形式至少需要一个普通的形式参数,后面的省略号不表示省略,而是函数原型的一部分。type是函数返回值和形式参数的类型。不同的编译器,对这个可变长参数的实现不一样,gcc4.x中是内置函数.关于可变长参数,可参阅
http://www.upsdn.net/html/2004-11/26.htmlhttp://www.upsdn.net/html/2004-11/24.html
程序分析va_listp;/*定义一个变量,保存函数参数列表的指针*/va_start(p,n);/*用va_start宏初始化变量p,va_start宏的第2个参数n,是一个固定的参数,必须是我们自己定义的变长函数的最后一个入栈的参数也就是调用的时候参数列表里的第1个参数*/for(;j<n;++j)/*j从1开始,遍历所有可变参数*/{i=va_arg(p,int);/*va_arg取出当前的参数,并认为取出的参数是一个整数(int)*/for(;i;i&=i-1)/*判断取出的i是否为0*/++k;/*如果i不为0,k自加,i与i-1进行与逻辑运算,直到i为0这是一个技巧,下面会谈到它的功能*/}当我们调用ripple函数时,传递给ripple函数的参数列表的第一个参数n的值是3.va_start初始化p指向第一个未命名的参数(n是有名字的参数),也就是5(第一个).每次对va_arg的调用,都将返回一个参数,并且把p指向下一个参数.va_arg用一个类型名来决定返回的参数是何种类型,以及在var_arg的内部实现中决定移动多大的距离才到达下一个参数for(;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题:考查静态变量的知识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第16题:(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;
http://hi.baidu.com/lifelens/blog/item/ff92dc4d44e1b1f2d62afc01.html


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: