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

news2024/10/19 3:25:26

笔者最近在找工作时,无意间读到了一本名为《剑指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;  // 4
    cout << sizeof(double) << endl;  // 8
    cout << sizeof(long) << endl;  // 8
    cout << sizeof(str1) << endl;  // 10
    cout << sizeof(str2) << endl;  // 8
    cout << sizeof(num1) << endl;  // 40
    cout << sizeof(num2) << endl;  // 8
    cout << sizeof(nullptr) << endl;  // 8
    cout << sizeof(MyClass1) << endl;  // 1
    cout << sizeof(MyClass2) << endl;  // 1
    cout << 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.coloradmin.cn/o/2218197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

当我们修复测试用例时,到底是修复的什么?

当我们运行了测试用例&#xff0c;发现其中一些测试用例未能通过。ok&#xff0c;这下要修复测试用例了&#xff01;但是&#xff0c;到底需要修复哪些内容呢&#xff1f; 其实从用例被加载到最终执行的过程中&#xff0c;有很多因素可能导致测试失败&#xff1a; 在测试构建过…

C语言中的文件操作:从基础到深入底层原理

文件操作是几乎所有应用程序的重要组成部分&#xff0c;特别是在系统级编程中。C语言因其高效、灵活以及接近硬件的特点&#xff0c;成为了文件操作的理想选择。本文将全面深入地探讨C语言中的文件操作&#xff0c;从文件系统的概念到具体的文件操作函数&#xff0c;再到底层的…

生成器和迭代器

迭代器 定义 迭代器是一个实现了选代协议的对象&#xff0c;它可以让我们遍历一个容器中的所有元素&#xff0c;而不需要知道容器的内部结构&#xff0c;迭代器可以被用于遍历列表、元组、字典、集合等容器类型。 工作原理 __iter__():方法返回迭代器对象本身&#xff0c;有…

《15分钟轻松学Go》教程目录

在AI快速发展的时代&#xff0c;学习Go语言依然很有用。Go语言擅长处理高并发任务&#xff0c;也就是说可以同时处理很多请求&#xff0c;这对于需要快速响应的AI服务非常重要。另外&#xff0c;Go适合用来处理和传输大量数据&#xff0c;非常适合机器学习模型的数据预处理。 …

leetcode动态规划(一)-理论基础

本节主要参考&#xff1a;代码随想录 题目分类 动态规划释义 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 动态规划中每一个状态一定是由上一个状态推导出来…

WinX86内核02-驱动程序

把昨天的程序改用 c++ 编译,改成 .cpp ,发现编译报错 原因是名称粉碎,因此可以直接 extern “C”声明一下这个函数 或者用 头文件(推荐) 因为 在头文件中 可以把 头文件一起包含进去 #pragma once extern "C" { #include <Ntddk.h> ​ /*驱动入口函…

一文搞懂模型倍率怎么计算的,以及模型分组倍率原理!

&#x1f4cd; 已知&#xff1a; ① 输入token&#xff1a;又名 提示、Input token 数 ② 输出token&#xff1a;又名 补全、Output token 数 &#x1f4cd; 基准价格【最初 gpt3.5 的价格&#xff0c;所以倍率越大&#xff0c;越聪明越贵&#xff0c;倍率越小越省钱越笨】 on…

秋招面试题记录

嵌入式软件开发 网上搜集的题目 1.Static关键词的作用&#xff1f; static 关键字有三个主要作用&#xff1a; 局部变量&#xff1a;在函数内部&#xff0c;static 局部变量只初始化一次&#xff0c;且在函数调用结束后仍然保留其值。全局变量/函数&#xff1a;在文件内部&a…

产品自问:前台和中后台

产品自问&#xff1a;前台和中后台 叮嘟&#xff01;这里是小啊呜的学习课程资料整理。好记性不如烂笔头&#xff0c;今天也是努力进步的一天。一起加油进阶吧&#xff01; 前台和中后台通常根据以下几个方面进行区分&#xff1a; 一、功能定位 前台&#xff1a;主要面向外部…

redo文件误删除后通过逻辑备份进行恢复

