ImageVerifierCode 换一换
格式:DOCX , 页数:65 ,大小:42.57KB ,
资源ID:11292858      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11292858.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(面试宝典之C++面试知识分享.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

面试宝典之C++面试知识分享.docx

1、面试宝典之C+面试知识分享2012.07.201.strcpy函数/*static*/char* my_strcpy(char* pDest, constchar* pSrc) assert(pDest != NULL) & (pSrc != NULL); char* pRet = pDest; / record the position of destination. while (*pRet+ = *pSrc+)!=0) NULL; return pDest;返回值用char*是为了实现链式表达式而返回具体值,如int length = strlen( strcpy( strDest, “

2、hello world”) );关键点:static方法:使某个函数只在一个源文件中有效,不能被其他源文件所用。(1)它允其他源文件建立并使用同名的函数,而不相互冲突。(2)声明为静态的函数不能被其他源文件所调用,因为它的名字不能得到。源字符串用const:保证源字符的内容不被改变(地址可以变)。const char* str涉及到的字符串,指针的地址可以变,但是指针指向地址的内容不能变;char* const str涉及到的指针内容不能改变。提高性能的方法:staticchar* my_strcpy2(char *pDest, constchar* pSrc) assert(pDest !=

3、 NULL) & (pSrc != NULL); char *s = (char*)pSrc; int delt = pDest - pSrc;/ 地址之差 while (sdelt = *s+) != 0); / sdelt实为*(s + delt) return pDest;char* my_memset(char *pDst, int val, size_t size) char *start = pDst; while (size 0) *pDst = (char)val; pDst = pDst + 1; size -; return start;void* my_memset(vo

4、id *pDst, int val, size_t size) / 库函数写法 void *start = pDst; while (size 0) *(char*)pDst = (char)val; pDst = (char*)pDst + 1; size -; return start;memcpy是不考虑内存重叠的。void* my_memcpy(void *pDst, constvoid *pSrc, size_t size) void *ret = pDst; while (size 0) *(char*)pDst = *(char*)pSrc; pDst = (char*)pDst

5、 + 1; pSrc = (char*)pSrc + 1; size -; return ret;void* my_memmove(void *pDst, constvoid *pSrc, size_t size) void *ret = pDst; if (char*)pDst = pDst)/内存没有重叠时与memcpy一样 while (size 0) *(char*)pDst = *(char*)pSrc; pDst = (char*)pDst + 1; pSrc = (char*)pSrc + 1; size -; else/ OverLapping buffers 内存重叠 pDs

