面试笔试题整理v1320100409_第1页
面试笔试题整理v1320100409_第2页
面试笔试题整理v1320100409_第3页
面试笔试题整理v1320100409_第4页
面试笔试题整理v1320100409_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、l 基础篇1. 内存的分配方式的分配方式有几种?1). 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。2). 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。3). 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。2. 是不是一个父类写了一个virtual 函数

2、,子类覆盖它的函数不加virtual ,也能实现多态?virtual修饰符会被隐形继承的。private 也被集成,只事派生类没有访问权限而已。virtual可加可不加。子类的空间里有父类的所有变量(static除外)。同一个函数只存在一个实体(inline除外)。子类覆盖它的函数不加virtual ,也能实现多态。在子类的空间里,有父类的私有变量。私有变量不能直接访问。3. 引用与指针有什么区别?1) 引用必须被初始化,指针不必。2) 引用初始化以后不能被改变,指针可以改变所指的对象。3) 不存在指向空值的引用,但是存在指向空值的指针4. 请列出const修饰符在C/C+中的用途const

3、int *a; /a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)int * const a; /a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)int const * a const; /a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)5. 在C+ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”?C+语言支持函数重载,C语言不支持函数重载。函数被C+编译后在库中的名字与C语言的不同。假设某个函数的原型为: void foo(int x, int y); 该函数被C编

4、译器编译后在库中的名字为_foo,而C+编译器则会产生像_foo_int_int之类的名字。C+提供了C连接交换指定符号extern“C”来解决名字匹配问题。6. 以下三条输出语句分别输出什么?char str1       = "abc"char str2       = "abc"const char str3 = "abc" const char str4 = "abc" const cha

5、r* str5  = "abc"const char* str6  = "abc"cout << boolalpha << ( str1=str2 ) << endl; / 输出什么?cout << boolalpha << ( str3=str4 ) << endl; / 输出什么?cout << boolalpha << ( str5=str6 ) << endl; / 输出什么?7. 头文件中的 ifn

6、def/define/endif 干什么用?防止头文件被重复引用8. 写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。#define MIN(A,B) (A) <= (B) ?(A) : (B)没有括号不得分9. 在类的构造函数中是否可调用类的虚成员函数。可以调用,但是这时虚成员函数只能作为普通函数调用,失去了多态特性。但是绝对不要写出这样的代码;-没有这句话不得分10. 分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var)BOOL型变量:if(!var)int型变量: if(var=0)float型变量:const float

7、EPSINON = 0.00001;if (x >= - EPSINON) && (x <= EPSINON)指针变量:if(var=NULL)11. 第一个设置a的bit 3,第二个清除a 的bit 3SetBit(x,b)x|=(b)ClrBit(x,b)x&=(b)12. 某32位系统下, C+程序,请计算sizeof 的值(5分).char str = “char *p = str ;int n = 10;请计算sizeof (str ) = ?(1)sizeof ( p ) = ?(2)sizeof ( n ) = ?(3)void Foo ( c

8、har str100)请计算sizeof( str ) = ?(4)void *p = malloc( 100 );请计算sizeof ( p ) = ?(5)答:(1)17 (2)4 (3) 4 (4)4 (5)413. 2整数互换,判断是否有错?Void swap( int* p1,int* p2 )int*p;*p = *p1;*p1 = *p2;*p2 = *p;在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC+中DEBUG运行时提示错误“AccessViolation”。该程序应该改为:Void swap( int* p1, int* p2 )int

9、 p;p = *p1;*p1 = *p2;*p2 = p;14. include<file.h> 与 include "file.h"的区别?前者是从Standard Library的路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h15. 结构与联合有和区别?1. 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。 2. 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成

10、员赋值是互不影响的。16. 类的静态函数的使用静态成员函数属于类的静态成员,它不是对象成员。因此,对静态成员的引用不需要用对象名。  在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员。如果静态成员函数中要引用非静态成员时,可通过对象来引用。17. 线程的入口函数可以是一个类的普通成员函数吗?不能,必须是类的静态成员函数。18. 类的静态成员变量可以在类的声明中被初始化吗? 不行。必须在类的外部被初始化。格式如下:int RefMap:m_counter = 0;19. 给定一个类A,需要实现两个类A对象的相加,请给出加号操作符的重载成员函数的原型A

11、operator+(const A& a, const A& b)20. 如何打印出当前源文件的文件名以及源文件的当前行号?_FILE_和_LINE_是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。21. 以下代码执行后,val的值是_: unsigned long val = 0; char a = 0x48; char b = 0x52; val = b << 8 | a; A 20992 B 21064 C 72 D 022. 下面代码输出什么?#include <iostream>using namespace std;cha

12、r* copy(char arr);void main()    char arr10 = "123456789"    char* dest = copy(arr);    cout<<dest<<endl;char* copy(char arr)    int arrSize = sizeof(arr);    char* pt = (char*)malloc(arrSize); 

13、0;  memset(pt,0,arrSize);    strcpy(pt,arr);    return pt;23. 微机中1K字节表示的二进制位数是()1. 10002. 8x10003. 10244. 8x102424. 下面这段代码能通过C/C+编译吗?为什么?void fun(const int val)    switch(val)        case 1:     