问题描述 开发同事让在一个服务器上查找下先前库的备份文件是否存在&#xff0c;如果存在进行下恢复。翻了服务器发现备份文件存在&#xff0c;多愁了一眼竟翻到了该备份文件于2024.6.17日恢复过的日志&#xff0c;赶紧和开发沟通说2024.6.17号已经恢复过了为啥还要恢复&#x…

【Linux】Anaconda下载安装配置Pytorch安装配置(保姆级)

目录 Anaconda下载 Anaconda安装 conda init conda --v Conda 配置 conda 环境创建 conda info --envs conda list Pytorch安装配置 检验安装情况 检验是否可以使用GPU Anaconda下载 可以通过两种途径完成Anaconda安装包的下载 途径一&#xff1a;本地windows下…

了解静态存储方式和动态存储方式的区别(超详细讲解)快来看

本篇通过一个代码题来考察静态变量和动态变量的区别&#xff0c;主要考察静态变量的值。 在前2章我们讲了变量可以分为全局变量和局部变量&#xff0c;而我们的变量&#xff0c;它的存储又有两种不同的方式:静态存储方式与动态存储方式。 自动局部变量:auto 静态局部变量:stati…

emwin的异常显示和父子坐标问题(瞎写的,别看 -- 2)

文章目录 4&#xff0c;想显示成 最后的demo 仿真器中 1&#xff0c;格子状显示 把下面这句注释掉&#xff0c;就可能会这么显示 WM_SetCreateFlags(WM_CF_MEMDEV);2&#xff0c;显示一副灰度图 很有可能你是这么写的 也就是 hMemDev GUI_MEMDEV_CreateFixed(0, 0, 200, …

Redis-02 单线程与高性能

Redis是单线程吗&#xff1f; Redis不是只有一个线程&#xff0c;通常所说Redis 的单线程主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的&#xff0c;这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能&#xff0c;比如持久化、异步删除、集群数…

BGP(边界网关协议)

1、网络AS&#xff08;自治系统&#xff09; 边界网关协议BGP&#xff08;Border Gateway Protocol&#xff09;是一种实现自治系统AS&#xff08;Autonomous System&#xff09;之间的路由可达&#xff0c;并选择最佳路由的距离矢量路由协议。 AS是指在一个实体管辖下的拥有…

【c++并发编程】线程池实现

参考https://shanhai.huawei.com/#/page-forum/post-details?postId43796 完整代码 #include <iostream> #include <vector> #include <queue> #include <thread> #include <mutex> #include <condition_variable> #include <functi…

牛企查:性价比很高的企业综合查询小程序

很多人都会有查询企业信息的需求&#xff1a; 入职公司前查询企业的基本信息&#xff1b; 只是需要简单便捷查询到企业的信用代码注册地址等基础信息&#xff1b; 做企业调查&#xff0c;分析时需要用到企业的一些数据&#xff1b; 研究一些单项数据的时候&#xff0c;需要…

拟声 0.37.0 | 拟物风格,超级优美,功能丰富

拟声是一款功能丰富的音视频播放器&#xff0c;支持多种音频来源&#xff0c;并具备独特的歌词弹幕、音源转换、跨设备共享与控制等功能。其创新的LRC歌词编解码器和新拟物风格的UI设计为用户提供了一个全新的视听体验。 大小&#xff1a;36M 百度网盘&#xff1a;https://pan…

代码审计-Python Flask

1.Jinjia2模版注入 Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug &#xff0c;模板引擎则使用 Jinja2。jinja2是Flask作者开发的一个模板系统&#xff0c;起初是仿django模板的一个模板引擎&#xff0c;为Flask提供模板支持&#xff0c;由于…

ubuntu下安装mysql遇到的问题

ubuntu下安装mysql sudo apt install -y mysql-server 出现问题 ……by process 3455 解决 安装 启动 systemctl status mysql.service sudo mysql -u root -p 如何修改密码 与datagrip的连接 查看IP ifconfig 若没安装 参考 Windows10的DataGrip2024.1.4连接ubuntu22.04中的M…