c笔试题汇总更新400道_第1页
c笔试题汇总更新400道_第2页
c笔试题汇总更新400道_第3页
c笔试题汇总更新400道_第4页
c笔试题汇总更新400道_第5页
已阅读5页,还剩143页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C++笔试面试1000题

1.什么是“引用”?申明和使用“引用”要注意哪些问题?

答:引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作

效果完全相同。申明一个引用的时候,切记要对其进行初始化。引用声明完毕后,

相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作

为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用

名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储

单元,系统也不给引用分配存储单元。不能建立数组的引用。

2.指针和引用的区别?

答:引用是在C++中引入的。它们之间的区别有:

(1)非空区别:指针可以为空,而引用不能为空

(2)可修改区别:如果指针不是常指针,那么就可以修改指向,而引用不能

(3)初始化区别:指针定义时可以不初始化,而引用在定义的时必须初始化

3、为什么构造函数不能声明为虚函数?

答:因为虚函数采用的是虚调用的方法,虚调用是指允许在只知道部分信息的情

况下的工作机制,特别允许我们调用一个只知道接口而不知道其对象的准确类型

的函数。但是如果我们要调用构造函数创建对象时,必须要知道对象的准确类型,

因此构造函数不能为虚函数。

4.charstrl[]=wabc”;charstr2[]="abc";strl==str2为FALSE,因为strl

和str2是位于堆栈上的,它们占用不同的内存空间。Constcharstr3[]="abc";

constcharstr4[]="abc";str3==str4为FALSE,同样它们是位于堆栈上的内存空

间,是不同的。Constchar*str5="abc”,constchar*str6="abc";char

*str7="abc",char*str8="abc",str5==str6str7==str8为TRUE,因为“abc”是位

于文字常量区的,系统会将儿个“abc”进行优化,使它们位于同一块内存区,因

此指针的指向也就相同了。

5.以下函数能求出数组的长度吗?

voidfun(charstr[]){intlen=sizeof(str)/sizeof(str[0]);}

答:不能,数组作为参数传递给函数时,数组名被退化为指针,因此函数中的

sizeof(str)实际是在求一个指针的sizeof,答案为4,因此不能计算出数组的长度。

6.类的静态成员和非静态成员有何区别?

答:类的静态成员每个类只有一个,静态成员为所有类的实例对象共享,静态成

员有静态成员变量和静态成员函数,静态成员变量使用前必须初始化,静态成员

变量可以被静态成员函数和非静态成员函数访问,而静态成员函数只能访问静态

成员变量,因为静态成员函数属于类,其没有this指针。非静态成员每个对象都

有一个。

7.static的有什么作用(包括在类中)?

答:(1)函数体内的静态变量,其值在函数的调用过程中保持不变。跟局部变量

的区别。

(2)在函数体外定义的静态变量,限制了它的使用范围只在于该子模块,该

子模块内的函数都能访问它,但是子模块外不能访问,实际就类似于是一个本地

的全局变量。与一般全局变量的区别。

(3)类的静态成员函数。

本质上来说,static就是声明了对象的生成期,限制了对象的作用域。

