面试题:手动实现一个sizeof

news/2024/12/22 23:44:59/

面试题:手动实现一个sizeof

前几天在网上看到这样一个面试题,好像是腾讯的。

就是手动实现一个sizeof操作符,实际上面试官想要的考点应该是通过偏移量来实现检测sizeof的功能。即使明白这个考点,如果没有准备的话实现起来也是不是特别容易的。简单概括就是定义一个结构体,将要计算的类型放入结构体中,通过结构体指针的偏移量来确定。

#include <stdio.h>#define my_sizeof(type) ((size_t)(&((struct {char c; type t; }*)0)->t))int main() {printf("Size of char: %zu\n", my_sizeof(char));printf("Size of int: %zu\n", my_sizeof(int));printf("Size of double: %zu\n", my_sizeof(double));// 对于数组,我们直接计算类型的大小再乘以元素数量printf("Size of int[10]: %zu\n", my_sizeof(int) * 10);return 0;
}

让我们来具体解释一下:

  1. 定义匿名结构体:
    • struct {char c; type t; } 定义了一个匿名结构体,它包含两个成员:一个 char 类型的成员 c 和一个 type 类型的成员 t
  2. 将空指针转换为结构体指针:
    • (struct {char c; type t; }*)0 将空指针 0 转换为指向该匿名结构体的指针,因为我们需要通过指针访问成员来得到偏移量。
  3. 访问结构体成员 t 的地址:
    • ((struct {char c; type t; }*)0)->t 通过指针访问结构体成员 t 的地址。
    • 由于 cchar 类型,占用1字节,所以 t 的地址实际上是 type 类型在结构体中的偏移量。因为内存对齐的原则,c的类型需要是最小的,这样不管type是什么类型,c占用的内存大小与type类型相同,因而偏移量就是type类型的大小。
  4. 计算偏移量:
    • &((struct {char c; type t; }*)0)->t 获取成员 t 的地址偏移量,这个偏移量就是 type 类型的大小。
    • 由于 c 的大小固定为1字节,所以 t 的地址就是 type 的大小。
  5. 转换为 size_t 类型:
    • 最后将偏移量转换为 size_t 类型,即 ((size_t)(&((struct {char c; type t; }*)0)->t))

不过,需要注意的是,这种方法是纯粹依靠编译器和平台的内存布局来确定的,对于某些复杂类型如结构体和联合体等,这种方法可能并不适应。但仅仅作为面试的一个考点应该是够, 想要面试的时候不仅能够快速想到这个考点而且能够短时间内手动实现代码,平时要多看、多思考并且多写。

最后给大家推荐一个LinuxC/C++高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习C/C++后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04uB


http://www.ppmy.cn/news/1466297.html

相关文章

配置 HTTP 代理 (HTTP proxy)

配置 HTTP 代理 [HTTP proxy] 1. Proxies2. curl2.1. Environment2.2. Proxy protocol prefixes 3. Use an HTTP proxy (使用 HTTP 代理)3.1. Using the examples (使用示例)3.1.1. Linux or macOS3.1.2. Windows Command Prompt 3.2. Authenticating to a proxy (向代理进行身…

小米路由器如何设置去广告功能,如何设置小米路由器的自定义Hosts(小米路由器如何去除小米广告、去除小米电视盒子开屏广告、视频广告)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 实现方案 📒📝 操作步骤📝 注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 小米设备的广告一直是用户头疼的问题,无论是开屏广告、应用内广告还是系统广告,都影响了用户体验。本文将详细介绍如何通过小米路由器实现去除广告…

Axios的使用简单说明

axios 请求方式和参数 axios 可以发送 ajax 请求&#xff0c;不同的方法可以发送不同的请求: axios.get&#xff1a;发送get请求 axios.post&#xff1a;发送post请求 axios.put&#xff1a;发送put请求 axios.delete&#xff1a;发送delete请求 无论哪种方法&#xff0c;第一…

一篇学习Java Object的常见方法

一、getClass public final native Class<?> getClass() 意义&#xff1a;返回此Object运行时的类作用&#xff1a;常用于反射和类型检查使用场景&#xff1a;当需要知道一个对象的实际类型时&#xff0c;可以使用。 public class GetClassExample {public static void …

如何从0到设计一个CRM系统

什么是CRM 设计开始之前&#xff0c;先来了解一下什么是CRM。CRM&#xff08;Customer Relationship Management&#xff09;是指通过建立和维护与客户的良好关系&#xff0c;达到满足客户需求、提高客户满意度、增加业务收入的一种管理方法和策略。CRM涉及到跟踪和管理客户的所…

YOLOv1深入解析与实战:目标检测算法原理

参考&#xff1a; https://zhuanlan.zhihu.com/p/667046384 https://blog.csdn.net/weixin_41424926/article/details/105383064 https://arxiv.org/pdf/1506.02640 1. 算法介绍 学习目标检测算法&#xff0c;yolov1是必看内容&#xff0c;不同于生成模型&#xff0c;没有特别…

【Linux-LCD 驱动】

Linux-LCD 驱动 ■ Framebuffer 简称 fb■ LCD 驱动程序编写■ 1、LCD 屏幕 IO 配置■ 2、LCD 屏幕参数节点信息修改■ 3、LCD 屏幕背光节点信息■ 4、使能 Linux logo 显示 ■ 设置 LCD 作为终端控制台■ 1、设置 uboot 中的 bootargs■ 2、修改/etc/inittab 文件 ■ LCD 背光…

Maven常见生命周期阶段的作用

文章目录 一、生命周期阶段1.clean2.compile3.test4.package5.verify6.install7.site8.deploy 二、compile、package、install的区别1.compile阶段&#xff1a;2.package阶段&#xff1a;3.install阶段&#xff1a;4.compile和package的区别5.package和install的区别 一、生命周…