【C++】面试题整理(未完待续)

embedded/2025/1/21 4:04:42/

【C++】面试题整理

文章目录

    • 一、概述
    • 二、C++基础
      • 2.1 - 指针在 32 位和 64 位系统中的长度
      • 2.2 - 数组和指针
      • 2.3 - 结构体对齐补齐
      • 2.4 - 头文件包含
      • 2.5 - 堆和栈的区别
      • 2.6 - 宏函数比较两个数值的大小
      • 2.7 - 冒泡排序
      • 2.8 - 菱形继承的内存布局
      • 2.9 - 继承重写
      • 2.10 - 如何禁止类在栈上分配内存
    • 三、智能指针
      • 3.1 - 智能指针是线程安全的吗?
      • 3.2 - 线程安全的几种方法
    • 四、 STL
      • 4.1 - map 删除
    • 五、参考

一、概述

最近面试,感觉有些比较基础的好久不用就有些生疏了,整理一下。

【备注】:题目的答案是个人整理的不能保证是标准答案。

二、C++基础

2.1 - 指针在 32 位和 64 位系统中的长度

4 字节和 8 字节

32/8 = 4
64/8 = 8

2.2 - 数组和指针

以下代码在 32 位和 64 位系统中分别打印什么?

char a[] = "123456789";
const char* b = "123456789";
std::cout << sizeof(a) << std::endl;
std::cout << sizeof(b) << std::endl;
  • 32位打印: 10 和 4
  • 64位打印: 10 和 8

指针已经在第一题中说过了,就不重复了。char 数组的大小需要加上最后的 \0

2.3 - 结构体对齐补齐

在 32 位和 64 位系统中分别是多少

struct M
{int a;double b;
};printf("%d", sizeof(struct M));

答案: 均为16,这里是结构体的对齐补齐,与系统位数无关。

2.4 - 头文件包含

两种包含头文件的区别

#include <stdio.h>
#include "stdio.h"
  • 尖括号,编译器会从系统目录中查找;
  • 双引号,编译器会首先从当前项目目录查找,找不到再去系统目录中查找。

虽然#include"“的查找范围更广,但是这并不意味着,不论是系统头文件,还是自定义头文件,一律用#include”“包含。因为#include”"的查找顺序存在先后关系,如果项目当前目录或者引用目录下存在和系统目录下重名的头文件,那么编译器在当前目录或者引用目录查找成功后,将不会继续查找,所以存在头文件覆盖的问题。另外,对于系统头文件,用#include<>包含,查找时一步到位,程序编译时的效率也会相对更高。

2.5 - 堆和栈的区别

  • 堆(heap): 向上增长内存,存储动态分配的内存,需要程序员自己管理,分配和释放。
  • 栈(stack): 向下增长内存,存储静态分配的内存,系统会自动释放。

2.6 - 宏函数比较两个数值的大小

要求不使用大于、小于和if

#define MAX(a,b) (int)((a)/(b)) == 0 ? (a) : (b);

定义宏函数需要注意,入参需要使用小括号括起来,避免传入算式导致预期外的计算

MAX(4-1,5); 
// 不加小括号 4 - 1/5 = 3 返回3 值错误。
// 加小括号 (4-1)/(5) = 0, 返回值为 5。

2.7 - 冒泡排序

void bubbleSort(int arr*, int n)
{for (int i = 0; i < n - 1; ++i){for (int j = 0; j < n - i - 1; ++j){if (arr[j] > arr[j+1]){int tmp = arr[j];arr[j] = arr[j+1];arr[j+1] = arr[j];}}}
}

如果我是面试官,我会在这里考一个打印 arr 的 sizeof ,因为 数组在传参时会退化为指针。

2.8 - 菱形继承的内存布局

class A
{
public:int a;
};class B : public A
{
public:int b;
};class C : public A
{
public:int c;
};class D : public B, public C
{
public:int d;
};

可以看到 A 中的内容被重复记录了两次

若改为虚继承,虚继承是为了解决冗余和二义性

class B : virtual public A {/*...*/};
class C : virtual public A {/*...*/};

在这里插入图片描述
则会出现一个虚基表指针 vbptr (virtual base pointer) 记录偏移

VS Developer Command Prompt 查看内存布局方法
cl /d1 reportSingleClassLayoutD filename.cpp

2.9 - 继承重写

实现一个 Shape 类,定义纯虚函数 area,定义 Rectangle 和 Circle 类继承 Shape 类,在main函数中打印面积。

class Shape
{
public:virtual double area() = 0;
};class Rectangle : public Shape
{
public: Rectangle(double width, double length):m_width(width), m_length(length) {}virtual double area() override{return m_width*m_length;}
private:double m_width {0.0};double m_length {0.0};	
};
#define PI 3.1415926
class Circle  : public Shape
{
public:Circle(double radius): m_radius(radius){}virtual double area() override{return PI * m_radius * m_radius}
private:double m_radius{0.0};	
};

调用

#include <iostream>
int main(int argc, char* argv[])
{Rectangle rect(3.0, 4.0);Circle c(2.0);std::cout << rect.area() << std::endl;std::cout << c.area() << std::endl;
}

2.10 - 如何禁止类在栈上分配内存