6、t = (char*)pDst + size - 1; pSrc = (char*)pSrc + size - 1; while (size 0) *(char*)pDst = *(char*)pSrc; pDst = (char*)pDst - 1; pSrc = (char*)pSrc - 1; size -; return ret;2.赋值语句int i = 1;int main() int i = i; / undefined value.里面定义了i之后就屏蔽了全局变量 return 0;3.求一个数转换成二进制的数中的1的个数的求法:int Count1forBinary(int

7、x) int count = 0; while (x) count +; x = x & (x -1); / 每次消去最后一个1 return count;补充:判断一个数是不是2的N次方的方法:!(x & (x -1)4.C语言中printf和C+中cout计算参数时是从右到左压栈的。printf(%d, %d, *ptr, *(+ptr); / 输出的结果应该是一样的cout *ptr n *(+ptr) endl; / 输出的结果应该是一样的5.优先级:+ -优先于* &(取值取址)优先于sizeof() 优先于 * / % 优先于6.求平均值:int f(int x, int y) r

8、eturn (x & y) + (x y) 1);7.不用判断语句求两个数中间比较大的数max = (a + b) + abs(a - b) / 2;8.不用中间变量,交换a、b的值方法一:a = a + b;b = a - b;a = a - b; / a+b可能会越界方法二:a = a b; b = a b; a = a b;2012.07.211.C+的类中的数据成员加上mutable后,修饰为const的成员函数,就可以修改它了。int fun() const /*/只能调用const的变量,不能改变cout setw(tmp) setfill() tmp endl; / setw()

9、为设置宽度,setfill()为设置填充字符2.sizeof的用法char ss3100 = 0123456789; cout sizeof(ss3):sizeof(ss3) endl; / 100,预分配的大小 cout strlen(ss3): strlen(ss3) endl; / 10,内部实现是用一个循环计算字符串的长度,直到“0”为止。 int ss4100; cout sizeof(ss4):sizeof(ss4) endl; / 400cout strlen (ss4):strlen (ss4) endl; / 错误,因为strlen的参数只能是char*,且必须是以”0”结束

10、。char *str1 = (char *)malloc(100); cout sizeof(str1):sizeof(str1) endl; / 4,指针的大小cout sizeof(*str1):sizeof(*str1) endl; / 1,第一个字符sizeof(struct)时,struct要考虑对齐,一般都是取结构体中最长的来对齐,结构体默认对齐长度为8。sizeof()计算栈中分配的大小,因此静态变量等全局数据区内的数的大小是不会计算在内的。sizeof()按字节大小计算。内存对齐的规则:1、对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(

11、#pragma pack()指定的数,这个数据成员的自身长度)的倍数。2、在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。默认的#pragma pack指定的值为8,如果最大数据结构成员长度为int,则结果本身按照4字节对齐,结构总大小必须为4的倍数。内存对齐的主要作用是:1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。2、性能原因:经过内存对齐后,CPU的内存访问速度大大提升。CPU把内存

12、当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块进行读取的。块大小称为memory access granularity(粒度)本人把它翻译为“内存读取粒度”。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。与strlen()的区别,具体实现sizeof是运算符,strlen是函数;sizeof操作符的结果类型是size_t;sizeof可以用类型做参数,还可以用函数做参数,而strlen只能用char*的变量做参数,且必须是以0结尾的;大部分编译器在编译时就计算sizeof的值,是类型或者变量的长度,而str

13、len在运行时计算,计算字符串的长度,而不是内存的大小;sizeof后如果是变量名可以不加括号。int my_strlen(constchar *str) assert(str != NULL); int len = 0; while (*str +) != 0)/ 先执行*,再执行+ len +; return len;int my_strlen2(constchar *str)/库函数 constchar *eos = str; while( *eos+ ) ; return( eos - str - 1 );3.程序中常规的的变量,都是从大地址向小地址放的(存放在一个堆栈中,堆栈以大地址

14、为底)。4.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如fun(char 8)、fun(char )都等价于fun(char *),编译器是不知道数组的大小的。5.类虚继承后,会添加虚表。虚继承是为了解决多重继承中的重定义而产生的。class B : public virtual A虚基类:在虚继承体系中的通过virtual继承而来的基类,如A。6.inline内联函数,在调用的地方不是跳转,而是把代码直接写到那里。与宏函数相比,内联函数要做类型检查。(const与宏的差别也是const有类型设置,会检查类型。)对于短小的代码,inline减少了普通函数调用时的资源消耗

15、,可以带来效率的提升,而它会增加空间的消耗。2012.07.231.指针和引用的区别引用不能为空,内容不能改变,使用前不会测试它的合法性;而指针正好相反。定义引用时必须初始化(const变量一样)。2.地址值相减,转换成int之后要/sizeof(int)。P68int* m = (int*)2000; int* n = (int*)1000; printf(%dn, m-n); / -2503.const指针:const int* a;可以执行a+,但是不能执行(*a)+指向const的指针:int* const;可以执行(*a)+,但不能执行a+4.数组名本身就是指针,加个&就变成了双指针

16、,即二位数组。int a = 1, 2, 3, 4, 5; int *ptr = (int *)(&a + 1); cout ptr - a endl; / 5,ptr指向下一行5.malloc与free是C+/C的标准库函数,而new/delete是C+的运算符。对于非内部数据结构的对象而言,只用malloc/free无法满足动态对象的要求。malloc和free是库函数而不是运算符,不在编译器控制权限之内,不能够执行构造函数和析构函数。6.智能指针auto_ptr是安全指针,包含在空间std中,用它构造的对象,析构函数总在退栈过程中被调用。auto_ptr pObj(new Object)

17、;auto_ptr source() return new Object;7. vector *a1 = new vector(); a1-push_back(d1); / 浅拷贝 delete a1; /释放vector对象,vector包含的元素也同时释放了8.静态模板类:templatetemplate用法STL9.一个空类默认产生的成员函数:默认构造函数、析构函数、拷贝构造函数、赋值函数。拷贝构造函数:CExample(constCExample& C)就是我们自定义的拷贝构造函数。可见,拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它的唯一的一个参数是本类型的一个引用

18、变量,该参数是const类型,不可变的。例如:类X的拷贝构造函数的形式为X(X& x)。当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:一个对象以值传递的方式传入函数体一个对象以值传递的方式从函数返回一个对象需要通过另外一个对象进行初始化。深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。CA(const CA& C)a=C.a;str=new chara

19、; /深拷贝if(str!=0)strcpy(str,C.str);10.class和struct的区别:class中变量默认是private,struct中变量默认是public。C+中存在struct是为了兼容以前的C项目。11.类中,初始化列表的初始化顺序是根据成员变量的声明顺序来执行的。常量必须在构造函数的初始化列表里初始化或者将其设置成static。class A A() const int Size = 0;或者class A static const int Size = 0;12.MFC中Cobject的析构函数是虚拟的。原因:多态的情况,CBase *p = new CChi

20、ld();析构时,如果不是virtual则会调用父类的析构函数,而实际new的子类的空间可能不会完全释放;而如果是virtual的析构函数,则会调用虚拟指针执行的子类的析构函数来释放空间。13.strcpy, strncpy, strlcpystrcpy 是依据 /0 作为结束判断的,如果 to 的空间不够,则会引起 buffer overflow。strcpy(char *to, const char *from) char *save = to; for (; (*to = *from) != /0; +from, +to); return(save);strncpy(path, src,

21、 sizeof(path) - 1); / 要赋值的长度pathsizeof(path) - 1 = /0;len = strlen(path);strlcpy(char *dst, const char *src, size_t size);而使用 strlcpy,就不需要我们去手动负责 /0 了,仅需要把 sizeof(dst) 告之 strlcpy 即可:strlcpy(path, src, sizeof(path);len = strlen(path);if ( len = sizeof(path) ) printf(src is truncated.);并且 strlcpy 传回的是

22、 strlen(str),因此我们也很方便的可以判断数据是否被截断。2012.07.241.String类P112class Stringpublic: String(constchar *str = NULL); /普通构造函数 String(const String ©); / 拷贝构造函数 String(); String&operator=(const String &other); / 赋值函数private: char *m_data;String:String(constchar *str /* = NULL */) if (NULL = str) m_data = ne