或(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的

内存只能被分配一次,因此其值在下次函数调用时仍维持上次的值。

(2)在模块内的static全局变量可以被模块内的所有函数访问,但不能被模块

外其他函数访问。

(3)在模块内的static函数只可被这一模块内的其他函数调用,这个函数的使

用范围被限制在声明它的模块。

(4)在类中的static成员变量属于整个类所有,对类的所有对象只有一份拷贝。

(5)在类中的static成员函数属于整个类所有,这个函数不接受this指针,因

而只能访问类的static成员变量。

8.写程序,将一个字符串倒序?

答:直接在main函数中实现的

voidmain()

{

char*source="hello";

char*des;

intlen=strlen(source);

des=(char*)malloc(len+l);〃申请空间必须是len+1,力口1是为了放结束符

if(!des){exit(l);}

char*s=&source[len-l];

char*d=des;

while(len—!=0){*d++=*s—;}

*d='\0';//必须要

cout«source«endl;

cout«des«endl;}

9.在C++程序中调用C编译后的函数,为什么要加externC的声明?

答:因为C++支持函数重载,而C不支持函数重载。函数被C++编译后在库中的

名字与C语言的不同。假设某个函数的原型为:voidfoo(intx,inty);该函数被C

编译器编译后在库中的名字为_f。。,而C++编译器则产生像_foo_int_int之类的名

字。C++提供了C连接交换指定符号externC来解决名字匹配问题。

10.C++中哪些函数不能被声明为虚函数?

答:普通函数(非成员函数),构造函数,内联成员函数、静态成员函数、友元函

数。

(1)虚函数用于基类和派生类,普通函数所以不能

(2)构造函数不能是因为虚函数采用的是虚调用的方法,允许在只知道部分信息

的情况的工作机制,特别允许调用只知道接口而不知道对象的准确类型的方法,

但是调用构造函数即使要创建一个对象,那势必要知道对象的准确类型。

(3)内联成员函数的实质是在调用的地方直接将代码扩展开

(4)继承时,静态成员函数是不能被继承的,它只属于一个类,因为也不存在动

态联编等

(5)友元函数不是类的成员函数,因此也不能被继承

ll.include<filename.h>^Dinclude<<filename.hM的区别?

答:<>是从标准库路径搜索,是从用户当前工作目录开始,找不到,在到标

准库开始

12.编写strlen函数,编写strcpy函数

答:

intStrlen(constchar*str){

intlen=0;

assert(str!=NULL);

while(*str++!=*\0'){len++;}

returnlen;}

非空判断是必须进行的操作,可以使用断言的方式assert(str)!=NULL才会继续

char*StrCpy(char*strDes,constchar*strSrc){

assert((strDes!=NULL)&&(strSrc!=NULL));

char*address=strDes;

while((*strDes++=*strSrc++)!='\0');

returnaddress;}

首先必须判断两个指针是否为空,由于复制后的指针需要返回,因此需要一个指针来记录地址的初始值,最

后将复制的结果返回是为了进行链式操作。

13Heap和Stack的区别?

答:Heap是堆,Stack是栈。

栈的空间由操作系统自动分配和回收,而堆上的空间由程序员申请和释

放。

栈的空间大小较小,而堆的空间较大。

栈的地址空间往低地址方向生长,而堆向高地址方向生长。

栈的存取效率更高。

程序在编译期间对变量和函数的内存分配都在栈上,

且程序运行过程中对函数调用中参数的内存分配也是在栈上。

14.输出的结果是多少,并分析过程?

unsignedshortA=10;

printf("%u\n",~A);

charch=128;

printf(a%d\n”,ch);

答:~A=4294967285,首先将A转化为int类型,即对应的二进制数值为:00000000

000000000000000000001010,~A=11111111111111111111111111110101,其实这

种情况最高位是1,认为是负数,但是在输出中指定以无符号数输出,于是结果为

4294967285=4294967295(四字节表示的最大数)-10.

ch=128对应的二进制为:10000000,在输出中以整数形式输出,由于最高位是1,

于是就是负数,10000000是该负数的补码,根据求补码的反步骤计算,先-1,得到

01111111,在取反得10000000=128,由于本身是负数,即为128.

15、sizeof和strlen之间的区别?

答:(1)sizeof操作符的结果类型是size_t,它在头文件中的typedef为unsignedint

类型,该类型保证能容纳实现所建立的最大对象的字节大小。

(2)sizeof是运算符,strlen是函数

(3)sizeof可以用类型做参数,strlen只能用char*做参数,且必须是

以‘\0'结尾的。

(4)数组做sizeof的参数不退化,传递给strlen就退化为指针。

(5)大部分编译程序在编译的时候就把sizeof计算过了,是类型或是变量

的长度。

(6)strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度,

而不是类型占用内存的大小。

(7)sizeof后如果是类型必须加括号,如果是变量名可以不加括号。

(8)当使用了一个结构类型或变量时,sizeof返回实际的大小。

(9)数组作为参数传递给函数时传的是指针而不是数组,传递的是数组

的首地址。

(10)计算结构变量的大小就必须讨论数组对齐问题。

(11)sizeof操作符不能用于函数类型,不完全类型或位字段。

16.内联函数和宏的差别?

答:内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,

在编译的时候内联函数可以直接被镶嵌到目标代码中,而宏只是一个简单的替换。

内联函数要做参数类型检查,这是与宏相比的优势。

Inline是指嵌入代码,就是在调用函数的地方不是跳转,而是把代码直接写到

那里去。对于短小的代码来说,inline可以带来一定效率的提升,而且和C时代的

宏函数相比,inline更安全可靠。可是这是以增加空间消耗为代价的。

Inline一般只适用于:一个函数被不断地重复调用;函数只有简单的儿行,且

函数内不能含有forwhileswitch语句。

17.请找出下面代码中的所以错误

说明:以下代码是把一个字符串倒序,如“abed”倒序后变为“deba”

Sinclude“string,h”

main(){

char*src="hello,world;

char*dest=NULL;

intlen=strlen(sre);

dest=(char*)malloc(len);

char*d=dest;

char*s=src[len];

while(len-!=0)

d++=s-;

printf("/s”,dest);

return0;

)

答:

方法L

intmain(){

char*sre="hello,world”;

intlen=strlen(src);

char*dest=(char*)malloc(len+1);〃要为\0分配一个空间

char*d=dest;

char*s=&src[lenT];〃指向最后一个字符

while(len-!=0)

*d++=*s-;

*d=0;〃尾部要加\0

printf("%s\n",dest);

free(dest);〃使用完,应当释放空间,以免造成内存汇泄露

return0;

)

18.用两个栈实现一个队列的功能?要求给出算法和思路!

设2个栈为A,B,一开始均为空.

入队:

将新元素push入栈A;

出队:

⑴判断栈B是否为空;

⑵如果不为空,则将栈A中所有元素依次pop出并push到栈B;

(3)将栈B的栈顶元素pop出;这样实现的队列入队和出队的平摊复杂度都还是

0(1),比上面的几种方法要好

19.下面的程序中x是多少?

enumstring{xl,x2,x3=10,x4,x5,}x;

x=0X801005,0x8010f4;

20多态的作用?

主要是两个:L隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码

重用;2.接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例

的某一属性时的正确调用。

21.Newdelete与mallocfree的联系与区别?

都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节

数并且不能初始化对象,new会自动调用对象的构造函数。delete会调用对象的

destructor,而free不会调用对象的destructor.

22.#defineDOUBLE(x)x+x,i=5*D0UBLE(5);i是多少?

答案:i为30。

23.局部变量能否和全局变量重名

答:能,局部会屏蔽全局。要用全局变量,需要使用〃::“

局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部

变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多

个同

名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变

量的作用域就在那个循环体内。2、如何引用一个已经定义过的全局变量答:

extern

可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来

引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间

会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间

不会报错,而在连接期间报错

24全局变量可不可以定义在可被多个.C文件包含的头文件中为什么

答:可以,在不同的C文件中以static形式来声明同名全局变量。

可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中

对此变量赋初值,此时连接不会出错

25.设有以下说明和定义:

typedefunion{longi;intk[5];charc;}DATE;structdata{intcat;DATEcow;doubledog;)too;

DATEmax;

则语句printf(H%d",sizeof(structdate)+sizeof(max));的执行结果是:52

答:DATE是一个union,变量公用空间.里面最大的变量类型是int[5],占用20个字节.所以它

的大小是20data是一个struct,每个变量分开占用空间.依次为int4+DATE20+doubles=32.

所以结果是20+32=52.当然…在某些16位编辑器下,ini可能是2字节,那么结果

是int2+DATE10+double8=2

26.unsignedshorthash(unsignedshortkey){return(key»)%256}

请问hash(16),hash(256)的值分别是:A.1.16;B.8.32;C.4.16;D.1.32

27请问下面程序有什么错误?

inta[60][250][1000],i,j,k;

for(k=0;k<=1000;k++)

for(j=0;j<250;j++)

for(i=0;i<60;i++)

a[j][k]=O;把循环语句内外换一下

28下面程序的打印结果是什么?请分析

#defineMax_CB500

voidLmiQueryCSmd(StructMSgCB*pmsg){

unsignedcharucCmdNum;

for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum+4-){......;}死循环,unsignedint值

范围是0~255

29.各种类型与0值的比较

请写出BOOLflag与“零值”比较的if语句。

标准答案:if(flag)或者if(!flag)

如下写法均属不良风格,不得分。if(flag==TRUE)

if(flag==1)if(flag==FALSE)if(flag==0)

请写出floatx与“零值”比较的if语句。(4分)标准答案示例:

constfloatEPSINON=0.00001;

if((x>=-EPSINON)&&(x<=EPSINON)

不可将浮点变量用或“!=”与数字比较,应该设法转化成“>="或“<二”此类形式

如下是错误的写法,不得分。if(x==0.0)if(x!=0.0)

请写出char*p与“零值”比较的if语句。(3分)标准答案:if(p==NULL)

if(p!=NULL)

如下写法均属不良风格,不得分。if(p==0)if(p!=0)if(p)if(!)

30编写类String的构造函数、析构函数和赋值函数

已知类Siring的原型为:

classString{

public:

String(constchar*str=NULL);//普通构造函数

String(constString&other);//拷贝构造函数

~String(void);〃析构函数

String&operate=(constString&other);//赋值函数

private:

char*m_data;〃用于保存字符串);

请编写String的上述4个函数。标准答案:、

String::-String(void)〃3分{

delete[]m_data;

〃由于m_data是内部数据类型,也可以写成deletem_data;

)

//String的普通构造函数String::String(constchar*str)〃6分{

if(str==NULL){

m_data=newchar[l];//若能加NULL判断则更好

*m_data=<\0,;}else

(

intlength=strlen(str);

String::-String(void)〃3分{

delete[]m_data;

〃由于m_data是内部数据类型,也可以写成deletem_data;

)

“String的普通构造函数

String::String(constchar*str)〃6分{

if(str==NULL){

m_data=newchar[l];〃若能力I」NULL判断则更好

*m_data=<\0,;}

else

intlength=strlen(str);

strcpy(m_data,other.m_data);}

〃赋值函数

String&String::operate=(constString&other)〃13分(

〃(1)检查自赋值〃4分if(this==&other)

return*this;〃文章来源草根IT

〃⑵释放原有的内存资源〃3分

delete[]m_data;

//(3)分配新的内存资源,并复制内容〃3分

intlength=strlen(other.m_data);

m_data=newchar[length+l];//若能加NULL判断则更好

strcpy(m_data,other.m_data)

//(4)返回本对象的引用〃3分

return*this;}

31引用”与指针的区别是什么?

指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序

的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。此外,

就是上面提到的对函数传ref和pointer的区别

32结构与联合有和区别?

1.结构和联合都是由多个不同的数据类型成员组成,但在任何同一时刻,联合中只存放了

一个被选中的成员(所有成员共用一块地址空间),而结构的所有成员都存在(不同成员的存

放地址不同)。

2.对于联合的不同成员赋值,将会对其它成员重写,原来成员的值就不存在了,而对于结

构的不同成员赋值是互不影响的

33.下面关于“联合”的题目的输出?

a)#include<stdio.h>union{

inti;

charx[2];}a;

voidmain(){

a.xfO]=10;a.x[l]=1;printf("%dH,a.i);}

答案:266(低位低地址,高位高地址,内存占用情况是OxOlOA)

b)main(){

union{/*定义一个联合*/

inti;

struct{/*在联合中定义一个结构*/

charfirst;charsecond;}half;}number;

number.i=0x4241;/*联合成员赋值*/

prinlf("%c%c\n",number.half.first,mumber.half.second);

number.half.first='a,;/*联合中结构成员赋值*/

number.half.second=,b,;

getch();}

答案:AB(0x41对应,A',是低位;0x42对应B,是高位)6261(number.i和number.half

共用一块地址空间)

34关联、聚合(Aggregation)以及组合(Composition)的区别?

涉及到UML中的一些概念:关联是表示两个类的一般性联系,比如“学生”和“老师”

就是一种关联关系;聚合表示has-a的关系,是一种相对松散的关系,聚合类不需要对被聚合

类负责,如下图所示,用空的菱形表示聚合关系:

从实现的角度讲,聚合可以表示为:

classA{...}classB{A*a;..…}而组合表示contains-a的关系,关联性强于聚合:组合类

与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关

系:实现的形式是:

classA{...}classB{Aa;...}

35面向对象的三个基本特征,并简单叙述之?

1.封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private,protected,

public)2.继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需

额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性

和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=>接口继承以及纯虚

函数)构成了功能复用的两种方式。

3.多态:是将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就

可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子

类类型的指针赋值给父类类型的指针

36.重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?

重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数

类型不同,或许两者都不同)。重写:是指子类重新定义复类虚函数的方法。从实现原理

上来说:重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数

就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:functionfunc(p:

integer):integer;和functionfunc(p:string):integer;»那么编译器做过修饰后的函数名称

可能是这样的:int_func、stjfunc.对于这两个函数的调用,在编译器间就已经确定了,是静态

的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!重写:

和多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,

动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函

数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)