14、  int ret = val*2;       break;    case 2:       break;    l 进阶篇1. 简要说说C+标准库的map和hash_map容器的原理及区别,什么时候适合使用它们在C+的STL中map是使用树(红黑树)来做查找算法,这种算法差不多相当与list线性容器的折半查找的效率一样,都是O (log2N).相比hash_map,hash_map使用hash表来排列

15、配对,hash表是使用关键字来计算表位置。当这个表的大小合适,并且计算算法合适的情况下,hash表的算法复杂度为O(1)的,但是这是理想的情况下的,如果hash表的关键字计算与表位置存在冲突,那么最坏的复杂度为O(n)。选用map还是hash_map,关键是看关键字查询操作次数,以及你所需要保证的是查询总体时间还是单个查询的时间。如果是要很多次操作,要求其整体效率,那么使用hash_map,平均处理时间短。如果是少数次的操作,使用 hash_map可能造成不确定的O(N),那么使用平均处理时间相对较慢、单次处理时间恒定的map,考虑整体稳定性应该要高于整体效率,因为前提在操作次数较少。如果在一

16、次流程中,使用hash_map的少数操作产生一个最坏情况O(N),那么hash_map的优势也因此丧尽了2. 已知strcpy函数的原型是 char *strcpy(char *strDest, const char *strSrc);其中strDest是目的字符串,strSrc是源字符串。不调用C+/C的字符串库函数,请编写函数 strcpy, ( 隐含 ):为何返回char*char *strcpy(char *strDest, const char *strSrc); assert(strDest!=NULL) && (strSrc !=NULL); / 2分 char

17、*address = strDest; / 2分 while( (*strDest+ = * strSrc+) != 0 ) / 2分 NULL ; return address ; / 2分返回char* 是为了链式操作3. 有关内存的思考题void GetMemory(char *p)p = (char *)malloc(100);void Test(void) char *str = NULL;GetMemory(str);   strcpy(str, "hello world");printf(str); 请问运行Test函数会有什么样

18、的结果?程序崩溃。因为GetMemory并不能传递动态内存,Test函数中的 str一直都是 NULL。strcpy(str, "hello world");将使程序崩溃。 char *GetMemory(void)   char p = "hello world"return p;void Test(void)char *str = NULL;str = GetMemory();    printf(str); 请问运行Test函数会有什么样的结果?可能是乱码。因为GetMemory

19、返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。void GetMemory2(char *p, int num)*p = (char *)malloc(num);void Test(void)char *str = NULL;GetMemory(&str, 100);strcpy(str, "hello");   printf(str);    请问运行Test函数会有什么样的结果?答:(1)能够输出hello(2)内存泄漏  void Test

20、(void)char *str = (char *) malloc(100);    strcpy(str, “hello”);    free(str);          if(str != NULL)          strcpy(str, “world”); printf(str);请问运行Test函数会有什么样的结果?答:篡改动态内存区的内容,后果难以预料,非常危险。因为free(st

21、r);之后,str成为野指针,if(str != NULL)语句不起作用。  4. 用变量a给出下面的定义    a) 一个整型数(An integer)    b) 一个指向整型数的指针(A pointer to an integer)    c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer)    d) 一个有10个整型数的数组(An array of 10 intege

22、rs)    e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)    f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)    g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)

23、60;   h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )    答案是:    a) int a; / An integer    b) int *a; / A pointer to an integer    c) int *a;

24、 / 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 array of 10 integers    g) int (*a)(int); / A pointer to a function a

25、 that takes an integer argument and returns an integer    h) int (*a10)(int); / An array of 10 pointers to functions that take an integer argument and return an integer5. 关键字volatile有什么含意1)并行设备的硬件寄存器(如:状态寄存器) 2)一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3)多线程应用中被几个任务共享的变量6. 下面的函数有什

26、么错误:int square(volatile int *ptr)        return *ptr * *ptr;这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面 的代码:    int square(volatile int *ptr)        int a,b;    a = *ptr;    b = *

27、ptr;    return a * b;    由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:long square(volatile int *ptr)        int a;    a = *ptr;    return a * a;    7. 下面的代码输出是什么,为什么?  &#

28、160; void foo(void)        unsigned int a = 6;    int b = -20;    (a+b > 6) puts("> 6") : puts("<= 6");    这个问题测试你是否懂得C语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。不管如何,这无符号整型问题的答案是输出是“>6”。原因 是当表达式中存在有符号类型和无符

29、号类型时所有的操作数都自动转换为无符号类型。 因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6.这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。8. #define 和 typedef的差别#define dPS struct s *    typedef struct s * tPS;    以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么?    这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应

30、当被恭喜的。答案是:typedef更好。思考下面的例子:    dPS p1,p2;    tPS p3,p4;    第一个扩展为    struct s * p1, p2;    上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。#define 可以被重定义9. 写出判断ABCD四个 表达式的是否正确, 若正确, 写出经过表达式中 a的值int a = 4;(A)a

