考查嵌入式C开发人员的最好的16道题.docx
《考查嵌入式C开发人员的最好的16道题.docx》由会员分享,可在线阅读,更多相关《考查嵌入式C开发人员的最好的16道题.docx(18页珍藏版)》请在冰豆网上搜索。
考查嵌入式C开发人员的最好的16道题
考查一个初级嵌入式系统开发人员的C基本功,附有答案题目由资深嵌入式系统专家拟定,
目的是考查入门级的嵌入式软件开发人员GavinShaw提供详细解答.
编者按:
非常基本关于C语言的问题,一个信息类(计算机,资讯工程,电子工程,通信工程)
专业的本科毕业生应该达到的水平,如果你有3道以上的题目不能答对,基本上我们都不好
说什么了....题目不难,全部都能快速地答完,当然也需要一定的知识储备.
约定:
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题:
考查类型转换
structnode
inta;
intb;
intc;
};
structnodes={3,5,6};
structnode*pt=&s;
printf("%d",*(int*)pt);
这段程序的输出是:
(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)xn
(b)x*n
(c)nx
第4题:
考查指针
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
第5题:
考查多维数组与指针
voidfoo(int[][3]);
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题目:
考查逗号表达式
inta,b,c,d;
a=3;
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题:
考查指针数组
inta[][3]={1,2,3,4,5,6};
int(*ptr)[3]=a;
printf("%d%d",(*ptr)[1],(*ptr)[2]);
++ptr;
(a)2356
(b)2345
(c)4500
第8题:
考查函数指针
int*f1(void)
intx=10;
return(&x);
int*f2(void)
int*ptr;
*ptr=10;
returnptr;
int*f3(void)
ptr=(int*)malloc(sizeof(int));
上面这3个函数哪一个最可能引起指针方面的问题
(a)只有f3
(b)只有f1andf3
(c)只有f1andf2
(d)f1,f2,f3
第9题:
考查自加操作(++)
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);
p[0]=f1;
p[1]=f2;
p[0](&a,b);
printf("%d\t%d\t",a,b);
p[1](&a,b);
voidf1(int*p,intq)
inttmp;
tmp=*p;
*p=q;
q=tmp;
voidf2(int*p,intq)
(a)5555
(b)3535
(c)5353
(d)3333
第11题:
考查自减操作(--)
voide(int);
e(a);
voide(intn)
e(--n);
printf("%d",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题:
数组与指针的区别与联系
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)以上都不对
第14题:
考查指针数组的指针
Voidf(char**);
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()那样,这个话题一般国内大学课堂是不会讲到的,不会也情有可原呵呵,
intripple(int,...);
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字面意思是易于挥发的。这个关键字来描述一个变量时,意味着给该变量赋值(写入)之后,马上再读取,写入的值与读取的值可能不一样,所以说它"容易挥发"的。这是因为这个变量可能一个寄存器,直接与外部设备相连,你写入之后,该寄存器也有可能被外部设备的写操作所改变;或者,该变量被一个中断程序,或另一个进程改变了.volatilevariableisn'taffectedbytheoptimization.Itsvalueafterthelongjumpisthelastvaluevariableassumed.blastvalueis5hence5isprinted.setjmp:Setsupfornonlocalgotovolatile不会被编译器优化影响,在longjump后,它的值是后面假定的变量值,b最后的值是5,所以5被打印出来.setjmp:设置非局部跳转Storescontextinformationsuchasregistervaluessothatthelomgjmpfunctioncanreturncontroltothestatementfollowingtheonecallingsetjmp.Returns0whenitisinitiallycalled.Lonjjmp:longjmpPerformsnonlocalgotoLonjjmp:执行一个非局部跳转Transferscontroltothestatementwherethecalltosetjmp(whichinitializedbuf)wasmade.Executioncontinuesatthispointasiflongjmpcannotreturnthevalue0.Anonvolatileautomaticvariablemightbechangedbyacalltolongjmp.Whenyouusesetjmpandlongjmp,theonlyautomaticvariablesguaranteedtoremainvalidarethosedeclaredvolatile.Note:Testprogramwithoutvolatilequalifier(resultmayvery)更详细介绍,请参阅C语言的setjmp和longjmp第2题: (a)Themembersofstructureshaveaddressinincreasingorderoftheirdeclaration.Ifapointertoastructureiscasttothetypeofapointertoitsfirstmember,theresultreferstothefirstmember.结构题的成员在内存中的地址是按照他们定义的位置顺序依次增长的。如果一个结构体的指针被看成它的第一个成员的指针,那么该指针的确指向第一个成员第3题: (a)此题目较难.这个程序的非递归版本intwhat(intx,intn){intval;intproduct;product=1;val=x;while(n>0){if(n%2==1)product=product*val;val=val*val;n=n/2;}returnproduct;}算法描述(whilen>0){ifnextmostsignificantbinarydigitofn(power)isonethenmultiplyaccumulatedproductbycurrentval,reducen(power)sequencebyafactoroftwousingintegerdivision.getnextvalbymultiplycurrentvalueofitself}Nonrecursiveversionoftheprogramintwhat(intx,intn){intval;intproduct;product=1;val=x;while(n>0){if(n%2==1)product=product*val;n=n/2;val=val*val;}}Algorithmdescription(whilen>0){ifnextmostsignificantbinarydigitofn(power)isonethenmultiplyaccumulatedproductbycurrentval,reducen(power)sequencebyafactoroftwousingintegerdivision.getnextvalbymultiplycurrentvalueofitself}第4题: (c)a的类型是一个整型数组,它有5个成员&a的类型是一个整型数组的指针所以&a+1指向的地方等同于a[6]typeofaisarrayofinttypeof&aispointertoarrayofint 所以*(a+1)等同于a[1]ptr等同a[6],ptr-1就等同与a[5]Takingapointertotheelementonebeyondtheendofanarrayissuretowork.第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);Thecommaseparatestheelementsofafunctionargumentlist.Thecommaisalsousedasanoperatorincommaexpressions.Mixingthetwousesofcommaislegal,butyoumustuseparenthesestodistinguishthem.theleftoperandE1isuatedasavoidexpression,thenE2isuatedtogivetheresultandtypeofthecommaexpression.Byrecursion,theexpressionE1,E2,...,Enresultsintheleft-to-rightuationofeachEi,withthevalueandtypeofEngivingtheresultofthewholeexpression.c=a,b;/*yieldsc=a*/d=(a,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);for(;j{i=va_arg(p,int);for(;i;i&=i-1)++k;}当我们调用r
i=va_arg(p,int);
for(;i;i&=i-1)
++k;
returnk;
(a)7
(c)5
(d)3
第16题:
考查静态变量的知识
intcounter(inti)
staticintcount=0;
count=count+i;
return(count);
for(i=0;i<=5;i++)
j=counter(i);
本程序执行到最后,j的值是:
(a)10
(b)15
详细参考答案
(b)
volatile字面意思是易于挥发的。
这个关键字来描述一个变量时,意味着给该变量赋值
(写入)之后,马上再读取,写入的值与读取的值可能不一样,所以说它"容易挥发"的。
这是因为这个变量可能一个寄存器,直接与外部设备相连,你写入之后,该寄存器也有可
能被外部设备的写操作所改变;或者,该变量被一个中断程序,或另一个进程
改变了.
volatilevariableisn'taffectedbytheoptimization.Itsvalue
afterthelongjumpisthelastvaluevariableassumed.
blastvalueis5hence5isprinted.
setjmp:
Setsupfornonlocalgoto
volatile不会被编译器优化影响,在longjump后,它的值是后面假定的变量值,b最后的值是5,所以5被打印出来.
设置非局部跳转
Storescontextinformationsuchasregistervaluessothatthelomgjmp
functioncanreturncontroltothestatementfollowingtheonecalling
setjmp.Returns0whenitisinitiallycalled.
Lonjjmp:
longjmpPerformsnonlocalgoto
执行一个非局部跳转
Transferscontroltothestatementwherethecalltosetjmp(which
initializedbuf)wasmade.Executioncontinuesatthispointasif
longjmpcannotreturnthevalue0.Anonvolatileautomaticvariable
mightbechangedbyacalltolongjmp.Whenyouusesetjmpandlongjmp,
theonlyautomaticvariablesguaranteedtoremainvalidarethose
declaredvolatile.
Note:
Testprogramwithoutvolatilequalifier(resultmayvery)
更详细介绍,请参阅C语言的setjmp和longjmp
(a)
Themembersofstructureshaveaddressinincreasingorderoftheir
declaration.Ifapointertoastructureiscasttothetypeofa
pointertoitsfirstmember,theresultreferstothefirstmember.
结构题的成员在内存中的地址是按照他们定义的位置顺序依次增长的。
如果一个结构体的
指针被看成它的第一个成员的指针,那么该指针的确指向第一个成员
此题目较难.
这个程序的非递归版本
intwhat(intx,intn)
intproduct;
product=1;
val=x;
while(n>0)
if(n%2==1)
product=product*val;
val=val*val;
n=n/2;
returnproduct;
算法描述
(whilen>0)
ifnextmostsignificantbinarydigitofn(power)isone
thenmultiplyaccumulatedproductbycurrentval,
reducen(power)sequencebyafactoroftwousingintegerdivision.
getnextvalbymultiplycurrentvalueofitself
Nonrecursiveversionoftheprogram
Algorithmdescription
(c)
a的类型是一个整型数组,它有5个成员
&a的类型是一个整型数组的指针
所以&a+1指向的地方等同于a[6]
typeofaisarrayofint
typeof&aispointertoarrayofint
所以*(a+1)等同于a[1]
ptr等同a[6],ptr-1就等同与a[5]
Takingapointertotheelementonebeyondtheendofanarray
issuretowork.
题目自身就给了足够的提示
b[0][0] =4
b[1][0] =7
第6题:
考查逗号表达式,逗号表达式的优先级是很低的,比赋值(=)的优先级低.逗号表达式
的值就是最后一个元素的值
逗号表达式的还有一个作用就是分割函数的参数列表..
E1,E2,...,En
上面这个表示式的左右是,E1,E2,...En的值被分别计算出来,En计算出来的结构赋给
整个逗号表达式
c=a,b;/*yieldsc=a*/
Thecommaseparatestheelementsofafunctionargumentlist.Thecommaisalso
usedasanoperatorincommaexpressions.Mixingthetwousesofcommaislegal,
butyoumustuseparenthesestodistinguishthem.theleftoperandE1is
uatedasavoidexpression,thenE2isuatedtogivetheresultandtype
ofthecommaexpression.Byrecursion,theexpression
resultsintheleft-to-rightuationofeachEi,withthevalueandtypeof
Engivingtheresultofthewholeexpression.
ptr是一个数组的指针,该数组有3个int成员
f1显然有问题,它返回一个局部变量的指针,局部变量是保存在stack中的,退出函数后,局
部变量就销毁了,保留其指针没有意义,因为其指向的stack空间可能被其他变量覆盖了
f2也有问题,ptr是局部变量,未初始化,它的值是未知的,*ptr不知道指向哪里了,直接
给*ptr赋值可能会覆盖重要的系统变量,这就是通常说的野指针的一种
sizeof 操作符给出其操作数需要占用的空间大小,它是在编译时就可确定的,所以其
操作数即使是一个表达式,也不需要在运行时进行计算.(++i+++i )是不会执行的,
所以i的值还是3
很显然选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.functionname
withoutparenthesisrepresentaddressoffunctionValueandaddressof
variableispassedtofunctiononlyargumentthatiseffectedisa
(addressispassed).Becauseofcallbyvaluef1,f2cannoteffectb
考查--操作和递归调用,仔细分析一下就可以了
建议不会的看看C专家编程
从左往有,遇到括号停下来,将第一个括号里的东西看成一个整体
考查什么时候数组就是指针.对某些类型T而言,如果一个表达式是T[] (T的数组),
这个表达式的值实际上就是指向该数组的第一个元素的指针.所以(buf+1)[5]实际上就
是*(buf+6)或者buf[6]
sizeof(int)的值是2,所以p+=sizeof(int)指向argv[2],这点估计大家都没有什么
疑问(p+=sizeof(int))[-1]指向argv[1],能理解吗,因为(p+=sizeof(int))[-1]
就相当于(p+=2)[-1],也就是(p+2-1)
在C编译器通常提供了一系列处理可变参数的宏,以屏蔽不同的硬件平台造成的差异,
增加程序的可移植性。
这些宏包括va_start、va_arg和va_end等。
采用ANSI标准
形式时,参数个数可变的函数的原型声明是:
typefuncname(typepara1,typepara2,...)
这种形式至少需要一个普通的形式参数,后面的省略号不表示省略,而是函数原型的一部分。
type是函数返回值和形式参数的类型。
不同的编译器,对这个可变长参数的实现不一样,
gcc4.x中是内置函数.
关于可变长参数,可参阅
程序分析
for(;j{i=va_arg(p,int);for(;i;i&=i-1)++k;}当我们调用r
当我们调用r
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1