1局部变量能否和全局变量重名.docx

上传人:b****6 文档编号:5625995 上传时间:2022-12-29 格式:DOCX 页数:27 大小:30.48KB
下载 相关 举报
1局部变量能否和全局变量重名.docx_第1页
第1页 / 共27页
1局部变量能否和全局变量重名.docx_第2页
第2页 / 共27页
1局部变量能否和全局变量重名.docx_第3页
第3页 / 共27页
1局部变量能否和全局变量重名.docx_第4页
第4页 / 共27页
1局部变量能否和全局变量重名.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

1局部变量能否和全局变量重名.docx

《1局部变量能否和全局变量重名.docx》由会员分享,可在线阅读,更多相关《1局部变量能否和全局变量重名.docx(27页珍藏版)》请在冰豆网上搜索。

1局部变量能否和全局变量重名.docx

1局部变量能否和全局变量重名

1、局部变量能否和全局变量重名?

    答:

能,局部会屏蔽全局。

要用全局变量,需要使用":

:

"

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

对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。

2、如何引用一个已经定义过的全局变量?

    答:

extern

    可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

3、全局变量可不可以定义在可被多个.C文件包含的头文件中?

为什么?

   答:

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

   可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。

4、语句for(;1;)有什么问题?

它是什么意思?

   答:

无限循环,和while

(1)相同。

5、do……while和while……do有什么区别?

   答:

前一个循环一遍再判断,后一个判断以后再循环。

6、请写出下列代码的输出内容

#include

main()

{

inta,b,c,d;

a=10;

b=a++;

c=++a;

d=10*a++;

printf("b,c,d:

%d,%d,%d",b,c,d);

return0;

}

答:

10,12,120

1.static有什么用途?

(请至少说明两种)

   1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。

   2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。

它是一个本地的全局变量。

   3)在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。

那就是,这个函数被限制在声明它的模块的本地范围内使用

2.引用与指针有什么区别?

   1)引用必须被初始化,指针不必。

   2)引用初始化以后不能被改变,指针可以改变所指的对象。

   3)不存在指向空值的引用,但是存在指向空值的指针。

3.描述实时系统的基本特性

      在特定时间内完成特定的任务,实时性与可靠性。

4.全局变量和局部变量在内存中是否有区别?

如果有,是什么区别?

     全局变量储存在静态数据库,局部变量在堆栈。

5.什么是平衡二叉树?

     左右子树都是平衡二叉树且左右子树的深度差值的绝对值不大于1。

6.堆栈溢出一般是由什么原因导致的?

     没有回收垃圾资源。

7.什么函数不能声明为虚函数?

     constructor函数不能声明为虚函数。

8.冒泡排序算法的时间复杂度是什么?

     时间复杂度是O(n^2)。

9.写出floatx与“零值”比较的if语句。

     if(x>0.000001&&x<-0.000001)

10.Internet采用哪种网络协议?

该协议的主要层次结构?

     Tcp/Ip协议

     主要层次结构为:

应用层/传输层/网络层/数据链路层/物理层。

11.Internet物理地址和IP地址转换采用什么协议?

     ARP(AddressResolutionProtocol)(地址解析協議)

12.IP地址的编码分为哪俩部分?

    IP地址由两部分组成,网络号和主机号。

不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。

13.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。

写出C程序。

    循环链表,用取余操作做

14.不能做switch()的参数类型是:

    switch的参数不能为实型。

找错

Voidtest1()

{

  charstring[10];

  char*str1="0123456789";

strcpy(string,str1);

}

Voidtest2()

{

  charstring[10],str1[10];

for(I=0;I<10;I++)

{

    str1[i]='a';

}

strcpy(string,str1);

}

Voidtest3(char*str1)

{

  charstring[10];

  if(strlen(str1)<=10)

{

  strcpy(string,str1);

}

}

2.  找错

#defineMAX_SRM256

DSNget_SRM_no()

{

    staticintSRM_no;

    intI;

    for(I=0;I{

SRM_no%=MAX_SRM;

if(MY_SRM.state==IDLE)

{

  break;

}

}

if(I>=MAX_SRM)

return(NULL_SRM);

else

returnSRM_no;

}

3.  写出程序运行结果

intsum(inta)

{

    autointc=0;

    staticintb=3;

c+=1;

b+=2;

return(a+b+C);

}

  

voidmain()

{

    intI;

inta=2;

for(I=0;I<5;I++)

{

  printf("%d,",sum(a));

}

}

4.  

intfunc(inta)

{

  intb;

  switch(a)

  {

    case1:

30;

    case2:

20;

    case3:

16;

    default:

0

}

returnb;

}

则func

(1)=?

5:

inta[3];

a[0]=0;a[1]=1;a[2]=2;

int*p,*q;

p=a;

q=&a[2];

则a[q-p]=?

6.

定义int**a[3][4],则变量占有的内存空间为:

_____

7.

编写一个函数,要求输入年月日时分秒,输出该年月日时分秒的下一秒。

如输入2004年12月31日23时59分59秒,则输出2005年1月1日0时0分0秒。

5.用变量a给出下面的定义

a)一个整型数(Aninteger)

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

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

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

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

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

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

h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数(Anarrayoftenpointerstofunctionsthattakeanintegerargumentandreturnaninteger)

答案是:

a)inta;//Aninteger

b)int*a;//Apointertoaninteger

