zoukankan      html  css  js  c++  java
  • C++笔试常见问题

    C++提供的编译预处理功能主要有以下三种:

    • 宏定义
    • 文件包含
    • 条件编译

    预编译又称为预处理 , 是做些代码文本的替换工作。处理#开头的指令 , 比如拷贝 #include 包含的文件代码, #define 宏定义的替换 , 条件编译等,就是为编译做的预备工作的阶段,主要处理#开始的预编译指令,预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。
    预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。

    下面是部分预处理指令:

        指令             用途
            #           空指令,无任何效果
            #include    包含一个源代码文件
            #define     定义宏
            #undef      取消已定义的宏
            #if         如果给定条件为真,则编译下面代码
            #ifdef      如果宏已经定义,则编译下面代码
            #ifndef     如果宏没有定义,则编译下面代码
            #elif       如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
            #endif      结束一个#if……#else条件编译块
            #error      停止编译并显示错误信息
    

    C++中的预编译


    const常量与define宏定义的区别

    1.编译器处理方式不同。define宏是在预处理阶段展开,生命周期止于编译期。只是一个常数、一个命令中的参数,没有实际的存在。#define常量存在于程序的代码段。const常量是编译运行阶段使用,const常量存在于程序的数据段。

    2.类型和安全检查不同。define宏没有类型,不做任何类型检查,仅仅是展开。const常量有具体的类型,在编译阶段会执行类型检查。

    3.存储方式不同。define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。const常量会在内存中分配(可以是堆中也可以是栈中)


    #include <my.h>#include "my.h"

    1.第一种方法(#include <my.h>)是用尖括号把头文件括起来。这种格式告诉预处理程序在编译器自带的或外部库的头文件中搜索被包含的头文件。第二种方法(#include "my.h")是用双引号把头文件括起来。这种格式告诉预处理程序在当前被编译的应用程序的源代码文件中搜索被包含的头文件,如果找不到,再搜索编译器自带的头文件。

    2.采用两种不同包含格式的理由在于,编译器是安装在公共子目录下的,而被编译的应用程序是在它们自己的私有子目录下的。一个应用程序既包含编译器提供的公共头文件,也包含自定义的私有头文件。采用两种不同的包含格式使得编译器能够在很多头文件中区别出一组公共的头文件

    总之, #include <my.h>是从标准库路径中开始搜索文件, #include "my.h"是编译器从用户的工作路径开始搜索文件


    面向对象的三个基本特征 和 五种设计原则

    三个基本特征

    1.封装(Encapsulation)

    所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

    2.继承(Inheritance)

    继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

    3.多态(Polymorphism)

    所谓多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。

    五种设计原则

    1.单一职责原则(Single-Resposibility Principle)

    一个类应该仅有一个引起它变化的原因

    2.开放封闭原则(Open-Closed principle)

    对扩展是开放的,对更改是封闭的!

    3.里氏替换原则(Liskov-Substituion Principle)

    子类可以替换父类并且出现在父类能够出现的任何地方,贯彻GOF倡导的面向接口编程

    4.依赖倒置原则(Dependecy-Inversion Principle)

    传统的结构化编程中,最上层的模块通常都要依赖下面的子模块来实现,也称为高层依赖低层!所以DIP原则就是要逆转这种依赖关系,让高层模块不要依赖低层模块,所以称之为依赖倒置原则!

    5.ISP 接口隔离原则(Interface-Segregation Principle)

    使用多个专门的接口比使用单个接口要好的多!

    面向对象三大特征、五大原则
    面向对象的三个基本特征 和 五种设计原则

    空类的大小为何是1

    标准禁止对象大小为 0,因为两个不同的对象需要不同的地址表示

    空类的大小为什么是1?

    关于static

    1.static可以修饰局部变量(静态局部变量)、全局变量(静态全局变量)和函数,被修饰的变量存储位置在静态区。

    • 对于静态局部变量,相对于一般局部变量其生命周期延长,直到程序运行结束而非函数调用结束,且只在第一次被调用时定义;
    • 对于静态全局变量,相对于全局变量其可见范围被缩小,只能在本文件中可见;
    • 修饰函数时作用和修饰全局变量相同,都是为了限定访问域。

    2.C++的static还可以修饰类成员(静态成员变量和静态成员函数),静态成员变量和静态成员函数不属于任何一个对象,是所有类实例所共有。实际上,它是增加了类的访问权限的全局函数。

    • 类的静态成员是该类所有实例的共用成员,也就是在该类的范畴内是个全局变量。
    • 类的静态函数是在该类的范畴内的全局函数,不能访问类的私有成员,只能访问类的静态成员,不需要类的实例即可调用;实际上,它就是增加了类的访问权限的全局函数。

    3.static的数据记忆性可以满足函数在不同调用期的通信,也可以满足同一个类的多个实例间的通信。

    4.未初始化时,static变量默认值为0。其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0×00,某些时候这一特点可以减少程序员的工作量。

    C++中常见的模板类

    这个。。。

    野指针出现的三种情况

    1.指针未初始化
    指针变量在定义时不会自动初始化成空指针,而是随机的一个值,可能指向任意空间,这就使得该指针成为野指针。

    2.指针指向的变量被free或delete后没有置为NULL
    在调用free或delete释放空间后,指针指向的内容被销毁,空间被释放,但是指针的值并未改变,仍然指向这块内存,这就使得该指针成为野指针。

    3.指针操作超过所指向变量的生存期
    当指针指向的变量的声明周期已经结束时,如果指针仍然指向这块空间,就会使得该指针成为野指针。

    注意:野指针只能避免而无法判断

    内存泄漏会引发什么问题

    内存泄露就是系统回收不了那些分配出去但是又不使用的内存, 随着程序的运行,可以使用的内存就会越来越少,机子就会越来越卡,直到内存数据溢出,然后程序就会挂掉,再跟着操作系统也可能无响应,接着你就按重启了。

    长期更新

    感谢阅读,如有问题,请批评指正,谢谢。
  • 相关阅读:
    emberjs 循环中设置model的不同属性值
    FUTURE .get 异常抛出会如何提示
    cpu ,鲲鹏,x86,主频,门电路,目录
    复制两个类的相同属性
    【深入Java虚拟机(1)】:Java内存区域与内存溢出
    RPC web service
    webservice
    django中配置Pymsql
    定义函数和调用函数的方式,函数形参和实参的介绍
    python名称空间与作用域
  • 原文地址:https://www.cnblogs.com/clwsec/p/11515508.html
Copyright © 2011-2022 走看看