31、+= (a+); (B) a += (+a) ;(C) (a+) += a;(D) (+a) += (a+);a = ?答:C错误,左侧不是一个有效变量, 不能赋值,可改为(+a) += a;改后答案依次为9,10,10,1110. 程序什么时候应该使用线程,什么时候单线程效率高。1耗时的操作使用线程,提高应用程序响应2 并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。3多CPU系统中,使用线程提高CPU利用率4改善程序结构。 一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。其他情况都使用单线程。11. 函数模板与类模板有

32、什么区别?函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地 指定。12. 已知String类定义如下:class Stringpublic:String(const char *str = NULL); / 通用构造函数String(const String &another); / 拷贝构造函数 String(); / 析构函数String & operater =(const String &rhs); / 赋值函数private:char *m_data; / 用于保存字符串;尝试写出类的成员函数实现。答案:Str

33、ing:String(const char *str)   if ( str = NULL ) /strlen在参数为NULL时会抛异常才会有这步判断            m_data = new char1 ;       m_data0 = '0' ;        else  

34、;         m_data = new charstrlen(str) + 1;       strcpy(m_data,str);     String:String(const String &another)    m_data = new charstrlen(another.m_data) + 1;    strcpy(m_

35、data,other.m_data);String& String:operator =(const String &rhs)    if ( this = &rhs)        return *this ;    delete m_data; /删除原来的数据,新开一块内存    m_data = new charstrlen(rhs.m_data) + 1;  &#

36、160; strcpy(m_data,rhs.m_data);    return *this ;String:String()    delete m_data ;13. 单向链表反转单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题。比如一个链表是这样的: 1->2->3->4->5 通过反转后成为5->4->3->2->1。最容易想到的方法遍历一遍链表,利用一个辅助指针,存储遍历过程中当前指针指向的下一个元素,然后将当前节点元素的指针反转后,利用已经存储的

37、指针往后面继续遍历。源代码如下:struct linka int data;linka* next;void reverse(linka*& head) if(head =NULL)return;linka *pre, *cur, *ne;pre=head;cur=head->next;while(cur)ne = cur->next;cur->next = pre;pre = cur;cur = ne;head->next = NULL;head = pre;还有一种利用递归的方法。这种方法的基本思想是在反转当前节点之前先调用递归函数反转后续节点。源代码如下。

38、不过这个方法有一个缺点,就是在反转后的最后一个结点会形成一个环,所以必须将函数的返回的节点的next域置为NULL。因为要改变head指针,所以我用了引用。算法的源代码如下:linka* reverse(linka* p,linka*& head)if(p = NULL | p->next = NULL)head=p;return p;elselinka* tmp = reverse(p->next,head);tmp->next = p;   return p; 14. C+是不是类型安全的?不是。两个不同类型的指针之间可以强制转换(用reint

39、erpret cast)。C#是类型安全的。15. 以下代码有什么问题? cout << (true?1:"1") << endl;16. 以下代码能够编译通过吗,为什么?unsigned int const size1 = 2;char str1 size1 ;unsigned int temp = 0;cin >> temp;unsigned int const size2 = temp;char str2 size2 ;17. 以下反向遍历array数组的方法有什么错误? vector array;array.push_back(

40、1 );array.push_back( 2 );array.push_back( 3 );for( vector:size_type i=array.size()-1; i>=0; -i) / 反向遍历array数组    cout << arrayi << endl;错误:1 少了<int> 2 size_type为unsigned int,所以死循环了。18. 以下代码有什么问题? typedef vector IntArray;IntArray array;array.push_back( 1 );arr

41、ay.push_back( 2 );array.push_back( 2 );array.push_back( 3 );/ 删除array数组中所有的2for( IntArray:iterator itor=array.begin(); itor!=array.end(); +itor )if( 2 = *itor ) array.erase( itor );19. 请简述以下两个for循环的优缺点/ 第一个for (i=0; i+;)if (condition)DoSomething();elseDoOtherthing();/ 第二个if (condition)for (i=0; i+;)

42、DoSomething();elsefor (i=0; i+;)DoOtherthing();20. 重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?常考的题目。从定义上来说:重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。重写:是指子类重新定义复类虚函数的方法。从实现原理上来说:重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和functio

43、n func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!重写:和多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)。21. 写一个函数返回1+2+3+n的值(假定结果不会超过长整型变量的范围)  int su

44、m( int n ) return ( (long)1 + n) * n / 2;/或return (1l + n) * n / 2; 22. 判断语句写法private static void method1()         long start = GetTickCount();        int result = 0;        for (int i = 0; i &l

45、t; 100; i+)             int number = i * 10;            int value = count(number);            for (int j = 0; j < 10; j+)  

46、0;              result += value;                if (j = 1)                  

47、;   result+;                                int x = number + j;             

48、;   if (result = x && x != 0)                     print(x, start);                     

49、               private static void method2()         long start = GetTickCount();        int result = 0;        for (int i = 0; i

50、< 100; i+)             int number = i * 10;            int value = count(number);            for (int j = 0; j < 10; j+)  &#

51、160;              result += value;                if (j = 1)                     result+;          &#

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论