37多态的作用是什么?

主要是两个:1.隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;2.接

口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用

38若没有定义拷贝构造函数,则编译器自动生成一个缺省的拷贝构造函数,它可能会产生什

么问题?

浅拷贝问题,主要原因为类中如果有指针成员变量时,当调用拷贝构造函数时只拷贝地址从

而使两个对象的指针变量指向了一个地址空间。

39简述成员函数、全局函数和友元函数的差别。

成员函数只能由该类所实例化的对象来进行调用。[静态成员除外]

全局函数可以在任意位置进行调用。

友元函数可以让本类和友元类对象调用。

40.简述结构化的程序设计、面向对象的程序设计的基本思想。

结构化程序设计为从程序代码的开始处按照顺序方式执行至代码的结束位置。是一种顺序的方

式,函数与变量没有明显的联系,面向对象主要把处理事情的事物和方法结合为一体成为一

个类,一个类具备处理一件事情的数据变量和处理方法,把数据和方法有机的结合为了一体,

使每一件事情都具备一定的独立性,形成一个模块。增加了内聚性,降低了耦合性。同时也增

加了代码的可读性以及代码的重用性。

41结构struct和类class有什么异同?

在c语言中struct只能对数据进行聚合,而C++的class把数据以及对数据的处理方法也同时聚

