c语言的面试题带答案2.docx
《c语言的面试题带答案2.docx》由会员分享,可在线阅读,更多相关《c语言的面试题带答案2.docx(31页珍藏版)》请在冰豆网上搜索。
c语言的面试题带答案2
1.static有什么用途?
(请至少说明两种)
1)限制变量的作用域
2)设置变量的存储域(堆,主动分配内存也是堆)
1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。
它是一个本地的全局变量。
3)在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。
那就是,这个函数被限制在声明它的模块的本地范围内使用。
补充:
一个代码在运行时分为4个区:
1)code:
代码
2)data:
全局,静态,常量没初值则值为0
3)堆:
new,malloc分配的内存,需要delete,free释放。
如果不释放,则只有等程序运行正常结束时,由操作系统回收,理论上无限大。
4)栈:
场景信息(函数的参数,返回值,局部变量,临时变量),VC的栈区默认是4M。
对大内存的操作,需要放堆区。
(没初值则值为无穷大)如:
栈区的空间自动分配自动释放。
Stedentstu[4*1024*1024]会出问题,应改为:
student*stu=newstu[4*1024*1024]释放:
delete[]stu;
4.全局变量和局部变量在内存中是否有区别?
如果有,是什么区别?
全局变量储存在静态数据库,局部变量在栈
6.堆栈溢出一般是由什么原因导致的?
堆栈溢出一般是循环的递归调用导致的,如果使用的大数据结构的局部变量,也可能导致堆栈溢出。
没有回收垃圾资源导致的是内存泄露最后内存耗尽。
20.不能做switch()的参数类型是:
switch的参数不能为实型。
(只能是intchar)
9.写出floatx与“零值”比较的if语句。
if(x<0.000001&&x>-0.000001)
intxif(x==0)if(x!
=0)
int*p;if(NULL==p)if(NULL!
=p)
boolx;if(x)if(!
x)
3.在c语言库函数中将一个字符转换成整型的函数是atol()吗,这个函数的原型是什么?
函数名:
atol
功能:
把字符串转换成长整型数
函数的原型:
longatol(constchar*nptr);
程序例:
#include
#include
intmain(void)
{
longl;
char*str="98765432";
l=atol(lstr);
printf("string=%sinteger=%ld\n",str,l);
return(0);
}
1.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
c用宏定义,c++用inline(内联函数)
8.软件测试都有那些种类?
黑盒:
针对系统功能的测试白合:
测试函数功能,各函数接口
9.确定模块的功能和模块的接口是在软件设计的那个阶段完成的?
概要设计阶段
11.unsignedchar*p1;
unsignedlong*p2;
p1=(unsignedchar*)0x801000;
p2=(unsignedlong*)0x810000;
请问p1+5=?
;
p2+5=?
;
答:
p1+5=0x801005;
p2+5=0x810014;
1.请问下面程序有什么错误?
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[i][j][k]=0;
习惯上应该把循环语句内外换一下----实际上有全部遍历了
(编译的时候没错,运行的时候出错,但这个数组太大,如果放在栈中,还是会溢出,要作为全局变量)
2.#defineMax_CB500
voidLmiQueryCSmd(StructMSgCB*pmsg)
{
unsignedcharucCmdNum;
......
for(ucCmdNum=0;ucCmdNum{
......;
}
死循环(unsignedchar0到255)
3.以下是求一个数的平方的程序,请找出错误:
#defineSQUARE(a)((a)*(a))
inta=5;
intb;
b=SQUARE(a++);//a被加了2次a=7,b=25
2、有一个16位的整数,每4位为一个数,写函数求他们的和。
解释:
整数110101*********1
和1101+0101+1011+0111
/*n就是16位的数,函数返回它的四个部分之和*/
charSumOfQuaters(unsignedshortn)
{
charc=0;
inti=4;
do
{
c+=n&15;
n=n>>4;
}while(--i);
returnc;
}
3、两个字符串,s,t;把t字符串接到s字符串尾,s字符串有足够的空间存放t字符串
voidconnect(char*s,constchar*t)//strcatstrlenstrcpystrcmpstrchrstrstr
{
char*q=t;
char*p=s;
if(q==NULL)return;//1
while(*p!
='\0')//2
{
p++;
}
while(*q!
=0)
{
*p=*q;
p++;
q++;
}
*p='\0';//3
}
voidmain()
{
charp[7]="ABC";
charp2[]="EFG";
connect(p,p2,3);
printf("%s",p);
}
4、分析下面的代码:
char*a="hello";
char*b="hello";
if(a==b)
printf("YES");
else
printf("NO");
常量字符串。
位于静态存储区,它在程序生命期内恒定不变。
如果编译器优化的话,会有可能a和b同时指向同一个hello的。
则地址相同。
如果编译器没有优化,那么就是两个不同的地址,则不同。
对VC,是相同。
5、局部变量能否和全局变量重名?
答:
能,局部会屏蔽全局。
要用全局变量,需要使用":
:
";局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。
对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
2、如何引用一个已经定义过的全局变量?
答:
extern 例如在某个.cpp中定义了一个全局变量inta=6,可在头文件中加入externinta;然后在需要引用的文件中包含该头文件。
或者直接在文件中加入 externinta;
3、全局变量可不可以定义在可被多个.C文件包含的头文件中?
为什么?
答:
可以
解决方法一:
在头文件中用static来定义同名全局变量。
另外某个.C文件中定义的非静态全局变量,可以在其头文件中用extern声明,需引用此全局变量的其他.C只需包含此头文件即可。
解决方法二:
在头文件中使用编译开关:
#ifndefA_H
#defineA_H
。
。
。
。
。
#endif
4、请写出下列代码的输出内容
#include
intmain(void)
{
inta,b,c,d;
a=10;
b=a++; //1011
c=++a; //1212
d=10*a++;//12013
printf("b,c,d:
%d,%d,%d",b,c,d);
return0;
}
答:
10,12,120
5、static全局变量与普通的全局变量有什么区别?
static局部变量和普通局部变量有什么区别?
static函数与普通函数有什么区别?
答:
1)全局变量(外部变量)的说明之前再冠以static就构成了静态的全局变量。
全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。
这两者在存储方式上并无不同。
这两者的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。
而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。
由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
2)从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。
把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
3)static函数与普通函数作用域不同,仅在本文件。
只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。
对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
综上所述:
static全局变量与普通的全局变量有什么区别:
static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:
static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
6、设有以下说明和定义:
typedefunion
{
longi;
intk[5];//20
charc;
}DATE;
structdata
{
intcat;//4
DATEcow;//20
doubledog;//8
}too;
DATEmax;
则语句printf("%d",sizeof(structdata)+sizeof(max));的执行结果是:
考点:
区别struct与union.(一般假定在32位机器上)
答:
DATE是一个union,变量公用空间.里面最大的变量类型是int[5],占用20个字节.所以它的大小是20.data是一个struct,每个变量分开占用空间.依次为int4+DATE20+double8=32.所以结果是20+32=52.
10、请找出下面代码中的所有错误(题目不错,值得一看)
说明:
以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”
#include
#include
#include
intmain()
{
char*src="hello,world";
char*dest=NULL;
intlen=strlen(src);
dest=(char*)malloc(len);
char*d=dest;
char*s=src[len];
while(len--!
=0)
*d++=*s--;
printf("%s",dest);
return0;
}
答:
方法1:
一共有4个错误;
intmain()
{
char*src="hello,world";
intlen=strlen(src);
char*dest=(char*)malloc(len+1);//要为分配一个空间
char*d=dest;
char*s=&src[len-1];//指向最后一个字符
while(len--!
=0)
*d++=*s--;
*d=0;//尾部要加’\0’
printf("%sn",dest);
free(dest);//使用完,应当释放空间,以免造成内存汇泄露
dest=NULL; //防止产生野指针
return0;
}
方法2:
(方法一需要额外的存储空间,效率不高.) 不错的想法
#include
#include
main()
{
charstr[]="hello,world";
intlen=strlen(str);
chart;
for(inti=0;i{
t=str[i];
str[i]=str[len-i-1];//小心一点
str[len-i-1]=t;
}
printf("%s",str);
return0;
}
3.Heap与stack的差别。
答:
Heap是堆,stack是栈。
Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。
Stack空间有限,Heap是很大的自由存储区
C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。
程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行
//124816。
。
。
//110100100010000
//01111111111
3一语句实现x是否为2的若干次幂的判断
#defineis2*n(x)((x&(x-1))?
0:
1)
intmain(void)
{
intm=512;
cout<<((m&(m-1))?
false:
true)< //即当m中只有一位为1时,才为若干次幂值
//考试大提示:
若有两个及以上1,则(m&(m-1))不为0,输出0,表示不为2的若干次幂
return(0);
}
类比:
x为2的若干次幂即表示x中1的位数为1,题目转化为求一个32位数中1的位数,如果为1,则表示该数为2的若干次幂
同理也可以利用此规则求一个32位数中1的位数,(m&(m-1)每次可用消除一个1,计算的次数即为1的个数!
2.下述三个有什么区别?
char*constp;
charconst*p
constchar*p
解答:
char*constp;//常量指针,p的指向不可以修改
charconst*p;//指向常量的指针,指向的常量值不可以改
constchar*p;//和charconst*p
3.解释下列输出结果
charstr1[]="abc";
charstr2[]="abc";
constcharstr3[]="abc";
constcharstr4[]="abc";
constchar*str5="abc";
constchar*str6="abc";
char*str7="abc";
char*str8="abc";
cout<<(str1==str2)<cout<<(str3==str4)<cout<<(str5==str6)<cout<<(str7==str8)<结果是:
0011
解答:
str1,str2,str3,str4是数组变量,它们有各自的内存空间;
而str5,str6,str7,str8是指针,它们指向相同的常量区域。
节省内存。
4.以下代码中的两个sizeof用法有问题吗?
[C易]
#include
#include"iostream.h"
voidUpperCase(charstr[])//将str中的小写字母转换成大写字母
{inti;
for(i=0;i数组做参数,会退化为指针。
可改为strlen(str)
if('a'<=str[i]&&str[i]<='z')
str[i]-=('a'-'A');//由小写转大写
}
voidmain()
{
charstr[]="aBcDefg";
cout<<"str字符长度为:
"<UpperCase(str);
cout<}
答:
函数内的sizeof有问题。
根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。
函数外的str是一个静态定义的数组,因此其大小为8,函数内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为4个字节,因此返回4。
注意:
数组名作为函数参数时,退化为指针.
数组名作为sizeof()参数时,数组名不退化,因为sizeof不是函数.
4.一个32位的机器,该机器的指针是多少位2^32=4G
地址总线宽度决定了CPU可以访问的物理地址空间.简单地说就是CPU到底能够使用多大容量的内存.对于386以上的微机系统.地址线的宽度为32位.最多可以直接访问4096MB(4GB)的物理空间.对大多数人来说已经够用了.
指针是多少位只要看地址总线的位数就行了。
80386以后的机子都是32的数据总线。
所以指针的位数就是4个字节了。
8位处理器、16位处理器、32位处理器和64位处理器,其计数都是8的倍数。
它表示一个时钟周期里,处理器处理的二进制代码数。
“0”和“1”就是二进制代码,线路上有电信号,则计做1,没有电信号则为0。
8位机有8条线路,每个时钟周期有8个电信号,组成一个字节。
所以,随8位处理器上升至64位处理器,每个时钟周期传送1个字节到8个字节,关联到时钟速度提高到若干个千兆赫之后,处理器处理信息的能力越来越大。
CPU的一次基本运算(and,or,xor,not),能处理/运算几个bits.64bitsdata交由32-bitCPU去运算,得分两次才行.
5.指出下面代码的输出,并解释为什么。
(不错,对地址掌握的深入挖潜)
main()
{
inta[5]={1,2,3,4,5};
int*ptr=(int*)(&a+1);//指针是数组类型,+1相当于加20.如果是(a+1)是+4
printf(“%d%d”,a,ptr);
printf("%d,%d",*(a+1),*(ptr-1));
}
输出:
124503612450562,5
a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].
6.请问以下代码有什么问题:
1).
intmain()
{
chara;
char*str=&a;
strcpy(str,"hello");
printf(str);
return0;
}
答;没有为str分配内存空间,将会发生异常
问题出在将一个字符串复制进一个字符变量指针所指地址。
虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。
2).
char*s="AAA";//常量的内容不能改,可定义为数组
printf("%s",s);
s[0]='B';
printf("%s",s);
有什么错?
答:
"AAA"是字符串常量。
s是指针,指向这个字符串常量,所以声明s的时候就有问题。
cosntchar*s="AAA";
然后又因为是常量,所以对是s[0]的赋值操作是不合法的。
7.用变量a给出下面的定义
a)一个整型数(Aninteger)
b)一个指向整型数的指针(Apointertoaninteger)
c)一个指向指针的的指针,它指向的指针是指向一个整型数(Apointertoapointertoaninteger)
d)一个有10个整型数的数组(Anarrayof10integers)
e)一个有10个指针的数组,该指针是指向一个整型数的(Anarrayof10pointerstointegers)
f)一个指向有10个整型数数组的指针(Apointertoanarrayof10integers)
g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数(Apointertoafunctionthattakesanintegerasanargumentandreturnsaninteger)
h)一个有10个函数指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数(Anarrayoftenpointerstofunctionsthattakeanintegerargumentandreturnaninteger)
答案是:
Int(*p[10])(int);
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