东软CC++笔试Word文件下载.docx

上传人:b****5 文档编号:20786611 上传时间:2023-01-25 格式:DOCX 页数:18 大小:30.52KB
下载 相关 举报
东软CC++笔试Word文件下载.docx_第1页
第1页 / 共18页
东软CC++笔试Word文件下载.docx_第2页
第2页 / 共18页
东软CC++笔试Word文件下载.docx_第3页
第3页 / 共18页
东软CC++笔试Word文件下载.docx_第4页
第4页 / 共18页
东软CC++笔试Word文件下载.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

东软CC++笔试Word文件下载.docx

《东软CC++笔试Word文件下载.docx》由会员分享,可在线阅读,更多相关《东软CC++笔试Word文件下载.docx(18页珍藏版)》请在冰豆网上搜索。

东软CC++笔试Word文件下载.docx

*strDest目的字符串,*strSrc源字符串,length源字符串的长度

函数实现为:

char*convert(char*strDest,constchar*strSrc,intlength)

char*cp=strDest;

inti=0;

while(*strSrc&

&

i{

if(*strSrc==’\t’)//将\t转换成4个空格

for(intj=0;

j<

4;

j++)

*cp++='

'

;

else//否则直接拷贝

*cp++=*strSrc;

strSrc++;

i++;

returnstrDest;

7.下列哪两个是等同的

intb;

Aconstint*a=&

b;

Bconst*inta=&

Cconstint*consta=&

Dintconst*consta=&

各式表示的意思分别为:

//*a是const,但指针a可变

//a是const,但*a可变

//a和*a都是const,常量和指针的值都不能改变

因此C,D两者是相同的。

总结个技巧:

如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;

如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。

5.struct和class有什么区别?

默认的访问级别不同,struct是public,class是private

6.没有别的不同了吗?

再看看下面的一段程序有什么错误:

Code

swap(int*p1,int*p2)

 int*p;

 *p=*p1;

 *p1=*p2;

 *p2=*p;

在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。

在VC++中DEBUG运行时提示错误“AccessViolation”。

野指针,也就是指向不可用内存区域的指针。

通常对这种指针进行操作的话,将会使程序发生不可预知的错误。

“野指针”不是NULL指针,是指向“垃圾”内存的指针。

人们一般不会错用NULL指针,因为用if语句很容易判断。

但是“野指针”是很危险的,if语句对它不起作用。

野指针的成因主要有两种:

一、指针变量没有被初始化。

任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。

所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。

二、指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。

别看free和delete的名字恶狠狠的(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。

通常会用语句if(p!

=NULL)进行防错处理。

很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。

例:

char*p=(char*)malloc(100);

strcpy(p,“hello”);

//p所指的内存被释放,但是p所指的地址仍然不变

if(p!

=NULL)//没有起到防错作用

strcpy(p,“world”);

//出错

另外一个要注意的问题:

不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。

该程序应该改为:

 intp;

 p=*p1;

 *p2=p;

3.内功题

试题1:

分别给出BOOL,int,float,指针变量与“零值”比较的if语句(假设变量名为var)

解答:

BOOL型变量:

var)

int型变量:

if(var==0)

float型变量:

constfloatEPSINON=0.00001;

   if((x>

=–EPSINON)&

(x<

=EPSINON)

指针变量:

 if(var==NULL)

剖析:

考查对0值判断的“内功”,BOOL型变量的0判断完全可以写成if(var==0),而int型变量也可以写成if(!

var),指针变量的判断也可以写成if(!

var),上述写法虽然程序都能正确运行,但是未能清晰地表达程序的意思。

一般的,如果想让if判断一个变量的“真”、“假”,应直接使用if(var)、if(!

var),表明其为“逻辑”判断;

如果用if判断一个数值型变量(short、int、long等),应该用if(var==0),表明是与0进行“数值”上的比较;

而判断指针则适宜用if(var==NULL),这是一种很好的编程习惯。

浮点型变量并不精确,所以不可将float变量用“==”或“!

=”与数字比较,应该设法转化成“>

=”或“<

=”形式。

如果写成if(x==0.0),则判为错,得0分。

试题2:

以下为WindowsNT下的32位C++程序,请计算sizeof的值

voidFunc(charstr[100])

 sizeof(str)=?

void*p=malloc(100);

sizeof(p)=?

sizeof(str)=4

sizeof(p)=4

Func(charstr[100])函数中数组名作为函数形参时,在函数体内,数组名失去了本身的内涵,仅仅只是一个指针;

在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

数组名的本质如下:

(1)数组名指代一种数据结构,这种数据结构就是数组;

例如:

charstr[10];

cout<

<

sizeof(str)<

endl;

  输出结果为10,str指代数据结构char[10]。

(2)数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;

str++;

//编译出错,提示str不是左值 

(3)数组名作为函数形参时,沦为普通指针。

WindowsNT32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof(str)、sizeof(p)都为4。

试题3:

写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。

另外,当你写下面的代码时会发生什么事?

least=MIN(*p++,b);

#defineMIN(A,B)((A)<

=(B)?

(A):

(B))

MIN(*p++,b)会产生宏的副作用

这个面试题主要考查面试者对宏定义的使用,宏定义可以实现类似于函数的功能,但是它终归不是函数,而宏定义中括弧中的“参数”也不是真的参数,在宏展开的时候对“参数”进行的是一对一的替换。

程序员对宏定义的使用要非常小心,特别要注意两个问题:

(1)谨慎地将宏定义中的“参数”和整个宏用用括弧括起来。

所以,严格地讲,下述解答:

#defineMIN(A,B)(A)<

(B)

#defineMIN(A,B)(A<

=B?

A:

B)都应判0分;

(2)防止宏的副作用。

  宏定义#defineMIN(A,B)((A)<

(B))对MIN(*p++,b)的作用结果是:

((*p++)<

=(b)?

(*p++):

(*p++))这个表达式会产生副作用,指针p会作三次++自增操作。

除此之外,另一个应该判0分的解答是:

(B));

这个解答在宏定义的后面加“;

”,显示编写者对宏的概念模糊不清,只能被无情地判0分并被面试官淘汰。

宏的一些副作用

1、优先级问题

1)传入变量优先级

#defineMULTI(a,b)a*b

MULTI(1+2,3)=>

1+2*3其实是想要(1+2)*3

2)作为值返回时,类似1)

#defineADD(a,b)(a)+(b)

intc=ADD(a,b)*3;

=>

(a)+(b)*3其实是想要(a+b)*3

所以,一般的规则是:

宏里面参数全部用括号括起来;

如果作为值返回,整个表达式也用括号括起来。

所以,上面最好这么写:

#defineMULTI(a,b)((a)*(b))

#defineADD(a,b)((a)+(b))

2、实际使用参数和宏内部变量同名

#defineHASH(str,sz,rst)do{unsignedintn=0;

n=xxx;

rst=n%sz;

}while(0)

这是一个hash的宏实现,其中定义了一个临时变量n,根据str计算n,然后对sz求模并把返回值赋给传进来的rst.

这么调用:

intn;

HASH(“hello”,7,n);

不会达到改变n的效果,因为实际使用参数n和宏内部的变量n同名。

宏扩展中最后一条语句是:

n=n%sz;

因为宏内部n有更小作用域,实际赋值的是宏内部的那个临时变量n。

外面调用的n不会有任何改变。

这个副作用有些隐蔽,一般的规则是:

宏内部变量使用一种不同风格的命名方式。

比如:

#defineHASH(str,sz,rst)do{unsignedint__n=0;

__n=…

3、++,–

#defineMAX(a,b)((a)>

(b)?

(a):

(b))

inta=3,b=2;

intc=MAX(a++,b);

执行看看,不但a的值不是和想要的一致,返回值c也会让你大吃一惊,哈哈。

(a=5,c=4)

在宏内部一个变量”执行”多少次,它就自增或自减了多少次。

所以一般使用宏最好不要传入自增自减。

如果你一定要在宏里消除这个副作用,可以这样:

#defineMAX(a,b)({int__x=(a),__y=(b);

(__x>

__y)?

__x:

__y;

})

也就是:

保证传入宏的参数在内部只使用一次。

(注意:

传入a++或++a都能得到各自正确的效果)

这里的内部变量__x,__y是不需要用括号包起来的,原因可以自己想想。

另外对宏中括号的使用补充说明两点:

因为宏中定义了临时变量,所以要用{}括起来;

因为要返回值,所以外面还要用()括起来({}不返回值);

另外,这里还有一个问题:

实际中a,b不一定是int的,这个宏中的临时变量声明为int,不通用。

改进:

#defineMAX(a,b,type)({type__x=(a),__y=(b);

使用:

MAX(1,2,int);

MAX(1.1,1.2,double);

是不是感觉怪怪的,有点c++的感觉~~这样的使用太复杂了,而且也会给代码的阅读带来难度。

我觉得好的态度是多了解些宏的可能的副作用,在实际编码中遵守第1、2条规则,不要往宏中传入自增自减的东西,就够了。

不要把过多的复杂度全扔给宏,”通用”也不能盲目,因为毕竟:

yy是没有极限的。

试题4:

为什么标准头文件都有类似以下的结构?

#ifndef__INCvxWorksh

#define__INCvxWorksh

#ifdef__cplusplus