合为•体,增加了内聚性。止匕外class拥有可再生性和可抽象性,实现的代码的复用。集中体

现在派生的功能和多态的功能。同时class也比struct具备更好的封装性,体现在三种访问权

限上。

在C++中的struct和class的结构基本一致,只是struct的默认权限为Public而class为private0

42C++是不是类型安全的?

答案:不是。两个不同类型的指针之间可以强制转换(用reinterpretcast)。C#是类型安全

的。

43简述数组与指针的区别?

数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任

意类型的内存块。(1)修改内容上的差别

chara[]="hello";a[0]='X';

char*p="world";〃注意p指向常量字符串

p[0]='X';〃编译器不能发现该错误,运行时错误

(2)用运算符sizeof可以计算出数组的容量(字节数)。sizeof(p),p为指针得到的是

一个指针变量

的字节数,而不是p所指的内存容量。C++/C语言没有办法知道指针所指的内存容量,除非

在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指

针。

chara[]="helloworld";char*p=a;cout«sizeof(a)«endl;//12字

节cout«sizeof(p)«endl;//4字节计算数组和指针的内存容

量voidFunc(chara[100]){cout«sizeof(a)«endl;//4字节不是100字节)

44如何判断一段程序是由C编译程序还是由C++编译程序编译的?

答案:#ifdef_cpluspluscout«"c++";#elsecout«"c";#endif

45.main主函数执行完毕后,是否可能会再执行一段代码,给出说明?

答案:可以,可以用_onexit注册一个函数,它会在main之后执行intfnl(void),fn2

(void),fn3(void),fn4(void);voidmain(void){

Stringstr("zhanglin");_onexit(fnl);_onexit(fn2);_onexit(fn3);_onexit(fn4);

printf("ThisisexecutedfirstAn");}

intfnl(){printf(Hnext.\n");return0;}

intfn2(){printf("executed");return0;}

intfn3(){printf("is");return0;}

intfn4(){printf('This*');return0;}

46文件中有一组整数,要求排序后输出到另一个文件中

#include<iostream>#include<fstream>usingnamespacestd;

voidOrder(vector<int>&data)//bubblesort{

intcount=data.size()

inttag=false〃设置是否需要继续冒泡的标志位

for(inti=0i<counti++)

{

for(intj=0j<count-i-1j++){

if(data[j]>data[j+l]){

tag=true

inttemp=data[j]

data[j]=data[j+l]datafj+1]=temp}

)

if(!tag)break})

voidmain(void){

vector<int>data;

ifstreamin("c:\\data.txtn);if(Jin){

cout«"fileerror!";

exit(l);}

inttemp;

while(!in.eof()){

in»temp;

data.push_back(temp);}

in.close。;〃关闭输入文件流Order(data);

ofstreamout("c:\\result.txt,');if(!out)

(

cout«*'fileerror!";

exit(l);)

for(i=0i<data.size()i++)

out«data«nn;

out.close。;〃关闭输出文件流}

47链表题:一个链表的结点结构

structNode{

intdataNode*next};

typedefstructNodeNode

(1)已知链表的头结点head,写一个函数把这个链表逆序(Intel)

Node*ReverseList(Node*head)〃链表逆序{

if(head==NULLIIhead->next==NULL)

returnhead;Node*pl=head;Node*p2=p1->next;Node*p3=p2->next;pl->next=NULL;

while(p3!=NULL){

p2->next=pl;pl=p2;p2=p3

p3=p3->next;}

p2->next=pl;head=p2;returnhead;}

(2)已知两个链表headl和head2各自有序,请把它们合并成一个链表依然有序。(保留

所有结点,即便大小相同)

Node*Merge(Node*headl,Node*head2){

if(head1==NULL)returnhead2;

if(head2==NULL)returnhead1;

Node*head=NULL;

Node*pl=NULL;Node*p2=NULL;

if(headl->data<head2->data){

head=headlpl=headl->next;p2=head2}else

{

head=head2;p2=head2->next;pl=headl;

)

Node*pcurrent=head;

while(pl!=NULL&&p2!=NULL){

if(pl->data<=p2->data){

pcurrent->next=pl;

pcurrent=pl;

pl=pl->next;}

else{

pcurrent->next=p2;pcurrent=p2;p2=p2->next}

)

if(pl!=NULL)pcurrent->next=pl;

if(p2!=NULL)

pcurrent->next=p2;returnhead;}

(3)已知两个链表headl和head2各自有序,请把它们合并成一个链表依然有序,这次要求

用递归方法进行。(Autodesk)答案:

Node*MergeRecursive(Node*headl,Node*head2){

if(headl==NULL)returnhead2;

if(head2==NULL)returnhead1;

Node*head=NULL;

if(head1->data<head2->data){

head=head1;

head->next=MergeRecursive(head1->next,head2);}else{head=head2;

head->next=MergeRecursive(head1,head2->next);}

returnhead;}

48写一个函数找出一个整数数组中,第二大的数(microsoft)

答案:

constintMINNUMBER=-32767

intfind_sec_max(intdataf],intcount){

intmaxnumber=data[0];intsec_max=MINNUMBER;

for(inti=1i<counti++){

if(data>maxnumber){

sec_max=maxnumber;

maxnumber=data;}else{

if(data>sec_max)

sec_max=data;}}

returnsec_max;}

49如何判断一个单链表是有环的?(注意不能用标志位,最多只能用两个额外指

针)

structnode{charval;node*next;}

boolcheck(constnode*head){)//returnfalse:无环;true:有环

一种O(n)的办法就是(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环

的话两者必然重合,反之亦然):

boolcheck(constnode*head){

if(head==NULL)retumfalse;node*low=head,*fast=head->next;while(fast!=NULL&

&fast->next!=NULL){

low=low->next;

fast=fast->next->next;

if(low==fast)returntrue;}

returnfalse;}

50用变量a给出下面的定义

a)一个整型数(Aninteger)b)一个指向整型数的指针(Apointertoaninteger)

