那些不能遗忘的知识点回顾——C/C++系列(笔试面试高频题)

有那么一些零碎的小知识点,偶尔很迷惑,偶尔被忽略,偶然却发现它们很重要,这段时间正好在温习这些,就整理在这里,一起学习一起提高!后面还会继续补充。

1.面向对象的特性

封装、继承、多态。

封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。(优点:可以隐藏实现细节,使得代码模块化)

继承:可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。(优点:可以扩展已存在的代码模块(类))

多态:一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。虽然针对不同对象的具体操作不同,但通过一个公共的类,这些操作可以通过相同的方式被调用。

多态实现的两种方式:父类指针指向子类对象 或 将一个基类的引用类型赋值为它的派生类实例。(重要:虚函数 + 指针或引用)

构造函数、复制构造函数、析构函数、赋值运算符不能被继承。

2.堆和栈

从内存角度来说:栈区(stack)由编译器自动分配释放,存放函数的参数值,局部变变量的值等,其操作方式类似于数据结构中的栈,可静态亦可动态分配。

堆区(heap)一般由程序员分配释放,若程序员不释放,可能造成内存泄漏,程序结束时可能由OS回收。只可动态分配,分配方式类似于链表。

从数据结构角度来说:堆可以被看成是一棵树,如:堆排序。

而栈是一种先进后出的数据结构。

3.malloc和new

1.malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。但它们都可用于申请动态内存和释放内存。

2.对于非内部数据类型的对象而言,用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free,因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,和一个能完成清理与释放内存工作的运算符delete。

3.new可以认为是malloc加构造函数的执行。new出来的指针是直接带类型信息的。而malloc返回的都是void*指针。new delete在实现上其实调用了malloc,free函数。

4.new 建立的是一个对象;malloc分配的是一块内存。
  6.对一个类求sizeof需要考虑的内容

见知识点4。同时,对于一个结构体和一个类执行sizeof()运算时情况比较复杂,详细分析请移步另一篇博文struct/class等内存字节对齐问题详解

4.重载和重写(覆盖)

方法的重写Overriding和重载Overloading是多态性的不同表现。

重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。

如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了,而且如果子类的方法名和参数类型和个数都和父类相同,那么子类的返回值类型必须和父类的相同;如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloading的方法是可以改变返回值的类型。也就是说,重载的返回值类型可以相同也可以不同。

5.“引用”与多态的关系?

引用是除指针外另一个实现多态的方式。这意味着,一个基类的引用可以指向它的派生类实例。例:

Class A; Class B : Class A{…};

B b; A& ref = b;

6.计算机加载程序包括哪几个区?

一个由C/C++编译的程序占用的内存分为以下几个部分:

(1)栈区(stack):—由编译器自动分配释放,存放函数的参数值,局部变量的值等。可静态也可动态分配。其操作方式类似于数据结构中的栈。

(2)堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。动态分配。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

(3)全局区(静态区):—程序结束后由系统释放,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域;未初始化的全局变量和静态变量在相邻的另一块区域(BSS,Block Started by Symbol),在程序执行之前BSS段会自动清0。

(4)文字常量区:—程序结束后由系统释放,常量字符串就是放在这里的。

(5)程序代码区:—存放函数体的二进制代码。

7.派生类中构造函数与析构函数,调用顺序

构造函数的调用顺序总是如下:

1.基类构造函数。如果有多个基类,则构造函数的调用顺序是某类在类派生表中出现的顺序,而不是它们在成员初始化表中的顺序。

2.成员类对象构造函数。如果有多个成员类对象则构造函数的调用顺序是对象在类中被声明的顺序,而不是它们出现在成员初始化表中的顺序。如果有的成员不是类对象,而是基本类型,则初始化顺序按照声明的顺序来确定,而不是在初始化列表中的顺序。

3.派生类构造函数。

析构函数正好和构造函数相反。

8.extern “C”的作用

extern "C"实现C++与C及其它语言的混合编程,是用在C和C++之间的桥梁。之所以需要这个桥梁是因为C编译器编译函数时不带函数的类型信息,只包含函数符号名字;而C++编译器为了实现函数重载,编译时会带上函数的类型信息,如他把上面的a函数可能编译成_a_float这样的符号为了实现重载。

extern "C"的惯用法:

在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:

extern “C”{

#include “cExample.h”

}

而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。

extern本身作为关键字修饰变量(函数)时声明该变量(函数)是外部变量(函数),通常全局变量在头文件中用这种方式声明,在对应源文件中定义,来防止重定义的错误。

9.析构函数、构造函数能不能被继承

见知识点1

10.C++为什么用模板类,为什么用泛型

通过泛型可以定义类型安全的数据结构(类型安全),而无须使用实际的数据类型(可扩展)。这能够显著提高性能并得到更高质量的代码(高性能),因为您可以重用数据处理算法,而无须复制类型特定的代码(可重用)。

11.结构体内存对齐,与什么有关(CPU)

在系统默认的对齐方式下:每个成员相对于这个结构体变量地址的偏移量正好是该成员类型所占字节的整数倍,且最终占用字节数为成员类型中最大占用字节数的整数倍。

详细分析见博客:struct/class等内存字节对齐问题详解

