考查嵌入式C开发人员的最好的0x10道题.docx

上传人:b****5 文档编号:4449964 上传时间:2022-12-01 格式:DOCX 页数:18 大小:82KB
下载 相关 举报
考查嵌入式C开发人员的最好的0x10道题.docx_第1页
第1页 / 共18页
考查嵌入式C开发人员的最好的0x10道题.docx_第2页
第2页 / 共18页
考查嵌入式C开发人员的最好的0x10道题.docx_第3页
第3页 / 共18页
考查嵌入式C开发人员的最好的0x10道题.docx_第4页
第4页 / 共18页
考查嵌入式C开发人员的最好的0x10道题.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

考查嵌入式C开发人员的最好的0x10道题.docx

《考查嵌入式C开发人员的最好的0x10道题.docx》由会员分享,可在线阅读,更多相关《考查嵌入式C开发人员的最好的0x10道题.docx(18页珍藏版)》请在冰豆网上搜索。

考查嵌入式C开发人员的最好的0x10道题.docx

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

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

考查一个初级嵌入式系统开发人员的C基本功,附有答案题目由资深嵌入式系统专家拟定,目的是考查入门级的嵌入式软件开发人员GavinShaw提供详细解答

编者按:

非常基本关于C语言的问题,一个信息类(计算机,资讯工程,电子工程,通信工程)专业的本科毕业生应该达到的水平。

题目不难,全部都能快速地答完,当然也需要一定的知识储备。

对于大多数人,我们预期你可能答错3)  4) 15)题,所以答错3道以内的,我们认为你很棒

答错5道题以内,我们认为你还不错(你还可能答错第9题)

如果你有6道以上的题目不能答对,基本上我们都不好说什么了....

约定:

  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个参数,返回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是函数返回值和形式参数的类型。

不同的编译器,对这个可变长参数的实现不一样,gcc4.x中是内置函数.

关于可变长参数,可参阅

程序分析

va_listp;/*定义一个变量,保存函数参数列表的指针*/

va_start(p,n);/*用va_start宏初始化变量p,

va_start宏的第2个参数n,

是一个固定的参数,

必须是我们自己定义的变长函数的最后一个入栈的参数

也就是调用的时候参数列表里的第1个参数*/

for(;j

{

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是有名字的参数),也就是is5(第一个).

每次对va_arg的调用,都将返回一个参数,并且把p指向下一个参数.

va_arg用一个类型名来决定返回的参数是何种类型,以及在var_arg的内部实现中决定移动多大的距离才到达下一个参数

(;i;i&=i-1)k++/*计算i有多少bit被置1*/

5用二进制表示是(101)2

7用二进制表示(111)3

所以k返回5(2+3),也即本题应该选c

举个例子,就很好理解了

令i=9=1001

i-1=1000

(i-1)+1=i

1000

+1

1001

因为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.AshokholdsaM.Eincomputerscienceandengineering.Ashokrecentlycompletedabookabout'"AdvancedTestinCandEmbeddedSystemProgramming",PublishedbyBPB

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1