c)一个指向指针的的指针,它指向的指针是指向一个整型数

(Apointertoapointertoaninteger)d)一个有10个整型数的数组(Anarrayof10integers)e)一

个有10个指针的数组,该指针是指向一个整型数的(Anarrayof10pointerstointegers)f)一

个指向有10个整型数数组的指针(Apointertoanarrayof10integers)

g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数

a)inta;//Aninteger

b)int*a;〃Apointertoaninteger

c)int**a;〃Apointertoapointertoanintegerd)inta[10];//Anarrayof10integers

e)int*a[10];//Anarrayof10pointerstointegers

f)int(*a)[10];//Apointertoanarrayof10integers

g)int(*a)(int);//Apointertoafunctionathattakesanintegerargumentandreturnsaninteger

h)int(*a[10])(int);

51关键字const是什么含意?

我只要一听到被面试者说:“const意味着常数”,我就知道我正在和一个业余者打交道。下

面的声明都是什么意思?constinta;

intconsta;

int*consta;

intconst*aconst;

前两个的作用是一样,a是一个常整型数。第三个意味着a是•个指向常整型数的指针(也

就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就

是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指

向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改

的)。

52关键字volatile有什么含意并给出三个不同的例子。

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假

设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个

变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:1).并行设

备的硬件寄存器(如:状态寄存器)2).一个中断服务子程序中会访问到的非自动变量