c)int**a;//Apointertoapointertoaninteger

d)inta[10];//Anarrayof10integers

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

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

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

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

6)有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC…

1、将一个字符串逆序

2、将一个链表逆序

3、计算一个字节里(byte)里面有多少bit被置1

4、搜索给定的字节(byte)

5、在一个字符串中找到可能的最长的子字符串

6、字符串转换为整数

7、整数转换为字符串

 2.找错题

  试题1:

voidtest1()

{

 charstring[10];

 char*str1="0123456789";

 strcpy(string,str1);

}

  试题2:

voidtest2()

{

 charstring[10],str1[10];

 inti;

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

 {

  str1[i]='a';

 }

 strcpy(string,str1);

}

  试题3:

voidtest3(char*str1)

{

 charstring[10];

 if(strlen(str1)<=10)

 {

  strcpy(string,str1);

 }

}

  解答:

  试题1字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;

  对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string,str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;

  对试题3,if(strlen(str1)<=10)应改为if(strlen(str1)<10),因为strlen的结果未统计’\0’所占用的1个字节。

  剖析:

  考查对基本功的掌握:

  

(1)字符串以’\0’结尾;

  

(2)对数组越界把握的敏感度;

  (3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:

  2分

voidstrcpy(char*strdest,char*strsrc)

{

 while((*strdest++=*strsrc++)!

=‘\0’);

}

  4分

voidstrcpy(char*strdest,constchar*strsrc)

//将源字符串加const,表明其为输入参数,加2分

{

 while((*strdest++=*strsrc++)!

=‘\0’);

}

  7分

voidstrcpy(char*strdest,constchar*strsrc)

{

 //对源地址和目的地址加非0断言,加3分

 assert((strdest!

=null)&&(strsrc!

=null));

 while((*strdest++=*strsrc++)!

=‘\0’);

}

  10分

//为了实现链式操作,将目的地址返回,加3分!

char*strcpy(char*strdest,constchar*strsrc)

{

 assert((strdest!

=null)&&(strsrc!

=null));

 char*address=strdest;

 while((*strdest++=*strsrc++)!

=‘\0’);

  returnaddress;

}

  从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!

需要多么扎实的基本功才能写一个完美的strcpy啊!

  (4)对strlen的掌握,它没有包括字符串末尾的'\0'。

  读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:

intstrlen(constchar*str)//输入参数const

  试题4:

voidgetmemory(char*p)

{

 p=(char*)malloc(100);

}

voidtest(void)

{

 char*str=null;

 getmemory(str);

 strcpy(str,"helloworld");

 printf(str);

}

  试题5:

char*getmemory(void)

{

 charp[]="helloworld";

 returnp;

}

voidtest(void)

{

 char*str=null;

 str=getmemory();

 printf(str);

}

试题6:

voidgetmemory(char**p,intnum)

{

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

}

voidtest(void)

{

 char*str=null;

 getmemory(&str,100);

 strcpy(str,"hello");

 printf(str);

}

  试题7:

voidtest(void)

{

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

 strcpy(str,"hello");

 free(str);

 ...//省略的其它语句

}

  解答:

  试题4传入中getmemory(char*p)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完

char*str=null;

getmemory(str);

  后的str仍然为null;

  试题5中

charp[]="helloworld";

returnp;

  的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。

这是许多程序员常犯的错误,其根源在于不理解变量的生存期。

  试题6的getmemory避免了试题4的问题,传入getmemory的参数为字符串指针的指针,但是在getmemory中执行申请内存及赋值语句

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

  后未判断内存是否申请成功,应加上:

if(*p==null)

{

 ...//进行申请内存失败处理

}

  试题7存在与试题6同样的问题,在执行

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

  后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:

str=null;

  试题6的test函数中也未对malloc的内存进行释放。

  剖析:

  试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。

但是要完全解答正确,却也绝非易事。

  对内存操作的考查主要集中在:

  

(1)指针的理解;

  

(2)变量的生存期及作用范围;

  (3)良好的动态内存申请和释放习惯。

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

swap(int*p1,int*p2)

{

 int*p;

 *p=*p1;

 *p1=*p2;

 *p2=*p;

}

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

在vc++中debug运行时提示错误“accessviolation”。

该程序应该改为:

swap(int*p1,int*p2)

{

 intp;

 p=*p1;

 *p1=*p2;

 *p2=p;

}

  3.内功题

  试题1:

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

  解答:

   bool型变量:

if(!

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<

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

  

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

charstr[10];

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)?

(a):

(b)

#definemin(a,b)(a<=b?

a:

b)

  都应判0分;

  

(2)防止宏的副作用。

  宏定义#definemin(a,b)((a)<=(b)?

(a):

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

((*p++)<=(b)?

(*p++):

(*p++))

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

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

#definemin(a,b)((a)<=(b)?

(a):

(b));

  这个解答在宏定义的后面加“;”,显示编写者对宏的概念模糊不清,只能被无情地判0分并被面试官淘汰。

  试题4:

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

#ifndef__incvxworksh

#define__incvxworksh

#ifdef__cplusplus

extern"c"{

#endif

/*...*/

#ifdef__cplusplus

}

#endif

#endif/*__incvxworksh*/

  解答:

  头文件中的编译宏

#ifndef __incvxworksh

#define __incvxworksh

#endif

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

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

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

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

void

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

当前位置:首页 > PPT模板 > 商务科技

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

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