《C语言面试题(经典全)(共40页).doc》由会员分享,可在线阅读,更多相关《C语言面试题(经典全)(共40页).doc(40页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上1.static有什么用途?(请至少说明两种)1)限制变量的作用域2)设置变量的存储域(堆,主动分配内存也是堆)1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。 3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。4.全局变量和局部变量在内存中是否有区别?如果有,是什么区别?全局变量储存在静态数据库,局部变量在栈6.堆栈溢出一般是由什么原因导
2、致的?堆栈溢出一般是循环的递归调用导致的,如果使用的大数据结构的局部变量,也可能导致堆栈溢出。没有回收垃圾资源导致的是内存泄露最后内存耗尽。20.不能做switch()的参数类型是:switch的参数不能为实型。(只能是int char)9.写出float x 与“零值”比较的if语句。if(x-0.)3.在c语言库函数中将一个字符转换成整型的函数是atol()吗,这个函数的原型是什么?函数名: atol功能: 把字符串转换成长整型数函数的原型: long atol(const char *nptr);程序例:#include #include int main(void)long l;cha
3、r *str = ;l = atol(lstr);printf(string = %s integer = %ldn, str, l);return(0);1.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C+中应用什么实现?c用宏定义,c+用inline8.软件测试都有那些种类?黑盒:针对系统功能的测试 白合:测试函数功能,各函数接口9.确定模块的功能和模块的接口是在软件设计的那个阶段完成的?概要设计阶段11.unsignedchar *p1; unsigned long *p2; p1=(unsigned char *)0x; p2=(unsigned long *)0x; 请问p
4、1+5=? ; p2+5=? ;答:p1+5=0x ; p2+5=0x ;1.请问下面程序有什么错误? int a602501000,i,j,k;for(k=0;k1000;k+)for(j=0;j250;j+)for(i=0;i60;i+) aijk=0;把循环语句内外换一下(编译的时候没错,运行的时候出错,但这个数组太大,如果放在栈中,还是会溢出,要作为全局变量)2.#defineMax_CB 500 void LmiQueryCSmd(Struct MSgCB * pmsg) unsigned char ucCmdNum; .for(ucCmdNum=0;ucCmdNum 4; whil
5、e (-i);return c;3、两个字符串,s,t;把t字符串接到s字符串尾,s字符串有足够的空间存放t字符串void connect(char *s, char *t, int i)char *q = t;char *p =s;if(q =NULL)return;while(*p!=0)p+;while(*q!=0)*p=*q;p+;q+;*p = 0;void main()charp7=ABC;charp2=EFG;connect(p,p2,3);printf(%s,p);4、分析下面的代码:char*a = hello;char*b = hello;if(a=b)printf(YES
6、);elseprintf(NO);常量字符串。位于静态存储区,它在程序生命期内恒定不变。如果编译器优化的话,会有可能a和b同时指向同一个hello的。则地址相同。如果编译器没有优化,那么就是两个不同的地址,则不同。对VC,是相同。5、局部变量能否和全局变量重名? 答:能,局部会屏蔽全局。要用全局变量,需要使用: ;局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。2、如何引用一个已经定义过的全局变量? 答:
7、extern 例如在某个.cpp中定义了一个全局变量int a,可在头文件中加入extern a;然后在需要引用的文件中包含该头文件。或者直接在文件中加入externa;3、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?答:可以在头文件中用static来定义同名全局变量。另外某个.C文件中定义的非静态全局变量,可以在其头文件中用extern声明,需引用此全局变量的其他.C只需包含此头文件即可。4、请写出下列代码的输出内容 #include intmain(void) int a,b,c,d;a=10; b=a+;c=+a; d=10*a+;printf(b,c,d:%d,%d,
8、%d,b,c,d); return 0; 答:10,12,1205、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?答: 1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文
9、件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。 2) 从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。3) static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件综上所述:static全局变量与普通的全局变量有什么区别:st
10、atic全局变量只初使化一次,防止在其他文件单元中被引用; static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值; static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝6、设有以下说明和定义: typedef unionlong i;int k5;/20char c; DATE;struct data int cat;/4 DATE cow; /20double dog;/8too; DATE max; 则语句 printf(%d,sizeof(struct data)+sizeof(ma
11、x);的执行结果是:考点:区别struct与union.(一般假定在32位机器上)答:DATE是一个union, 变量公用空间.里面最大的变量类型是int5, 占用20个字节. 所以它的大小是20. data是一个struct,每个变量分开占用空间. 依次为int4 + DATE20 +double8 = 32. 所以结果是 20 + 32 = 52.10、请找出下面代码中的所有错误 (题目不错,值得一看)说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba” #includestring.hmain() char*src=hello,world;char* dest=NULL
12、; int len=strlen(src); dest=(char*)malloc(len); char* d=dest; char* s=srclen; while(len-!=0) *d+=*s-; printf(%s,dest);return 0; 答: 方法1:一共有4个错误; int main()char* src = hello,world; int len = strlen(src); char* dest = (char*)malloc(len+1);/要为分配一个空间 char* d = dest;char* s = &srclen-1;/指向最后一个字符while( len
13、- != 0 ) *d+=*s-; *d = 0; /尾部要加0 printf(%sn,dest);free(dest); / 使用完,应当释放空间,以免造成内存汇泄露dest = NULL; /防止产生野指针return 0;方法2: (方法一需要额外的存储空间,效率不高.)不错的想法#include #include main()charstr=hello,world;intlen=strlen(str);char t;for(int i=0;ilen/2; i+)t=stri;stri=strlen-i-1;/小心一点strlen-i-1=t;printf(%s,str);return
14、0;3Heap与stack的差别。答:Heap是堆,stack是栈。Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。Stack空间有限,Heap是很大的自由存储区C中的malloc函数分配的内存空间即在堆上,C+中对应的是new操作符。程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行/ 1 2 4 8 16。/ 1 10 1001000 1 0000/ 0 1 11111 11113 一语句实现x是否为2的若干次幂的判断#define is2*n(x) (x & (x - 1)? 0 : 1)int main(void)i
15、nt m = 512;cout (m & (m - 1) ? false : true) endl;/即当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* const p;charconst * pconstchar *p解答:c
16、har * const p; /常量指针,p的值不可以修改char const * p;/指向常量的指针,指向的常量值不可以改const char *p; /和char const *p3. 解释下列输出结果charstr1 = abc;charstr2 = abc;constchar str3 = abc;constchar str4 = abc;constchar *str5 = abc;constchar *str6 = abc;char*str7 = abc;char*str8 = abc;cout ( str1 = str2 ) endl;cout ( str3 = str4 ) e
17、ndl;cout ( str5 = str6 ) endl;cout ( str7 = str8 ) endl;结果是:0 0 1 1解答:str1,str2,str3,str4是数组变量,它们有各自的内存空间;而str5,str6,str7,str8是指针,它们指向相同的常量区域。节省内存。4. 以下代码中的两个sizeof用法有问题吗?C易#include #include iostream.hvoid UpperCase( char str ) / 将 str 中的小写字母转换成大写字母 int i; for( i=0;isizeof(str)/sizeof(str0); +i )/是指
18、针的大小4,只循环了4次。数组做参数,会退化为指针。可改为strlen(str) if( a=stri& stri=z ) stri -=(a-A );/由小写转大写void main() char str =aBcDefg; cout str字符长度为: sizeof(str)/sizeof(str0) endl;/是数组的大小6 UpperCase( str ); cout str endl;答:函数内的sizeof有问题。根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。函数外的str是一个静态定义的数组,因此其大小为8,函数内的str实际只是一
19、个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为4个字节,因此返回4。 注意:数组名作为函数参数时,退化为指针. 数组名作为sizeof()参数时,数组名不退化,因为sizeof不是函数.4. 一个32位的机器,该机器的指针是多少位 232=4G地址总线宽度决定了CPU可以访问的物理地址空间.简单地说就是CPU到底 能够使用多大容量的内存.对于386以上的微机系统.地址线的宽度为32位.最多可以直接访问4096MB (4GB)的物理空间.对大多数人来说已经够用了.指针是多少位只要看地址总线的位数就行了。80386以后的机子都是32的数据总线
20、。所以指针的位数就是4个字节了。8位处理器、16位处理器、32位处理器和64位处理器,其计数都是8的倍数。它表示一个时钟周期里,处理器处理的二进制代码数。“0”和“1”就是二进制代码,线路上有电信号,则计做1,没有电信号则为0。8位机有8条线路,每个时钟周期有8个电信号,组成一个字节。所以,随8位处理器上升至64位处理器,每个时钟周期传送1个字节到8个字节,关联到时钟速度提高到若干个千兆赫之后,处理器处理信息的能力越来越大。CPU 的一次基本运算 (and, or, xor, not), 能处理/运算几个 bits. 64 bits data 交由 32-bit CPU 去运算, 得分两次才行
21、.5. 指出下面代码的输出,并解释为什么。(不错,对地址掌握的深入挖潜)main()int a5=1,2,3,4,5;int *ptr=(int *)(&a+1);/指针是数组类型,+1相当于加20.如果是(a+1)是+4printf(“%d %d”,a,ptr);printf(%d,%d,*(a+1),*(ptr-1);输出: 2,5a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a0的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a1,&a+1是下一个对象的地址,即a5.6.请问以下代码有什么问题:1).intmain()char a;char *str=&a;
22、strcpy(str,hello);printf(str);return 0;答;没有为str分配内存空间,将会发生异常问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。2).char*s=AAA;/常量的内容不能改,可定义为数组printf(%s,s);s0=B;printf(%s,s);有什么错?答: AAA是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。cosnt char* s=AAA;然后又因为是常量,所以对是s0的赋值操作是不合法的。7.用变量a给出下面的定义a)一个整型数(An integer)
23、b) 一个指向整型数的指针(A pointer to an integer) c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer toan integer) d) 一个有10个整型数的数组(An array of 10integers) e) 一个有10个指针的数组,该指针是指向一个整型数的(Anarray of 10 pointers to integers) f) 一个指向有10个整型数数组的指针(A pointerto an array of 10 integers) g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A
24、pointer to a functionthat takes an integer as an argument and returns an integer) h) 一个有10个函数指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argumentand return an integer )答案是:Int (*p10)(int);a) int a; / An integer b) int *a; / A pointer to an integer c
25、) int *a; / A pointer to a pointer to an integer d) int a10; / An array of 10 integers e) int*a10; / An array of 10 pointers to integers f) int (*a)10; / A pointer to an arrayof 10 integers g) int (*a)(int);/ A pointer to a function a that takes an integer argumentand returns an integer h) int (*a10
26、)(int); / An array of 10 pointers to functions that take aninteger argument and return an integer3.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL4.写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。#define MIN( A,B) (A)= (B) ?(A) : (B) A = B ?A : B5.关键字static的作用是什么?在C语言中,关键字stati
27、c有三个明显的作用:1). 在函数体,一个被声明为静态的全局变量在这一函数被调用过程中维持其值不变。 (值的保存)2). 在模块内(但在函数体外),一个被声明为静态的全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。(限制作用域)3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。 (限制作用域)6.关键字const是什么含意?下面的声明都是什么意思?1 const int a; 2 int const a; 3 const int *a; 4 int const * a;5 int
28、* const a; 6 int const * const a;1、const int a;2、int const a;3、 4、内容不可变,指针可变 : constint *a;5、内容不可变,指针可变 : int * const a;6、内容可变,指针不可变 : intconst * const a; 8. 关键字volatile有什么含意并给出三个不同的例子。一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volati
29、le变量的几个例子:1). 并行设备的硬件寄存器(如:状态寄存器)2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)3). 多线程应用中被几个任务共享的变量6.int (*s10)(int) 表示的是什么啊int (*s10)(int) 函数指针数组,每个指针指向一个int func(int param)的函数。1.有以下表达式:inta=248; b=4;int const c=21;const int *d=&a;int*const e=&b;int const int *const f =&a;请问下列表达式哪些会被编译器禁止?为什么?*c
30、=32;d=&b;*d=43;e=34;e=&a;f=0x321f;答:*c 这是个什么东东,禁止d=&b是很OKe=34不OKe = &a 说了是const 禁止 e的地址不能改const int *const f =&a; 禁止 f的内容和地址都不能改2.交换两个变量的值,不使用第三个变量。即a=3,b=5,交换之后a=5,b=3;答:有两种解法, 一种用算术算法, 一种用(异或)a = a + b;b = a - b;a = a - b;ora =ab;/ 只能对int,char.b = ab;a = ab;2个bit (bit1与bit2异或,结果为0说明它们不同,则bit2异或0可把
31、bit1还原。 结果为1说明它们相同,则bit2异或1可把bit1还原。4.#include#includevoidgetmemory(char *p) /函数的参数是局部变量,在这里给它分配内存还在,但是P释放了。p=(char *) malloc(100);intmain( )char *str=NULL;getmemory(str);strcpy(str,helloworld);printf(%s/n,str);free(str);return 0;答: 程序崩溃,getmemory中的malloc不能返回动态内存, free()对str操作很危险解决方案1:可改为按引用传递:void
32、getmemory(char *&p)解决方案2:返回指针Char* getmemory(char *p)p=(char *) malloc(100);return p;5.charszstr10;strcpy(szstr,);产生什么结果?为什么?答;正常输出,长度不一样,会造成非法的OS,覆盖别的内容.0没保存2.c指针int *pn;-指针数组,每个元素均为指向整型数据的指针。int (*p)n;-p为指向一维数组的指针,这个一维数组有n个整型数据。int *p();-函数带返回指针,指针指向返回的值。int (*p)();-p为指向函数的指针。3. 数组越界问题 (这个题目还是有点小险
33、的)下面这个程序执行后会有什么错误或者效果:#defineMAX 255intmain()unsignedchar AMAX,i;for (i=0;i=MAX;i+)Ai=i;解答:MAX=255,数组A的下标范围为:0.MAX-1,这是其一,其二 当i循环到255时,循环内执行: A255=255;这句本身没有问题,但是返回for (i=0;i=MAX;i+)语句时,由于unsignedchar的取值范围在(0.255),i+以后i又为0了.无限循环下去.注:char类型为一个字节,取值范围是-128,127,unsigned char 0 ,2554.C+:memset ,memcpy 和
34、strcpy 的根本区别?答:#include memory.hmemset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为 或;例:char a100;memset(a, , sizeof(a);memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:chara100,b50; memcpy(b, a, sizeof(b);注意如用sizeof(a),会造成b的内存地址溢出。strcpy就只能拷贝字符串了,它遇到0就结束拷贝;例:chara100,b50;strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一
35、个0之前)是否超过50位,如超过,则会造成b的内存地址溢出。void main() char a100; memset(a, a,sizeof(a)-1); memset(&a99,0,1); printf(%sn,a); charstr1100=abc; charstr250=efghdfkdjf; memcpy(str1,str2, sizeof(str2); printf(%sn,str1); strcpy(str1, str2); printf(%sn,str1);strcpy 原型:char *strcpy_su(char *dest,char *src) assert(dest!=
36、NULL)&(src!=NULL); char *address = dest; while(*dest+=*src+)!=0) continue; return address;用法:#include 功能:把src所指由NULL结束的字符串复制到dest所指的数组中。说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。memcpy原型:void *memcpy_su(void *dest, void *src, unsigned int count) assert(dest!=NULL)&(src!=NULL); char*b
37、dest = (char*)dest; char* bsrc =(char*) src; while(count-0) *bdest+ = *bsrc+; return dest;用法:#include 功能:由src所指内存区域复制count个字节到dest所指内存区域。说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。Memset原型:原型:extern void *memset(void *buffer, char c, int count);用法:#include功能:把buffer所指内存区域的前count个字节设置成字符c。说明:返回指向buffer的指针。v
38、oid *memset_su(void*buffer, int c, int count) assert (buffer!=NULL); char* buffer2 =(char*)buffer; while(count-0) *buffer2+ = c; return buffer;5.ASSERT()是干什么用的答:ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常用来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于
39、查找错误。例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:.ASSERT( n != 0);k = 10/ n;.ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。#include#includevoid main()intn=1;assert( n != 0); /c c+中使用/ASSERT( n != 0); /什么头文件?printf(sun);1. 编写用C语言实现的求n阶阶乘问题的递归算法:答:long int fact(int n)If(n=0|n=1) Return 1;ElseReturn n*fact(n-1);5. 冒泡排序:#include stdio.hvoid printArr(int R,int n) inti; for(i=0;in;i+) printf(%d,Ri); printf(n);void swap(int * a ,int * b) int c=*a; *a=*b; *b=c;/4 冒泡排序void maopaoSort(int R,int n) for(inti=0;in-1;i+) / 需要冒泡的次数 /* for(intj=0;jn
限制150内