c++面试题汇总资料

上传人:E**** 文档编号:102048660 上传时间:2019-10-01 格式:DOC 页数:12 大小:55.34KB
返回 下载 相关 举报
c++面试题汇总资料_第1页
第1页 / 共12页
c++面试题汇总资料_第2页
第2页 / 共12页
c++面试题汇总资料_第3页
第3页 / 共12页
c++面试题汇总资料_第4页
第4页 / 共12页
c++面试题汇总资料_第5页
第5页 / 共12页
点击查看更多>>
资源描述

《c++面试题汇总资料》由会员分享,可在线阅读,更多相关《c++面试题汇总资料(12页珍藏版)》请在金锄头文库上搜索。

1、C+知识点整理 空指针与野指针的区别:空指针也就是通常指向为NULL的指针,野指针就是指向一块未知的内存区域(可以是通过malloc或new申请空间后,释放后没有将指针置为空),也有可能定义了一个指针没有初始化,由于内存空间中的值在未赋值之前是随机数,所以也有可能诞生野指针。 malloc函数为C语言中的标准函数,标准中规定:在分配内存失败时会返回“NULL Pointer”空指针,而非为初始化的指针。 C+在分配内存失败时会抛出BAD_ALLOC异常。 野指针:指向垃圾内存的指针,而非空指针。 野指针产生原因: 1.声明的指针未被初始化,指针默认值随机产生。创建指针应该将其初始化为NULL或

2、者指向某一内存。 2.free和delete掉的指针未重置为NULL,free后的指针仍指向该内存,但该内存已变为垃圾内存。 另:空指针不指向任何实际的对象或函数,反过来说对象或函数的指针也不可能为空指针。,auto是默认类型,每次调用sum函数时auto类型的变量重新赋值为0,static是静态变量,如果在函数内部进行定义,则只在第一次调用时进行赋初值,其作用范围是sum函数内部,在函数内部可以改静态变量的值;先说宏和函数的区别: 1. 宏做的是简单的字符串替换(注意是字符串的替换,不是其他类型参数的替换),而函数的参数的传递,参数是有数据类型的,可以是各种各样的类型. 2. 宏的参数替换是

3、不经计算而直接处理的,而函数调用是将实参的值传递给形参,既然说是值,自然是计算得来的. 3. 宏在编译之前进行,即先用宏体替换宏名,然后再编译的,而函数显然是编译之后,在执行时,才调用的.因此,宏占用的是编译的时间,而函数占用的是执行时的时间. 4. 宏的参数是不占内存空间的,因为只是做字符串的替换,而函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的. 5. 函数的调用是需要付出一定的时空开销的,因为系统在调用函数时,要保留现场,然后转入被调用函数去执行,调用完,再返回主调函数,此时再恢复现场,这些操作,显然在宏中是没有的. 内联函数与宏的区别: 1.内

4、联函数在运行时可调试,而宏定义不可以;2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会;3.内联函数可以访问类的成员变量,宏定义则不能;4.在类中声明同时定义的成员函数,自动转化为内联函数。external 作用之一: 当它与 “C” 一起连用时,如:extern “C” void fun(int a , int b);会告诉C+编译器在编译fun这个函数名是按着C的规则去翻译相应的函数名而不是C+的,C+的规则在翻译这个函数名时会把fun这个名字变得面目全非。回调函数就是一个通过函数指针调用的函数。 如果你把函数的指针(地址)作为参数传递给另一个函数,当

5、这个指针被用来调用其所指向的函数时,我们就说这是回调函数。 回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应回调函数不能是特定的类成员函数。因为类成员函数含有this指针。核心就是类成员函数需要this指针访问函数,而全局或者静态函数不需要this指针。 简言之,类的成员函数需要隐含的this指针而回调函数没有办法提供。 int *a34, 则变量占有的内存空间为每个元素存放的都是二级指针,每个指针在32位系统下占4个字节的内存,共3*4=12个元素,则共占内存12*4=48字节C+中使用模板类的原因: (1) 可用来创建动态增

6、长和减小的数据结构; (2) 它是类型无关的,因此具有很高的可利用性; (3) 它在编译时检查数据类型,保证了类型安全; (4) 它是平台无关的,具有可移植性; (5) 可用于基本数据类型。 A. 由于编译后的名字不同,C+程序不能直接调用C 函数B. extern C 既可以修饰函数也可以修饰变量C. c+提供关键字extern“C”,被extern C修饰的是按照C语言方式编译和连接的它是if not define 的简写,是宏定义的一种,实际上确切的说,这应该是预处理功能三种(宏定义、文件包含、条件编译)中的一种-条件编译。 在c语言中,对同一个变量或者函数进行多次声明是不会报错的。所以

