c++面试题(一)——基础篇

1.c++中struct和class的区别

  • struct 一般用于描述一个数据结构集合,而 class 是对一个对象数据的封装
  • struct 中默认的访问控制权限是 public 的,而 class 中默认的访问控制权限是 private 的。
  • 在继承关系中,struct 默认是公有继承,而 class 是私有继承
  • class 关键字可以用于定义模板参数,就像 typename,而struct 不能用于定义模板参数。

2.C++中指针和引用的区别

  • 指针是存储变量地址变量;引用是变量的别名
  • 指针变量定义时不必=初始化;引用定义时必须初始化,不然会报错。
  • 指针变量定义时可以初始化为NULL;引用不能初始化为NULL,不然报错。
  • const修饰指针变量,const放在之前,指针变量所指向变量的值不可改变,指针值可以改变;const放在之后,指针变量所指向变量的值可以改变,指针值不可以改变;
  • const修饰引用,const放在&之前,不能修改引用所表示的变量的值;const放在&之后,const的作用被忽略,可以修改引用所表示的变量的值。
  • sizeof运算符作用于指针变量得到指针变量自身大小;作用于引用,得到引用所指向的变量的大小。
  • 指针可以有多级,引用只有一级。
  • 指针的自增、自减表示指向下一个同类型变量的地址,一般用于指向数组的指针;引用的自增、自减表示指向变量值的增、减。

3.extern “c”的作用
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示
编译器这部分代码按C语言的进行编译,而不是C++的。
4.深拷贝、浅拷贝、写时拷贝

  • 深拷贝:不仅拷贝指针,对指针指向的内容进行拷贝,深拷贝后两个指针指向两个不同的地址。
  • 浅拷贝:只是对指针的拷贝,拷贝后两个指针指向同一个内存空间。
  • 写时拷贝:内核为新生成的子进程创建虚拟空间结构,来复制于父进程的虚拟地址结构,但不给这段分配物理内存,它们共享父进程的物理空间,当父进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间。
    类似于陪读,陪着学习,但不占学习名额。

5.malloc/new、free/delete各自底层实现原理
在使用的时候 new和delete 搭配使用,malloc 和 free 搭配使用。

  • 属性:
    • malloc/free 是库函数,需要头文件的支持。
    • new/delete 是关键字,需要编译器的支持参数。
    • new 申请空间时,无需指定分配空间的大小,编译器会根据类型自行计算。
    • malloc 在申请空间时,需要确定所申请空间的大小返回值。
    • new 申请空间时,返回的类型是对象的指针类型,无需强制类型转换,符合类型安全的操作符。
    • malloc 申请空间时,返回的是 void* 类型,需要进行强制类型的转换,转换为对象类型的指针。
    • 分配失败:new 分配失败时,会抛出 bad_alloc 异常,malloc 分配失败时返回空指针
  • 重载:new/delete 支持重载,malloc/free 不能进行重载
  • 自定义类型实现:new 首先调用 operator new 函数申请空间(底层通过 malloc 实现),然后调用构造函数进行初始化,最后返回自定义类型的指针;delete 首先调用析构函数,然后调用operator delete 释放空间(底层通过 free 实现)。malloc/free 无法进行自定义类型的对象的构造和析构。
  • 内存区域:new 操作符从自由存储区上为对象动态分配内存,而 malloc 函数从堆上动态分配内存。(自由存储区不等于堆)。
  • ==new类型是安全=的,而malloc不是。

6、数组和链表的区别
数组:

  • 逻辑结构:
    • 数组在内存中连续;
    • 使用数组之前,必须实现固定数组长度,不支持动态改变数组大小;
    • 数组元素增加时,有可能会数组越界;
    • 数组元素减少时,会造成内存浪费;
    • 数组增删时需要移动其他元素
  • 内存结构:数组从栈上分配内存,使用方便,但是自由度小
  • 访问效率:数组在内存中顺序存储,可通过下标访问,访问效率高
  • 越界问题:数组的大小是固定的,所以存在访问越界的风险
    • 使用场景:
    ◦ 空间:数组的存储空间时栈上分配的,存储密度大,当要求存储的大小变化不大时,且可以事
    先确定大小,宜采用数组存储数据
    ◦ 时间:数组访问效率高。当线性表的操作主要是进行查找,很少插入和删除时,宜采用数组结

    链表:
  • 逻辑结构:
    • 链表采用动态内存分配的方式,在内存中不连续
    • 支持动态增加或者删除元素
    • 需要时可以使用malloc或者new来申请内存,不用是使用free或者delete来释放内存
  • 内存结构:链表从对上分配内存,自由度大,但是要注意内存泄漏
  • 访问效率:链表访问效率低,如果想要访问某个元素,需要从头遍历
  • 越界问题:只要可以申请得到链表空间,链表就无越界风险
  • 使用场景:
    • 空间:链表的存储空间是堆上动态申请的,当要求存储的长度变化较大时,且事先无法估量数
      据规模,宜采用链表存储。
    • 时间:链表插入、删除效率高,当线性表要求频繁插入和删除时,宜采用链表结构。

7.野指针和悬空指针的区别

  • 野指针:访问一个已删除或访问受限的内存区域的指针,野指针不能判断是否为NULL来避免。指针没有初始化,释放后没有置空,越界。
  • 悬空指针:一个指针的指向对象已被删除。

8.如何避免野指针

  • 当指针没有做初始化,即没有指向时,将指针指为NULL。一方面可以提醒自己这个指向NULL的指
    针不可操作不可访问,另一方面NULL这个标记便于我们检查和避免野指针;初始化为NULL的目
    的:一是出现段错误时易改错,二是(void *0) 是0地址,是不允许操作,不允许访问的。
  • 当想给指针赋值时,检查是否已经给他分配了内存空间,如果没有分配就再用malloc分配。
  • 给指针分配完内存后,不使用时再利用free()函数清空内存空间(清空原来的缓冲区),并再将指
    针指为NULL。

9.const和define的区别

  • const生效于编译的阶段;define生效于预处理阶段。
  • const定义的常量,在C语言中是存储在内存中、需要额外的内存空间的;define定义的常量,运行时是直接的操作数,并不会存放在内存中。
  • const定义的常量是带类型的;define定义的常量不带类型。
    28、左值引用和右值引用的区别
    可以取地址的,有名字的,非临时的就是左值;
    不能取地址的,没有名字的,临时的就是右值;
    可见立即数,函数返回的值等都是右值;而非匿名对象(包括变量),函数返回的引用,const对象等都是左值。
    在汇编层面右值引用做的事情和常引用是相同的,即产生临时量来存储常量。但是,唯一 一点的区别是,右值引用可以进行读写操作,而常引用只能进行读操作。
    右值引用的存在并不是为了取代左值引用,而是充分利用右值(特别是临时对象)的构造来减少对象构造和析构操作以达到提高效率的目的
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

君莫笑lucky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值