(Non-automaticvariables)

3).多线程应用中被几个任务共享的变量(回答下面问题)

1).一个参数既可以是const还可以是volatile吗?解释为什么。

2).一个指针可以是volatile吗?解释为什么。

3).下面的函数有什么错误:intsquare(volatileint*ptr){

return*ptr**ptr;}

下面是答案:

1).是的。-个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是

const因为程序不应该试图去修改它。

2).是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buiTer的指

针时。3).这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,

由于*ptr指向一个volatile型参数,编译器将产生类似卜一面的代码:intsquare(volatileint*ptr){

inta,b;a=*ptr;b=*ptr;returna*b;}由于*ptr的值可能被意想不到地该变,因此a和b可能

是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

longsquare(volatileint*ptr){

inta;a=*ptr;

returna*a;

53用C++写个程序,如何判断一个操作系统是16位还是32位的?不能用sizeofO

函数

A1:

16位的系统下,

inti=65536;

cout«i;//输出0;

inti=65535;

cout«i;//输出T;

32位的系统下,

inti=65536;

cout«i;//输出65536;

inti=65535;

cout«i;//输出65535;

A2:

inta=、0;

if(a>65536){cout<<z/32bit,,<<endl;}

else{cout«z,16bitz,«endl;}

54C和C++有什么不同?

从机制上:C是面向过程的(但C也可以编写面向对象的程序);C++是面向对象的,

提供了类。但是,C++编写面向对象的程序比C容易从适用的方向:C适合要求代

码体积小的,效率高的场合,如嵌入式;C++适合更上层的,复杂的;llinux核

心大部分是c写的,因为它是系统软件,效率要求极高。从名称上也可以看出,

C++比c多了+,说明C++是c的超集;那为什么不叫c+而叫C++呢,是因为C++比

c来说扩充的东西太多了,所以就在c后面放上两个+;于是就成了c++C语言是结

构化编程语言,C++是面向对象编程语言。C++侧重于对象而不是过程,侧重于类

的设计而不是逻辑的设计

55在不用第三方参数的情况下,交换两个参数的值

#include<stdio.h>voidmain(){

inti=60;

intj=50;

i=i+j;

j=i-j;

i=i-j;

printf("i=%d/n",i);

printf("j=%d/n",j);}

