当前位置: 首页 > news >正文

C++之《剑指offer》学习记录(2):sizeof

笔者最近在找工作时,无意间读到了一本名为《剑指offer》的书,粗略翻阅了一下,感觉这将会是一本能让我不再苦恼于笔试和面试“手搓代码”的书。故笔者写下该系列博客记录自己的学习历程,希望能和这本书的读者朋友们一起交流学习心得。
介绍:《剑指Offer:名企面试官精讲典型编程题(第2版)》剖析了80个典型的编程面试题,系统整理基础知识、代码质量、解题思路、优化效率和综合能力这5个面试要点。
编程题链接:牛客网在线编程_算法面试_面试必刷TOP101 (nowcoder.com)
本博客关键词:sizeof

介绍

  1. 在C/C++中,sizeof是一个关键字,也是一个运算符,用来获取类型或对象在内存中所占的字节大小。
  2. sizeof不是函数,在代码的编译阶段就会执行
  3. sizeof计算内存占用大小的应用场景:基本数据类型、数组、结构体、类、指针、枚举、联合体等。

引入

先阅读一下代码,预测下cout对应的输出都会是什么?(假设代码在64位机器上运行)

#include <iostream>using namespace std;// 空类型
class MyClass1
{
};// 添加了构造函数和析构函数的空类型
class MyClass2
{MyClass2();~MyClass2();
};// 析构函数为虚函数的空类型
class MyClass3
{MyClass3();virtual ~MyClass3();
};int main(int argc, char const *argv[])
{char str1[10] = "hello";const char *str2 = "hello world";int num1[10];int *num2 = new int[10];cout << sizeof(int) << endl;cout << sizeof(double) << endl;cout << sizeof(long) << endl;cout << sizeof(str1) << endl;cout << sizeof(str2) << endl;cout << sizeof(num1) << endl;cout << sizeof(num2) << endl;cout << sizeof(NULL) << endl;cout << sizeof(MyClass1) << endl;cout << sizeof(MyClass2) << endl;cout << sizeof(MyClass3) << endl;return 0;
}

结果如下:

    cout << sizeof(int) << endl;  // 4cout << sizeof(double) << endl;  // 8cout << sizeof(long) << endl;  // 8cout << sizeof(str1) << endl;  // 10cout << sizeof(str2) << endl;  // 8cout << sizeof(num1) << endl;  // 40cout << sizeof(num2) << endl;  // 8cout << sizeof(nullptr) << endl;  // 8cout << sizeof(MyClass1) << endl;  // 1cout << sizeof(MyClass2) << endl;  // 1cout << sizeof(MyClass3) << endl;  // 8

分析

  1. sizeof(int)这个输出为4很好理解,int类型占用4个字节的内存。
  2. sizeof(double)输出为8,也很好理解,double类型占用8个字节的内存。
  3. sizeof(long)输出为8。在32位机器中,long占4个字节,在64位机器中long占8个字节。
  4. sizeof(str1)输出为10,str1对应了数组str1[10]
  5. sizeof(str2)输出为8,str2对应一个指针。这里大家第一次看可能会有疑问,明明有”数组名称代表数组首元素地址“的说法,为什么sizeof(str1)sizeof(str2)的输出结果不一样呢?我是这样理解的:首先str2在这里确实是一个指针,所以sizeof(str2)对应的值是8,这是很好理解的;但是对于数组str1[10],str1本质上只是数组名,它并不占用任何的内存,它代表的是数组,它可以表示数组首元素的地址,但实际上数组首元素的地址是str1[0]对应的地址,str1数组名不占用实际内存。当使用sizeof运算符通过数组名计算数组内存占用时,数组名表示的是整个数组,而不是某个地址。
  6. 根据第5点的解释,很容易可以得出sizeof(num1)的输出为40,sizeof(num2)的输出为8。
  7. sizeof(nullptr)输出为8,关键字 nullptr 表示空指针。

接下来就是对sizeof(MyClass)的分析,也是书里提到的一个案例。

  1. 提问:定义一个空类型,里面没有任何成员变量和成员函数,对该类型求sizeof,结果是多少?
  2. 答案:空类型的示例中不包含任何信息,但是在声明该类型的实例时,必须在内存中有一定的空间,否则无法使用这些实例。至少占用多少字节的内存,由编译器决定,在GCC中,每个空类型的实例占用1字节。
  3. 提问:如果在空类型中加入一个构造函数和一个析构函数,再求sizeof,结果是多少?
  4. 答案:仍然是1,调用构造函数和析构函数只需要知道函数的地址即可,而函数的地址只与类型相关,编译器因为这两个函数而在实力内添加任何额外的信息。
  5. 提问:如果将析构函数标记为虚函数呢?
  6. 答案:在32位机器中输出为4,在64位机器中输出为8。因为C++编译器一旦发现类型中有虚函数,就会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针
    空类型如下:
// 空类型
class MyClass1{};

加了构造函数和析构函数:函数内容也为空

// 添加了构造函数和析构函数的空类型
class MyClass2
{MyClass2();~MyClass2();
};

将析构函数标记为虚函数:

// 析构函数为虚函数的空类型
class MyClass3
{MyClass3();virtual ~MyClass3();
};
http://www.lryc.cn/news/465813.html

相关文章:

  • linux线程 | 同步与互斥 | 线程池以及知识点补充
  • ArkTS 如何实现表单,地区选择效果
  • Vite 项目的核心配置- vite.config.ts 和 tsconfig.json 全解析
  • 如何使用JMeter进行性能测试的保姆级教程
  • Qt 实战(11)样式表 | 11.1、样式表简介
  • WebGl 多缓冲区和数据偏移
  • 基于SSM的甜品店销售管理系统
  • Spacetime Gaussian Feature Splatting for Real-Time Dynamic View Synthesis
  • PCL 基于FPFH特征描述子获取点云对应关系
  • 项目实战:Qt+OpenCV仿射变换工具v1.1.0(支持打开图片、输出棋盘角点、调整偏移点、导出变换后的图等等)
  • OpenCV坐标系统与图像处理案例
  • Unity之如何使用Unity Cloud Build云构建
  • Halcon开启多线程
  • Echarts 点击事件无法使用 this 或者 this绑定的数据无法获取
  • PCL 基于距离阈值去除错误对应关系(永久免费版)
  • DirectX 11 和 Direct3D 11 的关系
  • 什么是SCRM?为什么企业要做SCRM?
  • 类间方差,分割地物
  • 基于微博评论的自然语言处理情感分析
  • MFEM( Modular Finite Element Methods)是一个灵活的、可扩展的、开源的有限元库
  • 在VMware上创建虚拟机以及安装Linux操作系统,使用ssh进行远程连接VMware安装注意点 (包含 v1,v8两张网卡如果没有的解决办法)
  • 关于vue3中如何实现多个v-model的自定义组件
  • 【STM32项目_2_基于STM32的宠物喂食系统】
  • 商场楼宇室内导航系统
  • 2025全网最全计算机毕业设计选题推荐:计算机毕设选题指导及避坑指南√
  • Vision China 2024 | 移远通信以一体化的AI训练及部署能力,引领3C电子制造智能升级
  • 浏览器播放rtsp视频流解决方案
  • Ubuntu下查看指定文件大小
  • 【南开X上海交大】OPUS:效率显著提升的OCC网络
  • SqlUtils 使用