💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] 1. 判断一段程序是什么编译器编译 如果编译器在编译cpp文件,那么`_cplusplus`就会被定义,如果是一个C文件被编译,那么`_STDC_`就会被定义,`_STDC_`是预定义宏,当它被定义后,编译器将按照ANSIC标准来编译C语言程序。 2. C++函数中值的传递方式 * 按值传递(pass by value) * 地址传递(pass by pointer) * 引用传递(pass by reference) 按值传递方式容易理解,但形参值的改变不能对实参产生影响。 ` ` 地址传递方式虽然可以使得形参的改变对相应的实参有效,但如果在函数中反复利用指针进行间接访问,会使程序容易产生错误且难以阅读。 ` ` 如果以引用为参数,则既可以使得对形参的任何操作都能改变相应的数据,又使得函数调用显得方便、自然。引用传递方式是在函数定义时在形参前面加上引用运算符“&”。 3. C++中虚函数问题 4. C++和C有什么不同 语法 特性 场景 效率 C:面向过程,效率高,嵌入式。如linux核心大部分是C写的 C++:面向对象。更上层,更复杂。增加里模版泛型。 5. C和C++中struct有什么区别 | | Protection行为 | 能否定义函数 | | --- | --- | --- | --- | | C | 无 | 否,但可以有函数指针 | | C ++ | 有,默认是public | 可以 | 6. C++中struct和class有什么区别 区别在于权限问题上。 class和struct 做类型定义时只有两点区别: 1)默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理 2)成员的默认访问权限。class的成员默认是private,struct默认是public权限。 7. int id[sizeof(unsigned long];这个对吗?为什么? 正确 这个sizeof是编译时运算符,编译时就确定里可以看成和机器有关的变量。sizeof(unsigned long]) 确定的常量。 8. new in c++ is a: **key word** and **operator** 9. 变量的指针含意是指变量的**地址** 10. 多态的作用 - 1.隐藏实现细节,是的代码能够模块化;扩展代码模块,实现代码重用 - 2.接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。 11. 多态类中的虚函数表是Complie-Time,还是Run-Time时建立的? 虚函数表是在编译时期就建立类,各个虚拟函数这时被组织成类一个虚拟函数的入口地址的数组,而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键。 12. 面向对象的三个基本特征,并简单叙述之 封装:将客观事物抽象成类,每个类对自身的数据和方法是想protection(private,protected,public) 继承:广义的继承有三种实现形式:实现继承、可视继承、接口继承。前两种和后一种构成类功能复用的两种方式。 多态:是将父类对象设置成为和一个或更多的与他的自对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特征以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。 是什么? 怎么用? 为什么使用它? 13. 内联函数在编译时是否做参数类型检查 内联函数要做参数检查,这his内联函数跟宏相比的优势。 14. 内存的分配方式有几种 1) 静态存储区域。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。 2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,到那时分配的内存容量有限。 3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。 15. 对于一个频繁使用但短小函数,在C语言中应用什么实现,在C++中应用什么实现》 C用宏定义,C++用inline 16. 全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的? 生命周期:全局变量随主程序创建而创建,随主程序销毁而销毁;局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在; 使用方式不同:通过声明后全局变量程序的各个部分都可以用到,放在静态数据区;局部变量只能在局部使用;分配在栈区。 操作系统和编译器通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行的时候被加载。局部变量则分配在堆栈里。 17. 如果在申请动态内存时找不到足够大的内存快,malloc和new将返回NULL指针,宣告内存申请失败。你是怎么处理内存耗尽的? 如果返回nULL则什么都不做 18. 用C++写一个程序,如何判断一个操作系统是16位还是32位的? 标准答案:定义一个指针p。打印出sizeof(p),如果打印结果是4,则表示该操作系统是32位,打印结果是2,表示是16位。计算指针变量 19. 不用sizeof() 判断操作系统是16位还是32位。 ``` unsign int a = ~0; if (a > 65536) { cout << "32 bit" << endl; } else { cout << "16 bit" << endl; } // 在64位操作系统中该方法不适合。需要用sizeof(指针)来计算 ``` 20. 为什么需要使用堆,使用堆空间的原因? 直到运行时才知道一个对象需要多少内存空间;不知道对象的生存周期到底有多长。 21. 若数组名作为实参而指针变量作形参,函数调用实参给形参的是() 数组第一个元素的地址 22. 有来malloc/free,为什么还要用new-delete malloc/free是C++/C语言的标准库函数,new/delete是C++的运算符。他们都可以用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能把执行构造函数和析构函数的任务强加于malloc/free. 因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。 23.为什么数组名作为参数,会改变数组的内容,而其他类型如int却不会改变变量的值? 数组传递的是首元素的地址。 24。请讲一讲析构函数和虚函数的用法和作用 析构函数是特殊的类成员函数,它没有返回类型,没有参数,不能显示调用,也没有重载,只有在类对象的生命周期结束的时候,由系统自动调用。有释放内存空间的作用。 可以是虚析构函数。 虚函数是C++多态的一种表现,使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。 25. 错误的转义字符('091') '\091' '\\' '\0' '\' 26. 如果ClassA中定义并实现虚函数int func(void), ClassB中也实现该函数,那么上述变量a->func()将调用哪个类里面的函数? 如果int func(void)不是虚函数,情况又如何?为什么? 第一问调用的是B的。第二问调用A的。虚函数的第一个典型应用。**虚函数只能借助于指针或者引用来达到多态的效果**。 27. 引用与指针有什么区别? 参考答案: 1)引用必须被初始化,指针不必 2)(引用初始化后不能被改变),指针可以改变所指的对象。 3)不存在只想空值的引用,但是存在指向空值的指针。 28. 你觉得如果不使用常量,直接在程序中填写数字或字符串,将会有什么麻烦? 1)程序的可读性变差。程序员自己会忘记那些数字或字符串是什么意思,用户则更加不知他们从何而来、表示什么。 2)在程序的很多地方输入同样的数字或字符串,难保不发生书写错误。 3)如果要修改数字或字符串,则会在很多地方改动,既麻烦又容易出错。 29. 在C++中有没有纯虚构造函数? 构造函数不能是虚的,只有虚的析构函数。构造函数需要指定数据类型。 30. 重复多次fclose 一个打开过一次的FILE*fp指针会有什么结果,并请解释。 考察点:导致文件描述符结构中指针指向的内存被重复释放,进而导致一些不可预期的异常。 31.重载和重写、重定义(覆盖)的区别 重载:在同一个类中。是允许存在多个同名函数,而这些函数的参数表不同。 重写:在继承链中,派生类与基类函数同名,屏蔽基类的函数(虚函数) 覆盖:不同名字空间,用于继承,子类重新定义复类虚函数的方法 32. C++是不是类型安全的? 不是。两个不同类型的指针之间可以强制转换(用reinterpret cast). 33. C++里是不是所有的动作都是main()引起的?如果不是,请距离 比如全局变量的初始化,就不是由main函数引起的。 34. main函数执行之前,还会执行什么代码》 全局对象的构造函数会在main函数之前执行 35. C++中virtual与inline的含义分别是什么? 在基类成员函数的声明加上virtual关键字,意味着将该成员函数声明为虚函数。inline与函数的定义体放在一起,使该函数称为内联。inline是一种用于实现的关键字,而不是用于声明的关键字。 虚函数的特点;用于多态、纯虚函数(抽象类)。如果希望派生类能够重新定义基类的方法,则在基类中将该方法定义为虚方法,这样可以启动动态联编。 内联函数的特点;使用内联函数的目的是为里提高函数的运行效率。内联函数体的代码不能过长,因为内联函数省去调用函数的时间是以代码膨胀为代价的。内联函数不能包含循环语句,因为执行循环语句要比调用函数的开销大。 36. const关键字?有哪些作用 1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它里; 2)对指针来说,可以指定指针本身为const,也可以指定指针所指对数据为const,或二者同时指定为const; 3)在一个函数声明中,const可以修饰形参,表明他是一个输入参数,在函数内部不能改变其值; 4)对于类成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类对成员变量; 5)对于类对成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值“。 37. VC中,编译工具条内对Debug与Release选项是什么含义? Debug:会额外新增一些可调式的符号。 Release:把运行不相关的信息剔除掉。发布版本 38. 是不是一个父类写类一个virtual函数,如果子类覆盖它的函数不加virtual,也能实现多态? virtual修饰符会被隐形继承。virtual可加可不加。子类的空间里有父类的所有变量(static除外)。同一个函数只存在一个实体(inline除外)。子类覆盖它的函数不加virtual,也能实现多态。在子类的空间里,有父类的私有变量。私有变量不能直接访问。 39. 一个栈的入栈序列是A,B,C,D,E,则栈的不可能的输出顺序是(DCEAB)。 栈:后进先出 40. 在不用第三方参数的情况下,交换两个参数的值。 ``` 一: a = a+b; b = a - b; a = a - b; 二: 异或: ``` 41.打印当前源文件的文件名以及源文件的当前行号? ``` //使用预定义的两个宏 cout << __FILE__; cout << __LINE__; ``` 42. 当一个类A中没有声明任何成员变量与成员函数,这时sizeof(A)的值为1 43. 下面的函数实现在一个固定的数上加上一个数,有什么错误。 ``` int add_n(int n) { static int i = 100; i += n; return i; } 解:因为static使得i的值会保留上次的值。以后的i会一直更新,使得第二次调用出现错误。去掉static就可以了。 ``` 44. 在排序方法中,关键码比较次数与记录地初始排列无关的是(D) ``` A.Shell排序 B.归并排序 C.直接插入排序 D.选择排序 ``` 45. 函数模版与类模版有什么区别? 函数模版的实例化是由编译程序在处理函数调用时自动完成的,而类模版的实例化必须由程序员在程序中显示的指定。 46、函数重载,我们靠什么来区分调用的那个函数?靠返回值判断可以不可以? ``` 不可以。 void Function(void); int Function(void); 上述两个函数,第一个没有返回值,第二个的返回值是int类型。如果这样调用函数:int x = Function(); 则可以判断除Function是第二个函数。问题是在C++/C程序中,我们可以忽略函数的返回值。在这种情况下,编译器和程序员都不知道哪个Function函数被调用。所以只能靠参数而不能靠返回值类型的不同来区分重载函数。 ``` 47.不能被重载的运算符 1) 不能改变C++内部数据类型(如int,float等)运算符。 2)不能重载‘.‘,因为 在类中对任何成员都有意义,已经成为标准用法。 3)不能重载目前C++运算符集合中没有的符号,如#,@,$等。原因有两点,一是难以理解,二是难以确定优先级。 4)对已经存在的运算符进行重载时,不能改变优先级规则,否则将引起混乱。 48.基类的析构函数不是虚函数,会带来什么问题? ``` class B: class A { } A* a = new B(); delete a; 如果A的析构函数中不是虚函数。则在delete的时候只调用A的析构函数而不会调用B的析构函数。造成内存泄漏。 ``` 49. 介绍一下模版和容器。如何实现 模版是C++中实现泛型的一种机制 容器是一种特定用途的类 模版可以说比较古老类。但是当前的泛型编程实质上就是模版编程。它体现类了一种通用和泛化的思想 STL 有7种主要容器: vector,list,deque, map, multimap, set, multiset. 50. 深拷贝和浅拷贝的区别 深拷贝:资源拷贝。意味着拷贝类资源和指针, 浅拷贝:只进行值拷贝。浅拷贝只是拷贝了指针,没有拷贝资源。这样使得两个指针指向同一份资源,造成对同一份析构两次,程序崩溃。临时对象的开销比局部对象小些