23、wchar1; m_data = 0; else int length = strlen(str); m_data = newcharlength + 1; strcpy(m_data, str); String:String() delete m_data;String:String(const String ©) int length = strlen(copy.m_data); m_data = newcharlength + 1; strcpy(m_data, copy.m_data);String& String:operator=(const String &other)

24、if (this = &other) return *this; delete m_data; m_data = newcharstrlen(other.m_data) + 1; strcpy(m_data, other.m_data); return *this;调用:String s1(hello); String s2 = s1;或者String s2(s1);/ 拷贝构造函数 String s3; s3 = s2; / 赋值函数2.重载在编译期间就确定了,是静态的,重载和多态无关。真正与多态相关的是覆盖(虚函数)。当定义了父类的虚函数后,父类指针根据赋给它的不同的子类的指针,动态地调用

25、属于子类的该函数,这样的函数调用在编译期间是无法确定的,调用子类的虚函数的地址无法给出。封装可以隐藏细节,使得代码模块化,继承可以扩展存在的代码模块,它们都是为了代码重用。而多态是为了接口重用。override覆盖(派生类函数覆盖基类virtual函数),overload重载(语义、功能相似的几个函数用同一个名字表示,但参数或返回值不同),overwrite重写(派生类的函数屏蔽了与其同名的基类函数)。重写:(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。(2)如果派生类的函数与基类的函数同名,并且参数也相同,但

26、是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。class Parentpublic: void F() cout Parent F().n; virtualvoid G() cout Parent G().n; int Add(int x, int y) return x + y; float Add(float x, float y) / overload return x + y; ;class Child : public Parent void F() /overwrite cout Child F().n; virtualvoid G() / ove

27、rride cout G();) p-F(); / Parent F(). p-G(); / Child G().3.void function()const; /常成员函数, 它不改变对象的成员变量. 也不能调用类中任何非const成员函数。4.析构函数可以是private的。class Test1public: Test1() cout Constructor. endl; ; void DeleteTest1() cout Delete test1. endl; deletethis; private: Test1() cout Destructor.DeleteTest1();5.构造

28、函数不能是virtual的。构造函数可以是private的,但是该类不能被实例化,因为不能执行初始化。private的构造函数不会生成默认的拷贝构造函数。6.构造函数是从最初始的基类开始构造,各个类的同名变量没有形成覆盖,都是单独的变量。接口的调用是就近的,优先调用离自己最近的接口(从当前层往上向父辈、祖父辈)。7. A *pa = newA(); B *pb = (B *)pa;/ 始终是A类空间 delete pa, pb;/删除所指向的地址,但pa、pb指针并没有删除,也就是悬浮指针 pa = newB();/ B类的空间 pb = (B *)pa;8.子类继承父类时,不管什么继承方式,子类都会继承父类的任何数据成员和方法,不管数据成员和方法是什么类型,只是因为继承方式或类型的原因而

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1