嵌入式系统开发人员C语言测试题编译预处理.docx
《嵌入式系统开发人员C语言测试题编译预处理.docx》由会员分享,可在线阅读,更多相关《嵌入式系统开发人员C语言测试题编译预处理.docx(10页珍藏版)》请在冰豆网上搜索。
嵌入式系统开发人员C语言测试题编译预处理
8.1 选择题
(695) 根据编码规范,下面说法正确的是____a__。
a.可以使用类型定义符typedef重命名用户类型;
b.typedefcharNAME[20];是正确的定义;
c.可以用宏定义来代替typedef的功能;
d.typedef是在预编译时完成的。
(a)
(696) 下面关于宏定义的说法正确的是:
____abcd____
a.虽然预处理程序可以用#include指令包含任意一个文件,但最好不要用#include指令包含类型名不是".h"的文件,因为这样不容易区分哪些文件是用于编译预处理的;
b.宏表达式及其参数应该使用括号括起来以避免二义性;
c.尽量避免直接在代码中使用数字,应使用有意义的宏定义名字;
d.宏所定义的多条表达式应放在大括号内。
(a.b.c.d)
(697) 下面宏定义符合规范的是___d__
a.#defineREC_AREA(a,b)a*b;
b.#defineREC_AREA(a,b)(a*b);
c.#defineREC_AREA(a,b)(a)*(b);
d.#defineREC_AREA(a,b)((a)*(b))
(d)
(698) 以下叙述正确的是__c__。
a. 根据编码规范,在程序的-行上可以出现多个有效的预处理命令行
b. 使用带参的宏时,参数的类型应与宏定义时的一致
c. 宏替换不占用运行时间,只占编译时间
d. 在以下定义中C R是称为"宏名"的标识符
#define C R 045
(c)
(699) 阅读下面程序:
__b___
#defineLETTER0
main()
{
charstr[20]="MultiMedia",c;
intI;
I=0;
While((c=str[I])!
='\0')
{I++;
#ifLETTER
if(c>='a'&&c<='z')
c=c-32;
#else
if(c>='A'&&c<='Z')
c=c+32;
#endif
printf("%c",c);
}
}
上面程序的运行结果是:
a. MultiMedia
b. multimedia
c. MULTIMEDIA
d. mULTImEDIA
(b)
(700) c语言提供的预处理功能包括条件编译,其定义形式为:
___d___
#XXX标示符
程序段1
#else
程序段2
#endif
这里XXX可以是:
a. define或include
b. ifdef或include
c. ifdef或ifndef或define
d. ifdef或ifndef或if
(d)
(701) 以下正确的描述是__acd__。
a.c语言的预处理功能是指完成宏替换和包含文件的调用
b.预处理指令只能位于c源程序文件的首部
c.凡是c源程序中行首以"#"标识的控制行都是预处理指令
d.C语言的编译预处理就是对源程序进行初步的语法检查
(a.c.d)
(702) 下面关于条件编译的说法不正确的是___d___。
a.#if常量表达式
检查常量表达式计算值是否为非0;
b.#ifdef标识符
检查标识符当前是否预定义过;
c.#undef标识符
如果标识符以前定义过,那么#undef后,标识符就被编译器认为是未定义的了;
d.#ifndef表达式
检查表达式当前是否没有定义过。
(d)
(703) 下面宏定义有可能引发错误的是___abcd___(已知PI是圆周率的宏常量)。
a.#defines(r)PI*(r)*(r)
b.#definel(r)2*PI*(r)
c.#definefun(x)(x++)*(x)
d.#definemax(x,y)x>y?
x:
y
(a.b.c.d)
(704) 在下列有关宏替换的叙述中,正确的说法是___
d__。
a.宏替换占用运行时间
b.宏名有类型
c.带参数的宏替换和函数等价
d.宏替换只是字符替换
(d)
(705) 设有以下宏定义:
___a___
#defineN3
#defineY(n)((N1)*n)
则执行语句:
z=2*(NY(51));后,z的值为
a.出错 b.42 c.48 d.54
(a)
(706) 宏定义#definePI31.14159中,宏名PI代替___d___。
a.单精度 b.双精度 c.常量 d.字符串
(d)
(707) 编译预处理命令以_____d______结尾。
a.; b.. c.\ d.回车
(d)
8.2 填空题
(708) 设有以下宏定义:
#defineWIDTH80
#defineLENGTHWIDTH+40
则执行赋值语句:
v=LENGTH*20;(v为int型变量)后,v的值是____。
(709) 以下程序运行结果是____。
#defineDEBUG
main()
{
inta=20,b=10,c;
c=a/b;
#ifndefDEBUG
printf("a=%o,b=%o",a,b);
#endif
printf("c=%d\n",c);
}
(710) 设有以下程序,为使之正确运行,请在括号中填入应包含的命令行。
其中函数try_me在myfile.h中定义。
________
________
main()
{
printf("\n");
try_me();
printf("\n");
}
(711) 下面程序的运行结果是_____:
#defineMUL(z)(z)*(z)
main()
{
printf("%d\n",MUL(1+2)+3);
}
(712) 下列程序段的输出是_______。
#definef(a,b,x) a*x+b
printf("%d,%dn",f(3,2,1),f(6,5,f(3,2,1)));
(713) 若有以下宏定义:
#define STR "%d,%c"
#define A 97
已知字符a的ASCII码值为97,则语句printf(STR,A,A+2);的输出结果为______。
(714) 宏定义有效范围从定义处开始,到本源程序结束处中止。
但可以用__________来提前解除宏定义的作用。
(715) 下面程序的输出结果是_____。
#defineFMT"%d,"
main()
{
intb[][4]={1,3,5,7,9,11,13,15,17,19,21,23};
printf(FMT,*(*(b+1)+1));
printf(FMT,b[2][2]);
}
8.3 问答与设计
(716) 下面类型定义语句,哪种方法更好?
为什么?
#definedPSstructs*
typedefstructs*tPS;
(717) 头文件中的ifndef/define/endif语句是干什么用的?
(718) 判断下面预编译条件语句是否正确,并改正:
if((cond==GLRUN)
#ifdefDEBUG
||(cond==GLWAIT)
#endif
)
{
…
}
(719) 判断下面预编译条件语句是否正确,并改正:
#defineINIT_RECT_VALUE(a,b)\
a=0;\
b=0;
(720) 用typedef定义一个文件指针FP。
(721) 假如使用了禁止在while的条件部分进行赋值的编译程序选择项,为什么可以查出下面代码中的运算优先级错误?
While(ch=getchar()!
=EOF)
(722) 怎样使用编译程序查出下面无意使用的空语句和赋值语句?
a.if(nCome==063)。
这里程序的本意是十进制63判断,但因为前面多了一个0使063成了八进制数。
结果变成了51。
b.If(pb!
=NULL&pb!
=0xff)。
这里不小心把&&键入为&,结果即使pb等于NULL还会执行*pb!
=0xff。
c.quot=numer/*pdenom。
这里无意间多了个*号结果使/*被解释为注释的开始。
d.word=bHigh<<8+bLow。
由于出现了运算优先级错误,该语句被解释成了:
word=bHigh<<(8+bLow)
(723) 编译程序怎样才能对"没有与之配对的else"这一错误给出警告?
应该怎样消除这一警告?
(724) 如果宏UINT_MAX定义在limit.h中,但假如在程序中忘了include这个头文件,下面的伪指令就会无声无息地失败,因为预处理程序会把预定义的UINT_MAX替换成0:
……
#ifUINT_MAX>65535U
……
#endif
怎样使预处理程序报告出这一错误?
(725) 什么是宏(macro)?
使用宏有哪些好处?
(726) 请说明有参宏和有参函数的区别。
(727) 请说明宏定义的有效范围。
(728) 文件包含的优点是什么?
(729) 请写出条件编译的宏命令。
(730) 指针作为函数参数时能够改变实参的值,请说明其原理。
(731) 使用宏更好,还是使用函数更好?
(732) 什么时候应该用宏代替函数?
(733) 怎样建立对类型不敏感的宏?
(734) 什么是标准预定义宏?
(735) 怎样取消一个已定义的宏?
(736) 预处理程序(preprocessor)有什么作用?
(737) 什么是标准预定义宏?
(738) 标准预定义宏__FILE__有什么作用?
(739) 标准预定义宏__LINE__有什么作用?
(740) 标准预定义宏__DATE__和__TIME__有什么作用?
(741) 怎样才能使程序打印出发生错误的行号?
(742) 怎样才能使程序打印出发生错误的源文件名?
(743) 怎样判断一个程序是用C编译程序还是用C++编译程序编译的?
(744) 怎样避免多次包含同一个头文件?
(745) 可以用#include指令包含类型名不是".h"的文件吗?
(746) #include和#include"file"有什么不同?
(747) 预处理指令#pragma有什么作用?
(748) #line有什么作用?
(749) 包含文件可以嵌套吗?
包含文件最多可以嵌套几层?
(750) 用#define指令说明常量有什么好处?
(751) 与用#define指令说明常量相比,用enum关键字说明常量有什么好处?
(752) 怎样检查一个符号是否已被定义?
(753) 如何使部分程序在演示版中失效?
(754) 预处理指令#pragma有什么作用?
(755) #line有什么作用?
(756) 连接运算符"##"有什么作用?
(757) 请说明typedef与#define的共同点和不同点。
(758) 当程序员为枚举类型增加新元素时,有时会忘记在相应的switch语句中增加新的case条件。
怎样才能使用断言帮助查出这个问题?
(759) 请指出下面函数中的断言的错误并改正。
/*getline───将一个以\n结尾的行读入缓冲区中*/
voidgetline(char*pch)
{
intch; //ch"必须"是int
do
{
ASSERT((ch=getchar())!
=EOF);
}
While((*pch++=ch)!
='\n')
}
(760) 每当使用ASSERT,宏__FILE__就产生一个唯一的文件名字符串。
怎样实现ASSERT宏,才能使文件名字符串在每个文件中只被定义一次?
(761) 用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)。
(762) 写一个"标准"宏MIN,这个宏输入两个参数并返回较小的一个。
#defineMIN(A,B)((A)<=(B)?
(A):
(B))
(763) 预处理器标识#error的目的是什么?
(764) 写出下列程序段的输出结果。
#define A 10
#define B (Aprintf("%d",B*2);
(765) 头文件中的ifndef/define/endif干什么用?
(766) #include和#include"filename.h"有什么区别?
(767) 用typedef语句定义一个返回整型的函数指针类型FPI。
9. 内存管理
9.1 填空题
(768) 下面程序的输出是_____,为什么?
char*ptr;
if((ptr=(char*)malloc(0))==NULL)
{
puts("Gotanullpointer");
}
else
{
puts("Gotavalidpointer");
}
(769) 以下程序运行后的输出结果是______。
main()
{
charm;
m='B'+32;printf("%c\n",m);
}
已有定义如下:
structnode
{
intdata;
structnode*next;
}*p;
以下语句调用malloc函数,使指针p指向一个具有structnode类型的动态存储空间。
请填空。
p=(structnode*)malloc(________);
(770) 在绝对地址0xXXXXXXXX上写入字符'a'的语句是___________。
unsignedchar*p=(unsignedchar*)0xF000FF00;
*p='a';
9.2 问答与设计
(771) 对下面程序段进行解释:
typedefvoid(*lpFunction)();
lpFunctionlpReset=(lpFunction)0xF000FFF0;
lpReset();
(772) 结合编译优化原理,指出下面程序存在的问题并修改。
inta,b,c;
a=inWord(0x100);//读取I/O空间0x100端口的内容存入a变量
b=a;
a=inWord(0x100);//再次读取I/O空间0x100端口的内容存入a变量
c=a;
(773) 以下为常见的内存错误,请分别给出解决措施:
a.内存分配未成功,却使用了它;
b.内存分配虽然成功,但是尚未初始化就引用它;
c.忘记了释放内存,造成内存泄露;
d.内存释放成功,却继续使用它。
(774) 嵌入式系统中动态分配内存可能发生的问题有哪些?
(775) 请分析下面代码,指出问题并改正:
voidGetMemory(T_S8*p,T_S16nNum)
{
p=(T_S8*)malloc(sizeof(T_S8)*nNum);
}
voidTest(void)
{
T_S8*str=NULL;
GetMemory(str,100);
strcpy(str,"hello");
}
(776) 用malloc()函数更好还是用calloc()函数更好?
(777) 说明变量存储在内存(memory)中的什么地方。
(778) 什么是堆?
(779) 什么是栈?
(780) 什么是页抖动?
有些操作系统(如UNIX和增强模式下的Windows)使用虚拟内存,这是一种使机器的作业地址空间大于实际内存的技术,它是通过用磁盘空间模拟RAM(random—accessmemory)来实现的。
在80386和更高级的IntelCPU芯片中,在现有的大多数其它微处理器(如Motorola68030,sparc和PowerPC)中,都有一个被称为内存管理单元(MemoryManagementUnit,缩写为MMU)的器件。
MMU把内存看作是由一系列“页(page)”组成的来处理。
一页内存是指一个具有一定大小的连续的内存块,通常为4096或8192字节。
操作系统为每个正在运行的程序建立并维护一张被称为进程内存映射(ProcessMemoryMap,缩与为PMM)的表,表中记录了程序可以存取的所有内存页以及它们的实际位置。
每当程序存取一块内存时,它会把相应的地址(虚拟地址,virtualaddress)传送给MMU,MMU会在PMM中查找这块内存的实际位置(物理地址,physicaladdress),物理地址可以是由操作系统指定的在内存中或磁盘上的任何位置。
如果程序要存取的位置在磁盘上,就必须把包含该地址的页从磁盘上读到内存中,并且必须更新PMM以反映这个变化(这被称为pagefault,即页错)。
希望你继续读下去,因为下面就要介绍其中的难点了。
存取磁盘比存取RAM要慢得多,所以操作系统会试图在RAM中保持尽量多的虚拟内存。
如果你在运行一个非常大的程序(或者同时运行几个小程序),那么可能没有足够的RAM来承担程序要使用的全部内存,因此必须把一些页从RAM中移到磁盘上(这被为pagingout,即页出)。
操作系统会试图去判断哪些页可能暂时不会被使用(通常基于过去使用内存的情况),如果它判断错了,或者程序正在很多地方存取很多内存,那么为了读入已调出的页,就会产生大量页错动作。
因为RAM已被全部使用,所以为了调入要存取的一页,必须调出另一页,而这将导致更多的页错动作,因为此时不同的一页已被移到磁盘上。
在短时间内出现大量页错动作的情形被称为页抖动,它将大大降低系统的执行效率。
频繁存取内存中大量散布的位置的程序更容易在系统中造成页抖动。
如果同时运行许多小程序,而实际上已经不再使用这些程序,也很容易造成页抖动。
为了减少页抖动,你应该减少同时运行的程序的数目。
对于大的程序,你应该改变它的工作方式,以尽量使操作系统能准确地判断出哪些页不再需要。
为此,你可以使用高速缓冲存储技术,或者改变用于大型数据结构的查找算法,或者使用效率更高的malloc()函数。
当然,你也可以考虑增加系统的RAM,以减少页出动作
(781) 怎样确定一块已分配的内存的大小?
(782) free()函数是怎样知道要释放的内存块的大小的?
(783) 用什么方法存储标志(flag)效率最高?
(784) 8、16位和32位的数是怎样存储的?
(785) 什么是高位字节和低位字节?
(786) 请指出下面代码的错误,并给出修改措施:
T_S8*itoa(T_S16n)
{
T_S8retbuf[20];
sprintf(retbuf,"%d",n); //将整数转化为字符串
returnretbuf; //希望返回字符串
}
(787) 请指出下面代码的错误,并给出修改措施:
T_S8*p=NULL;
T_S16nMemSize=0;
…
p=malloc(1024);
nMemSize=sizeof(p); //希望得到这个指针变量所分配的内存块的大小
(788) 使用malloc()函数时,为什么要将其返回值强制转换成被赋值指针变量的数据类型?
(789) 请写出malloc()的函数原型。
(790) 请设计内存检查方法,使其能够避免对访问被分配内存块之外的内存单元进行访问。
(791) 如果对一个指针指向的内存块释放掉,随后又这块内存进行了再分配,因此,刚才被悬挂的指针又指向了新分配的内存块。
请设计一种方案查出这类错误。
(792) Test函数的运行结果如何?
voidGetMemory(char*p)
{
p=(char*)malloc(100);
}
voidTest(void)
{
char*str=NULL;
GetMemory(str);
strcpy(str,"helloworld");
printf(str);
}
(793) Test函数的运行结果如何?
char*GetMemory(void)
{
charp[]="helloworld";
returnp;
}
voidTest(void)
{
char*str=NULL;
str=GetMemory();
printf(str);
}
(794) Test函数的运行结果如何?
VoidGetMemory2(char**p,intnum)
{
*p=(char*)malloc(num);
}
voidTest(void)
{
char*str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
printf(s