C语言面试题(经典全).docx
1. static有什么用途?(请至少说明两种)1)限制变量的作用域2)设置变量的存储域(堆,主动支配内存也是堆)1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内 所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。3)在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调 用。那就是,这个函数被限制在声明它的模块的本地范围内运用。4,全局变量和局部变量在内存中是否有区分?假如有,是什么区分?全局变量储存在静态数据库,局部变量在栈6.堆栈溢出一般是由什么缘由导致的?堆栈溢出一般是循环的递归调用导致的,假如运用的大数据结构的局部变量, 也可能导致堆栈溢出。 没有回收垃圾资源导致的是内存泄露最终内存耗尽。20.不能做switch。的参数类型是:switch的参数不能为实型。(只能是int char)9.写出float x与“零值”比较的if语句。 too;DATE max;则语句 printf (/,%d/, sizeof (struct data句sizeof (max);的执行结果是:考点:区分struct与union.(一般假定在32位机器上)答:DATE是一个union,变量公用空间.里面最大的变量类型是int5,占用20 个字节.所以它的大小是20. data是一个struct,每个变量分开占用空间.依次 为int4 + DATE20 +double8 = 32.所以结果是 20 + 32 = 52.10、请找出下面代码中的全部错误(题目不错,值得一看)说明:以下代码是把一个字符串倒序,如“abed”倒序后变为“deba”#includez/string. hmain ()char*src=/hello, world”;char* dest=NULL;int len=strlen(sre);dest=(char*)malloc(len);char* d=dest;char* s=srclen;while(len-!=0)*d+=*s;printf (/z%sz/, dest);答:方法1: 一共有4个错误;int main ()(char* src = "hello, world”;int len = strlen (src);char* dest =(char*)manoc (len+1);要为支配一个空间char* d = dest;char* s = &srclen-l;指向最终一个字符while( len- != 0 )*d+=*s;*d = 0;尾部要加'0'printf(sn,dest);free(dest);运用完,应当释放空间,以免造成内存汇泄露dest = NULL;防止产生野指针return 0;)方法2:(方法一须要额外的存储空间,效率不高.)不错的想法ftinclude <stdio. h>ftinclude <string.h>main ()(charstr =/zhello, world”;intlen=strlen (str);char t;for(int i=0;i<len/2; i+)t=stri;stri=strlen-i-l ;/当心一点str len-i-l=t;printf(%s,str);return 0;3. Heap与stack的差别。答:Heap是堆,stack是栈。Stack的空间由操作系统自动支配/释放,Heap上的空间手动支配/释放。Stack空间有限,Heap是很大的自由存储区C中的malloc函数支配的内存空间即在堆上,C+中对应的是new操作符。程序在编译期对变量和函数支配内存都在栈上进行,且程序运行过程中函数调用 时参数的传递也在栈上进行/ 124 8 16ooo/ 11010010001 0000/ o 111 in mi3 一语句实现x是否为2的若干次幕的推断#def ine is2*n(x) (x & (x - 1)? 0 : 1) int main (void) int m 二 512; cout << (m & (m - 1) ? false : true) << endl;/即当m中只有一位为1时丁才为若干次嘉值考试大提示:若有两个及以上L则(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解答:char * const p; 常量指针,p的值不行以修改char const * p; 指向常量的指针,指向的常量值不行以改const char *p; /和char const *p3 .说明下列输出结果charstrl = abc;charstr2 = abc;constcharstr3 = abc;constcharstr4 = abc;constchar*str5 = abc;constchar*str6 = abc;char*str7 = abc;char*str8 = abc;cout<< ( strl = str2endl;cout<< ( str3 = str4endl;cout<< ( str5 = str6endl;cout<< ( str7 = str8endl;结果是:0 0 11解答:strl, str2, str3, str4是数组变量,它们有各自的内存空间;而str5, str6, str7, str8是指针,它们指向相同的常量区域。节约内存。4 .以下代码中的两个sizeof用法有问题吗? C易ftinclude <stdio. h>ftinclude "iostream. h void Uppercase ( char str ) /将str中的小写字母转换成大写字母 int i;for ( i=0; i<sizeof (str)/sizeof (str0) ; +i )是指针的大 小4,只循环了4次。数组做参数,会退化为指针。可改为strlen(str)if ( ' a'二str i&& str i <=,)stri -=('a''A');由小写 转大写void main()char str 二aBcDefg”;cout << str字符长度为: <<sizeof (str)/sizeof (str 0) << endl; /是数组的大小6Uppercase( str );cout << str <<endl;答:函数内的sizeof有问题。依据语法,sizeof如用于数组,只能测出静态数组 的大小,无法检测动态支配的或外部数组大小。函数外的str是一个静态定义的 数组,因此其大小为8,函数内的str实际只是一个指向字符串的指针,没有任何 额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为4 个字节,因此返回4。留意:数组名作为函数参数时,退化为指针.数组名作为sizeof ()参数时, 数组名不退化,因为sizeof不是函 数.4 . 一个32位的机器,该机器的指针是多少位 2132 =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. 64 bits data交由32-bit CPU去运算,得分两次才行.5 .指出下面代码的输出,并说明为什么。(不错,对地址驾驭的深化挖潜)main ()int a5 = l, 2, 3, 4, 5;int *ptr=(int *) (&a+l);指针是数组类型,+1相当于加20.假如是(a+1)是+4printf( a%d %dv, a, ptr);printf Cz%d, %d,*(a+l), *(ptrT);输出:1245036 1245056 2,5a, &a的地址是一样的,但意思不一样,a是数组首地址,也就是a0的地址,&a 是对象(数组)首地址,a+1是数组下一元素的地址,即al,&a+l是下一个对象 的地址,即a5.6 .请问以下代码有什么问题:1) .intmain ()char a;char *str=&a;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) b) 一个指向整型数的指针(A pointer to an integer) c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer toan integer) d) 一个有10个整型数的数组(An array of lOintegers) e) 一个有10个指针的数组,该指针是指向一个整型数的(Anarray of 10 pointers to integers) f) 一个指向有10个整型数数组的指 针(A pointerto an array of 10 integers) g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A 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) int *a; / A pointer to a pointer to an integer d) int a10; / An array of 10 integers e) inta10 ; / 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)(int) ; / An array of 10 pointers to functions that take aninteger argument and return an integer3 .用预处理指声明一个常数,用以表明1年中有多少秒(忽视闰年问 题)define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL4 .写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。ftdefine MIN( A, B) (A) <= (B) ? (A) : (B) A <= B ? A : B5 .关键字static的作用是什么?在C语言中,关键字static有三个明显的作用:1) .在函数体,一个被声明为静态的全局变量在这一函数被调用过程中维持其值 不变。(值的保存)2) .在模块内(但在函数体外),一个被声明为静态的全局变量可以被模块内所 用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。(限制 作用域)3) .在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那 就是,这个函数被限制在声明它的模块的本地范围内运用。(限制作用域)6.关键字const是什么含意?下面的声明都是什么意思?1 const int a; 2 int const a; 3 const int *a; 4 int const * a;5 int * 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的变量是说这变量可能会被意想不到地变更,这样,编译器 就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必需每次都当心地重新读取这个变量的 值,而不是运用保存在寄存器里的备份。下面是volatile变量的几个例子:1) .并行设备的硬件寄存器(如:状态寄存器)2) . 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)3) .多线程应用中被几个任务共享的变量3.在c语言库函数中将一个字符转换成整型的函数是atol ()吗,这个函数的原型 是什么?函数名:atol功能:把字符串转换成长整型数函数的原型:long atol (const char *nptr);程序例:ftinclude <stdlib.h>ftinclude <stdio.h>int main (void)(long 1;char *str = "98765432”;1 = atol(Istr);printf("string = %s integer =str, 1);return (0);1.对于一个频繁运用的短小函数,在C语言中应用什么实现,在C+中应用什么实 现?c用宏定义,c十1用inline6. 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 constint *const f =&a;请问下列表达式哪些会被编译器禁止?为什么?*c=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;答:有两种解法,一种用算术算法,一种用X异或)a = a + b;b = a - b;a = a - b;ora =ab;/ 只能对int, char.b = a b;a = a b;2个bit (1)江1与13比2异或,结果为0说明它们不同,则bit2异或0可把bit 1还原。结果为1说明它们相同,则 1)近2异或1可把131.1;1还原。4. #include<stdio. h>#include<stdlib. h>voidgetmemory (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 getmemory(char *&p)解决方案2:返回指针Char* getmemory(char *p)(p=(char *) malloc(100);return p;5. charszstr10;strcpy(szstr, ”0123456789);产生什么结果?为什么?答;正常输此长度不一样,会造成非法的os,覆盖别的内容.,(r没保存2. c指针int *pn;指针数组,每个元素均为指向整型数据的指针。int (*p) n;p为指向一维数组的指针,这个一维数组有n个整型数据。int *p();函数带返回指针,指针指向返回的值。int (*p) () ;p为指向函数的指针。3. 数组越界问题(这个题目还是有点小险的) 下面这个程序执行后会有什么错误或者效果: ftdefineMAX 255intmainOunsignedchar 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类型为一个字节,取值范围是型为8, 127, unsigned char 0 , 2554. C+:memset , memcpy 和strcpy 的根本区分?答:#include "memory. hmemset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行 初始化为'或'';例:char a100;memset (a, J,, sizeof (a);memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的 数据长度;例:chara100, b50 ; memcpy (b, a, sizeof (b);留意如用 sizeof (a),会造成b的内存地址溢出。strcpy就只能拷贝字符串了,它遇到0'就结束拷贝;例: chara 100, b50 ; strcpy (a, b);如用 strcpy (b, a),要留意a中的字符串长度(第 一个''0'之前)是否超过50位,如超过,则会造成b的内存地址溢出。void main ()char a100;memset (a, ' a', sizeof (a) -1);memset(&a99,J0",1);printf (z,%sn/z, a);charstrl100=abc;charstr2 50=,efghdfkdjfz/;memcpy(strl,str2, sizeof(str2);printf(sn,strl);strcpy(strl, str2);printf(sn,strl);strcpy 原型:char *strcpy_su(char *dest, char *src)assert (dest!=NULL)&&(src!=NULL);char "address = dest;while(*dest+=*src+) !=' 0')continue;return address;)用法:ftinclude <string. h>功能:把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*bdest = (char*)dest;char* bsrc =(char*) src;while(count->0)*bdest+ = *bsrc+;return dest;用法:ttincludememory, h功能:由src所指内存区域复制count个字节到dest所指内存区域。说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。Memset 原型:原型:extern void *memset (void *buffer, char c, int count);用法:ttinclude 功能:把buffer所指内存区域的前count个字节设置成字符c。说明:返回指向buffer的指针。void *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),程序将报告错误,并终止执行。假如表达式不 为3则接着执行后面的语句。这个宏通常用来推断程序中是否出现了明显非法 的数据,假如出现了终止程序以免导致严峻后果,同时也便于查找错误。例如, 变量n在程序中不应当为3假如为0可能导致错误,你可以这样写程序:ASSERT( n != 0);k = 10/ n;ASSERT只有在Debug版本中才有效,假如编译为Release版本则被忽视。assert。的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区 分是可以用在Release版本中。#include<stdio. h>#include<assert. h> void mainOintn=l;assert ( n != 0) ;/c c+中运用/ASSERT ( n != 0); 什么头文件?printf("sun");)1.编写用C语言实现的求n阶阶乘问题的递归算法:答:long int fact (int n)(If(n=0|n=l)Return 1;ElseReturn n*fact(n-l);5.冒泡排序:include "stdio.hvoid printArr(int R, int n)inti;for(i=0;i<n;i+)printf (d ", Ri);void swap(int * a , int * b)int c=*a;*a=*b;*b=c;/4冒泡排序 void maopaoSort (int R , int n)for (inti=0; i<n-l; i+)/ 须要冒泡的次数for (intj=0;j<n-li;j+)/ /每次须要比较的次数/大的往下沉swap(&Rj, &Rj+U);for(intj=n-l; j>i; j-)/ /每次须要比较的次数if(Rj<Rj-l)j-H);)小的往上冒swap(&Rj, &Rvoid main ()(int i;intnum6=0;printf (/zPleaseinput 6 numbers: n/z);for(i=0;i<6;i+)scanf (zz%dz/, &numi);puts ("beforesort:);printArr(num, 6);maopaoSort(num, 6);puts ("aftersort:);printArr(num,6);8 .软件测试都有那些种类?黑盒:针对系统功能的测试 白合:测试函数功能,各函数接口9 .确定模块的功能和模块的接口是在软件设计的那个阶段完成的?概要设计阶段11. unsignedchar *pl;unsigned long *p2;pl=(unsigned char *)0x801000;p2=(unsigned long *)0x810000;请问 pl+5=?;p2+5二?;答:pl+5=0x801005;p2+5=0x810014L请问下面程序有什么错误?int a60 250 1000, i, j, k;for(k=0;k<1000;k+)for(j=0;j<250;j+)for (i=0;i<60;i+)ai j k>0;试题8:再看看下面的一段程序有什么错误:swap(int* pl, int* p2 )int *p;* p = *pl;* pl = *p2;* p2 二 *p;在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩 溃。在VC+中DEBUG运行时提示错误"Access Violation该程序应当改为:swap( int* pl, int* p2 )(int p;p 二 *pl;* pl = *p2;* p2 = p;试题L分别给出BOOL, int, float,指针变量 与“零值”比较的if语句(假 设变量名为var)解答:BOOL型变量:if(!var)int 型变量:if (var-0)float型变量:const float EPSINON = 0.00001;if (x >= - EPSINON) && (x <= EPSINON)指针变量: if (NULL = var)试题2:以下为Windows NT下的32位C+程序,请计算sizeof的值voidFunc ( char str100)sizeof ( str ) = ?void*p = malloc ( 100 );sizeof ( p ) = ?解答:sizeof ( str )二 4sizeof ( p )= 4剖析:Func ( char str100)函数中数组名作为函数形参时,在函数体内,数组 名失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。数组名的本质如下:(1)数组名指代一种数据结构,这种数据结构就是数组;例如:char str 10;cout << sizeof (str) << endl;输出结果为10, str指代数据结构char 10。(2)数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不 能作自增、自减等操作,不能被修改;char str10;str+; 编译出错,提示str不是左值(3)数组名作为函数形参时,沦为一般指针。Windows NT 32位平台下,指针的长度(占用内存的大小)为4字节,故 sizeof ( str )、sizeof ( p )者B为4。3:写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。另外,当你 写下面的代码时会发生什么事?least= MIN(*p+, b);解答:define MIN (A, B) (A)二(B) ? (A) : (B)MIN(*p+, b)会产生宏的副作用剖析:(1)谨慎地将宏定义中的“参数”和整个宏用用括弧括起来。所以,严格 地讲,下述解答:define MIN (A, B) (A)<二(B) ? (A) : (B)define MIN (A, B) (A <= B ? A : B )ftdefine MIN(A,B) (A) <= (B) ? (A) : (B);都应判0分;(2)防止宏的副作用。宏定义#define MIN(A,B) (A) <= (B) ? (A) : (B)对MIN(*p+, b)的作 用结果是:(*p+) <= (b) ? (*p+) : (b)这个表达式会产生副作用,指针P会作2次+自增操作。” dfjdosfjkodskf “dos” 100034.请编写能干脆实现strstr ()函数功能的代码。 strstr (str, substr);在 str中找substr,找到后把后面的全部截取返回。include <iostream> using std:cout;using std:endl;char* my_strstr( char* strl, char* str2 ) if (NULL = strl | NULL = str2) throw;char *p = NULL;char *q = NULL;const char v ='0' ; for (int i=0; v != strl i; +i)p = &strli;q = str2;while (v != *q && *q = *p)+p;+q;if ('0' = *q)return &strli; return NULL; int main( void )char a= ok2023;char* p = my_strstr( a, "com" ) ;if (NULL = p)cout << "not find” << endl;else cout << p << endl; p = my_strstr ( a, 2023 );if (NULL =二 p) cout << z/not find” << endl; else cout << p << endl;8.写一个函数,检查字符是否是整数,假如是,返回其整数值。(或者:怎样只 用4行代码,编写出一个从字符串到长整形的函数?)析:扫描一遍,每次生成对应整数的最高位。一行也就搞定了!1234” -a 1*1000+2*100+3*10+4'0' - 9'“1234” 1234long convert (char* s_string) longs_integer=0;for (int sLen= strlen (s_string), i = 0; i < sLen;s_integer += (s_stringi+ -' O')*pow(10, sLen - i - 1);returns_integer;)12 21 23 34 152o对1, 2, 3, 4, 5这五个数随意取出两个数,列出他们的全部组合。void main()(char =for(int i=0;i<5-l;i+)for(intj=i+l;j<5;j+)if (ai!=aj)cout<<ai<<aj«z/cout<<aj<<ai«/z;cout<<endl;)/12 21 13 31 14 41 15 51/23 32 24 42 25 52/34 43 35 53/45 541) .用预处理指令#10门血声明一个常数,用以表明1年中有多少秒(忽视闰年问 题)ttdefine SECONDS_PER_YEAR (60 * 60 * 24 *365)UL1) define语法的基本学问(例如:不能以分号结束,括号的运用,等等)2)懂得预处理器将为你计算常数表达式的值,因此,干脆写出你是怎么样计 算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。3)意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符 号L,告知编译器这个常数是的长整型数。4)假如你在你的表达式中用到UL(表示无符号长整型),那么你有了