C语言笔试题.docx
《C语言笔试题.docx》由会员分享,可在线阅读,更多相关《C语言笔试题.docx(60页珍藏版)》请在冰豆网上搜索。
C语言笔试题
1.1
#ifdefNDEBUG
#defineTRACE(S)S
#else
#defineTRACE(S)printf("%s;/n",#S);S
#endif
问:
以上TRACE()宏的作用是什么?
1.2#error的作用?
1.3定义一个宏,求出给定数组中的元素的个数
#defineNELEMENTS(array)?
?
1.4定义一个宏,求出给定结构中给定成员的偏移量
#defineOFFSET(structure,member)?
?
【2数据声明和定义】
给定以下类型的变量a的定义式:
a)Aninteger
b)Apointertoaninteger
c)Apointertoapointertoaninteger
d)Anarrayof10integers
e)Anarrayof10pointerstointegers
f)Apointertoanarrayof10integers
g)Apointertoafunctionthattakesanintegerasanargumentandreturnsaninteger
h)Anarrayoftenpointerstofunctionsthattakeanintegerargumentandreturnaninteger
【3复杂类型
(1)】
有如下表达式:
char(*(*x())[])();
请用文字描述x是什么。
【4复杂类型
(2)】
jmp_buf的定义:
typedefstruct_jmp_buf
{
REG_SETreg;
intextra[3];
}jmp_buf[1];
setjmp函数的原型:
externintsetjmp(jmp_buf__env);
问:
调用setjmp时传递__env的内容,还是传递指针?
【5头文件】
问:
为什么标准头文件都有类似以下的结构?
#ifndef__INCvxWorksh
#define__INCvxWorksh
#ifdef__cplusplus
extern"C"{
#endif
/*...*/
#ifdef__cplusplus
}
#endif
#endif/*__INCvxWorksh*/
【6static关键字】
请说出static关键字的3种用处:
(1)用于全局变量;
(2)用于局部变量;
(3)用于函数。
/*file.c*/
staticinta;
intb;
staticintfn()
{
staticintx;
inty;
}
【7const关键字】
7.1const关键字的意义是什么?
7.2解释以下的变量定义:
constinta1;
intconsta2;
constint*a3;
int*consta4;
intconst*consta5;
【8volatile关键字】
8.1volatile意义?
例如
volatileint*p;
8.2volatile能和const一起使用吗?
例如
volatileconstint*p;
【9sizeof()】
有以下定义:
char*pmsg="A";
charmsg[]="A";
charch='A';
问:
sizeof(pmsg)=?
sizeof(msg)=?
sizeof(“A”)=?
sizeof(ch)=?
sizeof(‘A’)=?
(在C++中等于多少?
)
voidf(charparam[100])
{
//sizeof(param)=?
}
【10字符串】
有以下代码
char*pmsg="hello,world!
";
strcpy(pmsg,"hi,there.");
试评论该代码。
【11混合运算】
有以下代码:
voidfoo()
{
unsignedinta=6;
intb=-20;
(a+b>6)?
puts(">6"):
puts("<=6");
}
请问调用foo()的输出?
【12内存访问】
有以下代码:
voidfn()
{
inta[100];
int*p;
p=(int*)((unsignedint)a+1);
printf(“p=0x%x/n”,*p);
}
试评论以上代码。
【13C库函数】
请说明以下函数的意义:
voidperror(constchar*__s);
fdprintf(int,constchar*,...);
isspace(),isxdigit(),strerr(),sprintf()
答案,仅供参考:
1.1这道题主要考察#的功能,S是一个表达式。
TRACE()的作用就是在DEBUG状态下,计算表达式S的值之前先打印S。
1.2#error用于向编译器报错,并输出它后面带的错误信息。
例如:
#ifndefSOMETHING
#errorSOMETHINGnotdefined!
#endif
如果在这段代码之前未定义过SOMETHING,则在编译时出错,并给出"SOMETHINGnotdefined!
"的错误信息。
1.3#defineNELEMENTS(array)(sizeof(array)/sizeof((array)[0]))
1.4#defineOFFSET(structure,member)((int)&(((structure*)0)->member))
2(a)Aninteger:
inta;
(b)Apointertoaninteger:
int*a;
(c)Apointertoapointertoaninteger:
int**a;
(d)Anarrayof10integers:
inta[10];
(e)Anarrayof10pointerstointegers:
int*a[10];
(f)Apointertoanarrayof10integers:
int(*a)[10];
(g)Apointertoafunctionthattakesanintegerasanargumentandreturnsaninteger:
int(*a)(int);
(h)Anarrayof10pointerstofunctionsthattakeanintegerargumentandreturnaninteger:
int(*a[10])(int);
3char(*(*x())[])();
这道题来自"TheCProgrammingLanguage"中的一个例子。
首先,确定标识符:
x
x是一个函数,没有参数:
x()
返回值是一个指针:
*x()
这个指针指向一个数组:
(*x())[]
数组中的每个元素是指针:
*(*x())[]
指向一个不带参数的函数:
(*(*x())[])()
函数的返回值是char:
char(*(*x())[])()
这里,要知道*、()和[]的优先级。
4这个定义有点怪,它的意思是:
jmp_buf这种类型是一个数组,只有一个元素,元素类型为struct{...}。
数组名作为函数参数时,应该是传递地址/指针。
5在编译源文件时,C编译器和C++编译器都会对符号(函数或变量)名作某些修正,但两者采用的修正方法不同,所以两者生成的目标文件不能互相链接。
在C++中使用extern"C"可以让C++符号获得C链接特性。
由于C++编译器会自动定义__cplusplus宏,所以在C语言头文件中采用这种结构可以保证无论使用何种编译器,生成的目标文件都具有C链接特性,能够与标准C编译器所生成的目标文件相链接。
6
(1)用于全局变量:
外部静态变量,只能在本源文件中被引用,不能被其它源文件所引用。
(2)用于局部变量:
局部静态变量,在函数返回后存储单元不释放;下一次调用该函数时,该变量为上次函数返回时的值。
(3)用于函数:
内部函数,只能被本源文件中的函数所调用,不能被其它源文件调用。
7.1const关键字在C语言中用于声明"常变量",其值不可修改,但具有确定的数据类型。
C编译器总是为其分配相应的存储单元。
在C++中,const关键字用于声明常量,C++编译器视具体情况决定是为其分配存储单元还是仅将其作为编译期间的常量。
7.2constinta1;a1是整型常量。
intconsta2;a2是整型常量。
等同于constinta2;
constint*a3;a3是指针(a3是可变的),指向一个整型常量。
等同于intconst*a3;
int*consta4;a4是常量指针(a4不可变),指向一个整型变量。
intconst*consta5;a5是常量指针(a5不可变),指向一个整型常量。
等同于constint*consta5;
8.1volatile关键字用于声明内存映射的易失型变量,这类变量的值随时可能由于某种编译器所不知道的原因(例如,外部设备对其写入)所改变,所以编译器在进行代码优化时不能对其做任何的假设和依赖。
8.2volatile可以和const一起使用,不过很少见。
const关键字的意思是限制编程者自己不能修改变量的值;两者并不矛盾。
例如一个内存映射的、只读的硬件寄存器,假设它的地址是p,则可以这样声明:
volatileconstUINT32*p;
9sizeof(pmsg)=指针变量的长度
sizeof(msg)=2(字符数组的长度)
sizeof("A")=2(字符串的长度)
sizeof(ch)=1(字符变量的长度)
sizeof(‘A’)=整型变量的长度(在C语言中,字符常量的数据类型实际上是int;在C++中,它的数据类型是char,从而原式等于1)
sizeof(param)=指针变量的长度(数组名作参数时,传递的是数组的起始地址)
10这种写法是和编译器&操作系统相关的,所以不应当这样写。
在WIN2K+VC环境下debug程序时会出现异常。
不过这样写,编译器不会报错。
按道理,"hello..."的类型是constchar[N],它是不能赋值给char*的,
因为会丢失常量属性。
但在const关键字成为C标准之前,大家都这样写程序,所以char*pmsg="hello..."
这种写法被给予特别豁免,即使在C++中也是如此,在"TheC++ProgrammingLanguage"的附录里对此有讨论。
"hello,world!
"是字符串常量(stringliteral),它的类型是constchar[N],N为字符串的长度(包括结尾的0)。
"TheCProgrammingLanguage"指出,写字符串常量的结果是未定义的(undefined)。
所以在有些平台(操作系统+编译器)
上程序不会出错,而在其它平台上程序出现异常。
GNU手册里这样说:
Writingintostringconstantsisaverybadidea;"constants"shouldbeconstant.
不过在GNU中它提供另外的选择:
使用-fwritable-strings进行编译就可以。
那么,为什么不允许修改字符串常量呢(它不也在内存中吗)?
这可能和另外一个特点有关,即重复字符串的合并。
现在的编译器应该会主动帮助我们合并程序中相同的字符串常量
以节省内存。
如果stringliteral可写,就会出现问题。
例如:
voidfoo()
{
printf("%s/n","howareyou?
");
}
voidbar()
{
char*p="howareyou?
";
strcpy(p,"WHOAREYOU?
");
}
调用foo()当然会打印"howareyou"。
但如果编译器合并字符串,那么先调用bar(),再调用foo(),foo()打印的就是
"WHOAREYOU?
"。
这当然不是我们想要的结果。
另外一方面,这样写也有问题(确实有人这么写):
if(func()=="something")
...
func()是:
char*func()
{
...
return"something";
}
这就假设编译器一定会帮我们合并字符串,然而那也不一定。
11输出">6"。
混合运算时的数据类型转换次序:
int-->unsigned-->long-->double。
另外,char和short必定转换为int,float必定转换为double。
12p=(int*)((unsignedint)a+1);
代码的意图是想使p指向数组的第二个元素,但通常的写法是:
p=a+1。
这里存在这样的问题:
a是个常量地址,
a+1指向下一个数组元素,而((unsignedint)a+1)指向下一个内存地址。
如果地址是字节计数的,则p指向的
是数组第一个元素的第二个字节。
还有一个效果就是:
在RISC上该printf语句会出异常,因为不允许非对齐访问
(mis-alignedaccess)。
对齐访问就是访问2字节变量的地址要能被2整除,4字节变量的地址要能被4整除,etc。
13这些函数到处都查得到,就不用做了吧.
【1使用宏】
1.1
#ifdefNDEBUG
#defineTRACE(S)S
#else
#defineTRACE(S)printf("%s;\n",#S);S
#endif
问:
以上TRACE()宏的作用是什么?
1.2#error的作用?
1.3定义一个宏,求出给定数组中的元素的个数
#defineNELEMENTS(array)?
?
1.4定义一个宏,求出给定结构中给定成员的偏移量
#defineOFFSET(structure,member)?
?
【2数据声明和定义】
给定以下类型的变量a的定义式:
a)Aninteger
b)Apointertoaninteger
c)Apointertoapointertoaninteger
d)Anarrayof10integers
e)Anarrayof10pointerstointegers
f)Apointertoanarrayof10integers
g)Apointertoafunctionthattakesanintegerasanargumentandreturnsaninteger
h)Anarrayoftenpointerstofunctionsthattakeanintegerargumentandreturnaninteger
【3复杂类型
(1)】
有如下表达式:
char(*(*x())[])();
请用文字描述x是什么。
【4复杂类型
(2)】
jmp_buf的定义:
typedefstruct_jmp_buf
{
REG_SETreg;
intextra[3];
}jmp_buf[1];
setjmp函数的原型:
externintsetjmp(jmp_buf__env);
问:
调用setjmp时传递__env的内容,还是传递指针?
【5头文件】
问:
为什么标准头文件都有类似以下的结构?
#ifndef__INCvxWorksh
#define__INCvxWorksh
#ifdef__cplusplus
extern"C"{
#endif
/*...*/
#ifdef__cplusplus
}
#endif
#endif/*__INCvxWorksh*/
【6static关键字】
请说出static关键字的3种用处:
(1)用于全局变量;
(2)用于局部变量;
(3)用于函数。
/*file.c*/
staticinta;
intb;
staticintfn()
{
staticintx;
inty;
}
【7const关键字】
7.1const关键字的意义是什么?
7.2解释以下的变量定义:
constinta1;
intconsta2;
constint*a3;
int*consta4;
intconst*consta5;
【8volatile关键字】
8.1volatile意义?
例如
volatileint*p;
8.2volatile能和const一起使用吗?
例如
volatileconstint*p;
【9sizeof()】
有以下定义:
char*pmsg="A";
charmsg[]="A";
charch='A';
问:
sizeof(pmsg)=?
sizeof(msg)=?
sizeof(“A”)=?
sizeof(ch)=?
sizeof(‘A’)=?
(在C++中等于多少?
)
voidf(charparam[100])
{
//sizeof(param)=?
}
【10字符串】
有以下代码
char*pmsg="hello,world!
";
strcpy(pmsg,"hi,there.");
试评论该代码。
【11混合运算】
有以下代码:
voidfoo()
{
unsignedinta=6;
intb=-20;
(a+b>6)?
puts(">6"):
puts("<=6");
}
请问调用foo()的输出?
【12内存访问】
有以下代码:
voidfn()
{
inta[100];
int*p;
p=(int*)((unsignedint)a+1);
printf(“p=0x%x\n”,*p);
}
试评论以上代码。
【13C库函数】
请说明以下函数的意义:
voidperror(constchar*__s);
fdprintf(int,constchar*,...);
isspace(),isxdigit(),strerr(),sprintf()
coon@23:
44:
01|阅读全文|评论0|引用0|编辑
c语言笔试题(九)
2006-09-06
Tag:
C语言
1.
#include"stdio.h"
intmain()
{
inta;
int*p;
p=&a;
*p=0x500;
a=(int)(*(&p));
a=(int)(&(*p));
if(a==(int)p)
printf("equal!
\n");
else
printf("notequal!
\n");
}
请问本程序的输出显示是什么?
答案:
输出显示为”equal!
”
2.
struct{
signedintbit0:
1;
signedintbit1:
1;
signedintbit2:
1;
signedintbit3:
1;
signedintbit4:
1;
signedintbit5:
1;
signedintbit6:
1;
signedintbit7:
1;
}bits;
请问sizeof(bits)是否是正确的表达式?
请问语句bitsmybits;的定义是否正确?
如果不正确,要如何修改上述的结构定义才能使该语句正确?
修改后的结构定义是否会影响sizeof(bits)的正确性?
如果正确则该表达式的值为多少?
如果将上述的结构中int类型改为char类型,此时sizeof(bits)的大小为多少?
答案:
1)是正确的表达式,因为sizeof后面的内容可以是类型,也可以是变量。
2)该语句的定义不正确,因为此时的bits为一个变量;应该这样修改结构的定义
typedefstruct{
signedintbit0:
1;
signedintbit1:
1;
signedintbit2:
1;
signedintbit3:
1;
signedintbit4:
1;
signedintbit5:
1;
signedintbit6:
1;
signedintbit7:
1;
}bits;
修改后sizeof(bits)表达式依然正确,其值为4;类型改为char后其值为1,注意该值是在VC环境中的32位程序中得到的值,在不同的编译器其值有可能不同,因此在编程时不能自己假定类似结构的大小。
3.
structbit{
unsignedinta[0]:
1,a[1]:
1,a[2]:
1….a[7]:
1;
}
请问这种写法是否正确?
为什么?
答案:
不正确,位域中的变量不能是数组。
4.
structa{
intx;
chary;
structaz;
structa*p;
}
请问这种定义结构正确否?
如果有问题,问题在哪里?
答案:
结构中不能对定义结构本身的非指针变量,如果编译器支持则会导致无限嵌套,因此一般编译器都会认为structa是未定义的类型,即使提前声明也不会有任何用处。
5.什么是可重入函数?
C语言中写可重入函数,应注意的事项?
答案:
可重入函数是指能够被多个线程“同时”调用的函数,并且能保证函数结果的正确性的函数。
在编写可重入函数时通常要注意如下的一些问题:
尽量不要使用全局变量,静态变量,如果使用了应该注意对变量访问的互斥。
通常可以根据具体的情况采用:
信号量机制,关调度机制,关中断机制等方式来保证函数的可重入性。
不要调用不可重