其实只要禁用 析构就可以在编译时报错,但是为了方便继承和使用

class A 
{
public:static A* Create(){ return new A();}void Destroy() { delete this;} // 不能为 static,因为静态函数中无 this 指针
protected:~A() {};A() {};A(const A& rhs) {/*...*/};A(const A&& rhs) {/*...*/};const A& operator=(const A& rhs) {/*...*/};const A& operator=(const A&& rhs) {/*...*/};
};

三、智能指针

3.1 - 智能指针是线程安全的吗?

不是,虽然引用计数是原子操作,但还有其他的操作

3.2 - 线程安全的几种方法

  • 加锁
  • 原子变量 std::atomic

四、 STL

4.1 - map 删除

改错。

using std::map;
using std::string;
int main(int argc, char* argv[])
{map<string, string> mapData;mapData["a"] = "aaa"; mapData["b"] = "bbb"; mapData["c"] = "ccc"; for (map<string, string>::iterator i=mapData.begin(); i!=mapData.end(); i++){if (i->first == "b"){mapData.erase(i);}}return 0;
}

错误是容器删除元素会有迭代器失效,网上给的改错方式是,将for循环 i++ 删除 加到函数中

for (map<string, string>::iterator i=mapData.begin(); i!=mapData.end(); /*i++*/)
{if (i->first == "b"){mapData.erase(i++);}else{i++;}
}

个人感觉这样也可以

for (map<string, string>::iterator i=mapData.begin(); i!=mapData.end();++i)
{if (i->first == "b"){i = mapData.erase(i);--i;}  
}

五、参考

  • https://blog.csdn.net/rammuschow/article/details/107947302 include
  • https://en.cppreference.com/w/cpp/container/map/erase std::map erase 函数
  • https://blog.csdn.net/AgoniAngel/article/details/105893798 菱形继承内存分布

http://www.ppmy.cn/embedded/155667.html

相关文章

Redis 中 TTL 的基本知识与禁用缓存键的实现策略(Java)

目录 前言1. 基本知识2. Java代码 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 单纯学习Redis可以看我前言的Java基本知识路线&#xff01;&#xff01; 对于Java的基本知识推荐阅读&#xff1a; java框架…

PiliPalaX ( 第三方安卓哔哩哔哩)

PiliPalaX 是一款哔哩哔哩第三方客户端。使用 Flutter 开发&#xff0c;基于PiliPala原版基础上创作出来的X升级版&#xff0c;目前支持Android、IOS客户端。 应用特色 目前着重移动端(Android、iOS)和Pad端&#xff0c;暂时没有适配桌面端、手表端等 https://pan.quark.cn/s/…

第九章:演示文稿软件PPT

文章目录&#xff1a; 一&#xff1a;界面 1.介绍 2.选项卡 2.1 开始 2.2 插入 2.3 设计 2.4 切换 2.5 动画 2.6 放映 2.7 审阅 2.8 视图 2.9 音频工具 2.10 视频工具 二&#xff1a;基础 三&#xff1a;设计 1.静态 2.动态 四&#xff1a;放映 一&#xff1…

软考信安22~网站安全需求分析与安全保护工程

1、网站安全威胁与需求分析 1.1、网站安全概念 网站安全主要是有关网站的机密性、完整性、可用性及可控性。 网站的机密性是指网站信息及相关数据不被授权查看或泄露。 网站的完整性是指网站的信息及数据不能非授权修改,网站服务不被劫持。 网站的可用性是指网站可以待续…

基于 Spring Boot、Vue 实现的调问开源问卷系统

是一款简单、高效、成熟、稳定、专业的开源问卷系统&#xff0c;自2012年启动至今经过9年的积累&#xff0c;已经形成一套完善的基于 JAVA WEB 的开源问卷表单解决方案。 &#x1f389;&#x1f389;&#x1f389; 企业版 全新的 企业版 已经发布&#xff0c;前后端分别采用 …

PyTorch 神经协同过滤 (NCF) 推荐系统教程

目录 教程概述1. 神经协同过滤模型概述NCF 模型的主要组成部分&#xff1a; 2. 数据加载与预处理3. 定义神经协同过滤模型4. 训练模型5. 模型评估6. 推荐物品7. 完整示例8. 总结 在本教程中&#xff0c;我们将使用 PyTorch 实现一个神经协同过滤&#xff08;Neural Collaborat…

NavVis手持激光扫描帮助舍弗勒快速打造“数字孪生”工厂-沪敖3D

在全球拥有近100家工厂的舍弗勒&#xff0c;从2016年开启数字化运营进程&#xff0c;而当前制造、库存、劳动力和物流的数字化&#xff0c;已无法支持其进一步简化工作流程&#xff0c;亟需数字化物理制造环境&#xff0c;打造“数字孪生”工厂。 NavVis为其提供NavVis VLX 3…

计算机网络 (45)动态主机配置协议DHCP

前言 计算机网络中的动态主机配置协议&#xff08;DHCP&#xff0c;Dynamic Host Configuration Protocol&#xff09;是一种网络管理协议&#xff0c;主要用于自动分配IP地址和其他网络配置参数给连接到网络的设备。 一、基本概念 定义&#xff1a;DHCP是一种网络协议&#xf…