方法二:

56下面的代码有什么问题?

classA{

public:

A(){p=this;)

~A(){if(p!=NULL){deletep;p=NULL;}}

A*p;

);

答:会引起无限递归

57sizeof用法总结

在VC中,sizeof有着许多的用法,而且很容易引起一些错误。下面根据sizeof后面的参数对

sizeof的用法做个总结。

A.参数为数据类型或者为一般变量。例如sizeof(int),sizeof(k)ng)等等。这种情况要注意的

是不同系统系统或者不同编译器得到的结果可能是不同的。例如int类型在16位系统中占2

个字节,在32位系统中占4个字节。

B.参数为数组或指针。下面举例说明.

intal5OJ;〃sizeof(a)=4*50=200;求数组所占的空间大小

int*a=newint[5OJ;//sizeof(a)=4;a为指针sizeof(a)是求指针的大小,在32位系统中,当然

是占4个字节。

C.参数为结构或类。Sizeof应用在类和结构的处理情况是相同的。但有两点需要注意,第

一、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结

构或者类的实例地址无关。

第二、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一个实例在内存中都

有唯一的地址。下面举例说明,

ClassTest{inta;staticdoublec};//sizeof(Test)=4.

Test*s;//sizeof(s)=4,s为一个指针。

Classtestl{};//sizeof(testl)=l;

D.参数为其他。下面举例说明。

intfunc(chars[5]){

cout<vsizeof(s);〃这里将输出4,本来s为一个数组,但山于做为函数的参数在传递的时

候系统处理为一个指针,所以sizeof(s)实际上为求指针的大小。

return1;

)

sizeof(func("1234,,))=4//Efunc的返回类型为int,所以相当于求sizeof(int).

58.i最后等于多少?

inti=1;

intj=i++;

if((i>j++)&&(i++==j))i+=j;

答:i=5

59数据库:抽出部门,平均工资,要求按部门的字符串顺序排序,不能含有〃human

resource”部门,employee结构如下:employee_id,employee_name,

depart_id,depart_name,wage

答:

selectdepart_name,avg(wage)

fromemployee

wheredepart_name<>'humanresource'

groupbydepart_name

orderbydepart_name

60试编写函数判断计算机的字节存储顺序是开序(littleendian)还是降序

(bigendian)

答:

boolIsBigendian(){

unsignedshortusData=Ox1122;

unsignedchar*pucData=(unsignedchar*)&usData;

return(*pucData==0x22);

)

61.线程同步的总结

对几种同步对象的总结

1.CriticalSection

A.速度快

B.不能用于不同进程

C.不能进行资源统计(每次只可以有一个线程对共享资源进行存取)

2.Mutex

A.速度慢

B.可用于不同进程

C.不能进行资源统计

3.Semaphore

A.速度慢

B.可用于不同进程

C.可进行资源统计(可以让一个或超过一个线程对共享资源进行存取)

4.Event

A.速度慢

B.可用于不同进程

C.可进行资源统计

62逻辑思维题:101个硬币100真、1假,真假区别在于重量。请用无祛码天平称

两次给出真币重还是假币重的结论。

答:1。个先取出2堆,33,33

第次称,如果不相等,说明有一堆重或轻那么把重的那堆拿下来,再放另外35个中的33

如果相等,说明假的重,如果不相等,新放上去的还是重的话,说明假的轻(不可能新放上去的轻)

第一次称,如果相等的话,这66个肯定都是真的,从这66个中取出35个来,与剩下的没称过的

35个比下面就不用说了

方法二:

第3题也可以拿A(50),B(50)比一下,一样的话拿剩下的一个和真的比一下。如果不一样,就

拿其中的一堆。比如A(50)再分成两堆25比一下,一样的话就在B(50)中,不一样就在A(50)中,

结合第一次的结果就知道了

63intid[sizeof(unsignedlong));这个对吗?为什么??

答:对,这个sizeof是编译时运算符,编译时就确定了可以看成和机器有关的常量。

64在C++程序中调用被C编译器编译后的函数,为什么要加extern"C”?

首先,作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键

字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。

通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声

明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件

即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但

是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数

extern"C"是连接申明(linkagedeclaration),被extern"C”修饰的变量和函数是按照C语言方式编

译和连接的,来看看C++中对类似。

C的函数是怎样编译的:

作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译

后在符号库中的名字与c语言的不同。例如,假设某个函数的原型为:

voidfoo(intx,inty);

该函数被C编译器编译后在符号库中的名字为_f。。,而C++编译器则会产生像一foo_int_int之

类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为

“mangledname")。

_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实

现函数重载的。例如,在C++中,函数voidfoo(intx,inty)与voidfoo(intx,floaty)编译生成

的符号是不相同的,后者为_foo_int_float。同样地,C++中的变量除支持局部变量外,还支

持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以来

区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一

无二的名字,这个名字与用户程序中同名的全局变量名字不同

65#defineDOUBLE(x)x+x,i=5*D0UBLE(5);i是多少?

答案:i为30。(注意直接展开就是了)5*5+5

66在8086汇编下,逻辑地址和物理地址是怎样转换的?(Intel)

答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址*10H+通用寄

存器内地址,就得到了真正要访问的地址。

67如何打印出当前源文件的文件名以及源文件的当前行号?答案:

cout«_FILE_;

cout<<_LINE—;

_FILE二和_ZlNE_是系统预定义宏,这种宏并不是在某个文件中定义的,而是

由编译器定义的

68观察下面的程序,找出错误,主要是字符串的操作

试题1:voidtestl(){

charstring[10];

char*strl="0123456789”;

strcpy(string,strl);

)

试题2:Voidtest2(){

charstring[10],strl[10];

inti;

for(i=0;i<10;i++){strl=!a';}

strcpy(string,strl);

)

试题3:voidtest3(char*strl){

charstring[10];

if(strlen(strl)<=10){strcpy(string,strl);}

)

解答:

试题1字符串strl需要11个字节才能存放下(包括末尾的、0)而string只有10个字节

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论