7、如果h文件里只是进行了声明工作,即使不使用# ifndef宏定义,多个c文件包含同一个h文件也不会报错。 但是在c+语言中,#ifdef的作用域只是在单个文件中。所以如果h文件里定义了全局变量,即使采用#ifdef宏定义,多个c文件包含同一个h文件还是会出现全局变量重定义的错误。 使用#ifndef可以避免下面这种错误:如果在h文件中定义了全局变量,一个c文件包含同一个h文件多次,如果不加#ifndef宏定义,会出现变量重复定义的错误;如果加了#ifndef,则不会出现这种错误。 根据语言定义, 在指针上下文中的常数0 会在编译时转换为空指针。也就是说, 在初始化、赋值或比较的时候,如果一边是

8、指针类型的值或表达式, 编译器可以确定另一边的常数0 为空指针并生成正确的空指针值。因此下边的代码段完全合法:char *p = 0;if(p != 0) 然而, 传入函数的参数不一定被当作指针环境, 因而编译器可能不能识别未加修饰的0 “表示” 指针。在函数调用的上下文中生成空指针需要明确的类型转换,强制把0 看作指针。例如, Unix 系统调用execl 接受变长的以空指针结束的字符指针参数。它应该如下正确调用:execl(/bin/sh, sh, -c, date, (char *)0);如果省略最后一个参数的(char *) 转换, 则编译器无从知道这是一个空指针,从而当作一个0 传入

9、。(注意很多Unix 手册在这个例子上都弄错了。) 堆和栈A. 堆的大小仅受操作系统的限制,栈的大小一般一般较小B. 在堆上频繁的调用new/delete容易产生内存碎片,栈没有这个问题A. 堆和栈都可以动态分配所谓动态内存分配就是指在程序运行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。从以上动、静态内存分配比较可以知道动态内存分配相对于静态内存分配的特点: 1、不需要预先分配存储空间; 2、分配的空间可以根据程序的需要扩大或缩小。 一是时间不同。静态分配发

10、生在程序编译和连接的时候。动态分配则发生在程序调入和执行的时候。 二是空间不同。堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由函数alloca()进行分配。不过栈的动态分配和堆不同,他的动态分配是由编译器进行释放,无需我们手工实现。对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。“栈(stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数

11、据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。 一般,用static修饰的变量,全局变量位于静态数据区。函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。 内存管理常用区间和区间中的数据静态区(static): 存放(初始化的)全局变量、静态变量和(未初始化的)全局变量和静态变量; 栈区(stack): 存放局部变量和函数的形参。栈中的内存空间由编译器自动申请和释放。 堆区(heap): 存放动态分配内存函数申请的变量。堆中的内存空间需要程序员

12、手动释放,否则会引发内存泄露。 5. 分配效率:栈的效率比较高。堆的效率比栈要低得多。 6. 增长方向:堆的增长方向是从程序低地址到高地址向上增长,而栈的增长方向刚好相反(实际情况可能不是这样的,与CPU的体系结构有关) 堆是不连续的,生长方向是向上的,即向着内存地址增大的方向增长;栈是连续的,生长方向是向下的,即向着内存地址减小的方向增长。栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提

13、示overflow。因此,能从栈获得的空间较小。 堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。阐述 C+ STL 中 vector, set, multiset , list, map, multimap , deque 的特点 .vector和built-in数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随即存取,即操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当该数组后的内存空间不够时,需要重新申请一块足够大的内存并进行

14、内存的拷贝。这些都大大影响了vector的效率。list就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除和插入。deque是一个double-ended queue,它的具体实现不太清楚,但知道它具有以下两个特点:它支持操作符,也就是支持随即存取,并且和vector的效率相差无几,它支持在两端的操作:push_back,push_front,pop_back,pop_front等,并且在两端操作上与list的

15、效率也差不多。Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性map内部的实现自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能。set是集合,set中不会包含重复的元素,这是和vector的第一个区别,第二个区别是set内部用平衡二叉树实现,便于元素查找,而vector是使用连续内存存储,便于随机存取。因此在实际使用时,如何选择这几个容器中哪一个,应根据你的需要而定,一般应遵循下面的原则:1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。4、如果你要存储一个数据字典,并要求方便地根据key找value,那么map是较好的选择5、如果你要查找一个元素是否在某集合内存中,则使用set存储这个集合比较好 vector,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号