为什么要对齐?当CPU访问正确对齐的数据时,它的运行效率最高,当数据大小的数据模数的内存地址是0时,数据是对齐的。例如:WORD值应该是总是从被2除尽的地址开始,而DWORD值应该总是从被4除尽的地址开始,数据对齐不是内存结构的一部分,而是CPU结构的一部分。当CPU试图读取的数值没有正确的对齐时,CPU可以执行两种操作之一:产生一个异常条件;执行多次对齐的内存访问,以便读取完整的未对齐数据,若多次执行内存访问,应用程序的运行速度就会慢。

12.指针和引用

1.指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。

2.指针可以有多级,但是引用只能是一级;

3.指针的值可以为空,也可能指向一个不确定的内存空间,但是引用的值不能为空,并且引用在定义的时候必须初始化为特定对象;(因此引用更安全)

4.指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变引用对象了;

5.sizeof引用得到的是所指向的变量(对象)的大小,而sizeof指针得到的是指针本身的大小;

6.指针和引用的自增(++)运算意义不一样;

13.volatile

volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。

volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样一来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。

14.#define与const的区别

• define不会做类型检查(容易出错),const拥有类型,会执行相应的类型检查
  • define仅仅是宏替换,不占用内存,而const会占用内存
  • const内存效率更高,编译器可能将const变量保存在符号表中,而不会分配存储空间,这使得它成 为一个编译期间的常量,没有存储和读取的操作

当使用#define定义一个简单的函数时,强烈建议使用内联函数替换!

15.析构函数中抛出异常时概括性总结

(1) C++中析构函数的执行不应该抛出异常;
  (2) 假如析构函数中抛出了异常,那么系统将变得非常危险,也许很长时间什么错误也不会发生;但也许系统有时就会莫名奇妙地崩溃而退出了,而且什么迹象也没有;
  (3) 当在某一个析构函数中会有一些可能(哪怕是一点点可能)发生异常时,那么就必须要把这种可能发生的异常完全封装在析构函数内部,决不能让它抛出函数之外,即在析构函数内部写出完整的throw…catch()块。
  出处:博客园
  原作者:闻波

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
水资源是人类社会的宝贵财富,在生活、工农业生产中是不可缺少的。随着世界人口的增长及工农业生产的发展,需水量也在日益增长,水已经变得比以往任何时候都要珍贵。但是,由于人类的生产和生活,导致水体的污染,水质恶化,使有限的水资源更加紧张。长期以来,油类物质(石油类物质和动植物油)一直是水和土壤中的重要污染源。它不仅对人的身体健康带来极大危害,而且使水质恶化,严重破坏水体生态平衡。因此各国都加强了油类物质对水体和土壤的污染的治理。对于水中油含量的检测,我国处于落后阶段,与国际先进水平存在差距,所以难以满足当今技术水平的要求。为了取得具有代表性的正确数据,使分析数据具有与现代测试技术水平相应的准确性和先进性,不断提高分析成果的可比性和应用效果,检测的方法和仪器是非常重要的。只有保证了这两方面才能保证快速和准确地测量出水中油类污染物含量,以达到保护和治理水污染的目的。开展水中油污染检测方法、技术和检测设备的研究,是提高水污染检测的一条重要措施。通过本课的研究,探索出一套适合我国国情的水质污染现场检测技术和检测设备,具有广泛的应用前景和科学研究价值。 本课针对我国水体的油污染,探索一套检测油污染的可行方案和方法,利用非分散红外光度法技术,开发研制具有自主知识产权的适合国情的适于野外便携式的测油仪。利用此仪器,可以检测出被测水样中亚甲基、甲基物质和动植物油脂的污染物含量,为我国众多的环境检测站点监测水体的油污染状况提供依据。
### 内容概要 《计算机试卷1》是一份综合性的计算机基础和应用测试卷,涵盖了计算机硬件、软件、操作系统、网络、多媒体技术等多个领域的知识点。试卷包括单选和操作应用两大类,单选部分测试学生对计算机基础知识的掌握,操作应用部分则评估学生对计算机应用软件的实际操作能力。 ### 适用人群 本试卷适用于: - 计算机专业或信息技术相关专业的学生,用于课程学习或考试复习。 - 准备计算机等级考试或职业资格认证的人士,作为实战演练材料。 - 对计算机操作有兴趣的自学者,用于提升个人计算机应用技能。 - 计算机基础教育工作者,作为教学资源或出参考。 ### 使用场景及目标 1. **学习评估**:作为学校或教育机构对学生计算机基础知识和应用技能的评估工具。 2. **自学测试**:供个人自学者检验自己对计算机知识的掌握程度和操作熟练度。 3. **职业发展**:帮助职场人士通过实际操作练习,提升计算机应用能力,增强工作竞争力。 4. **教学资源**:教师可以用于课堂教学,作为教学内容的补充或学生的课后练习。 5. **竞赛准备**:适合准备计算机相关竞赛的学生,作为强化训练和技能检测的材料。 试卷的目标是通过系统性的目设计,帮助学生全面复习和巩固计算机基础知识,同时通过实际操作目,提高学生解决实际问的能力。通过本试卷的学习与练习,学生将能够更加深入地理解计算机的工作原理,掌握常用软件的使用方法,为未来的学术或职业生涯打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值