extern“C”{

#endif

/**/

#endif/*__INCvxWorksh*/

头文件中的编译宏

#ifndef __INCvxWorksh

#define __INCvxWorksh

的作用是防止被重复引用。

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

函数被C++编译后在symbol库中的名字与C语言的不同。

例如,假设某个函数的原型为:

voidfoo(intx,inty);

该函数被C编译器编译后在symbol库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。

_foo_int_int这样的名字包含了函数名和函数参数数量及类型信息,C++就是考这种机制来实现函数重载的。

为了实现C和C++的混合编程,C++提供了C连接交换指定符号extern“C”来解决名字匹配问题,函数声明前加上extern“C”后,则编译器就会按照C语言的方式将该函数编译为_foo,这样C语言中就可以调用C++的函数了。

试题5:

编写一个函数,作用是把一个char组成的字符串循环右移n个。

比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh”

函数头是这样的:

//pStr是指向以’\0′结尾的字符串的指针

//steps是要求移动的n

voidLoopMove(char*pStr,intsteps)

 //请填充…

正确解答1:

voidLoopMove(char*pStr,intsteps)

 intn=strlen(pStr)–steps;

 chartmp[MAX_LEN];

 strcpy(tmp,pStr+n);

 strcpy(tmp+steps,pStr);

 *(tmp+strlen(pStr))=‘\0′;

 strcpy(pStr,tmp);

正确解答2:

 memcpy(tmp,pStr+n,steps);

 memcpy(pStr+steps,pStr,n);

 memcpy(pStr,tmp,steps);

这个试题主要考查面试者对标准库函数的熟练程度,在需要的时候引用库函数可以很大程度上简化程序编写的工作量。

最频繁被使用的库函数包括:

(1)strcpy

(2)memcpy

(3)memset

memcpy

  原型:

externvoid*memcpy(void*dest,void*src,unsignedintcount);

  用法:

#include

  功能:

由src所指内存区域复制count个字节到dest所指内存区域。

  说明:

src和dest所指内存区域不能重叠,函数返回指向dest的指针。

  注意:

与strcpy相比,memcpy并不是遇到’\0′就结束,而是一定会拷贝完n个字节。

  举例:

  //memcpy.c

  #include

  intmain(intargc,char*argv[])

  {

  char*s=”GoldenGlobalView”;

  chard[20];

  clrscr();

  memcpy(d,s,strlen(s));

  d[strlen(s)]=’\0′;

  printf(“%s”,d);

  getchar();

  return0;

  }

  截取view

  memcpy(d,s+14,4);

  //memcpy(d,s+14*sizeof(char),4*sizeof(char));

也可

  d[4]=’\0′;

  输出结果:

  View

  初始化数组

  charmsg[10];

  memcpy(msg,0,sizeof(msg));

memset

函数原型

  void*memset(void*s,intch,unsignedn);

编辑本段

程序例

  

memset函数

intmain(void)

  charbuffer[]=“Helloworld\n”;

  printf(“Bufferbeforememset:

%s\n”,buffer);

  memset(buffer,‘*’,strlen(buffer));

  printf(“Bufferaftermemset:

  Bufferbeforememset:

Helloworld

  Bufferaftermemset:

***********

  编译平台:

  MicrosoftVisualC++6.0

  也不一定就是把内容全部设置为ch指定的ASCII值,而且该处的ch可为int或者其他类型,并不一定要是char类型。

例如下面这样:

  intarray[5]={1,4,3,5,2};

  for(inti=0;

i<

5;

i++)

  cout<

"

?

  memset(s,'

G'

6);

//貌似这里有点问题//单步运行到这里会提示内存访问冲突

  printf("

%s"

s);

  } 

  【应该是没有问题的,字符串指针一样可以,并不是只读内存,可以正常运行】

  3。

memset()函数常用于内存空间初始化。

如:

  charstr[100];

  memset(str,0,100);

  4。

memset()的深刻内涵:

用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘memset(a,'

\0'

sizeof(a));

  memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;

  chara[100],b[50];

  memcpy(b,a,sizeof(b));

//注意如用sizeof(a),会造成b的内存地址溢出。

  strcpy就只能拷贝字符串了,它遇到'

就结束拷贝;

  strcpy(a,b);

  如用strcpy(b,a),要注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。

  5.补充:

某人的一点心得

  memset可以方便的清空一个结构类型的变量或数组。

  如:

  structsample_struct

  charcsName[16];

  intiSeq;

  intiType;

  };

  对于变量

  structsample_strcutstTest;

  一般情况下,清空stTest的方法:

  stTest.csName[0]='

  stTest.iSeq=0;

  stTest.iType=0;

  用memset就非常方便:

  memset(&

stTest,0,sizeof(structsample_struct));

  如果是数组:

  structsample_structTEST[10];

  则

  memset(TEST,0,sizeof(structsample_struct)*10);

试题8:

请说出static和const关键字尽可能多的作用

static关键字至少有下列n个作用:

(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

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

(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

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

(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

const关键字至少有下列n个作用:

(1)欲阻止一个变量被改变,可以使用const关键字。

在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了

(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时

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

当前位置:首页 > 法律文书 > 调解书

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

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