sizeof 运算符的实现

2024-11-08 09:04:00
admin
原创
26
摘要:问题描述:我尝试实现sizeof运算符。 我这样做了:#define my_sizeof(x) ((&x + 1) - &x) 但对于任一数据类型,它最终总是给出结果“1”。然后我用谷歌搜索了一下,找到了以下代码:#define my_size(x) ((char *)(&x + 1)...

问题描述:

我尝试实现sizeof运算符。 我这样做了:

#define my_sizeof(x) ((&x + 1) - &x)

但对于任一数据类型,它最终总是给出结果“1”。

然后我用谷歌搜索了一下,找到了以下代码:

#define my_size(x) ((char *)(&x + 1) - (char *)&x)

如果进行了类型转换,代码就可以正常工作,我不明白为什么。此代码还可以完美地填充结构。

它还适用于:

#define my_sizeof(x) (unsigned int)(&x + 1) - (unsigned int)(&x)

有人可以解释一下类型转换后它是如何工作的吗?


解决方案 1:

指针减法的结果以元素为单位,而不是以字节为单位。因此,根据定义,第一个表达式的计算结果为1

除此之外,你真的应该在宏中使用括号:

#define my_sizeof(x) ((&x + 1) - &x)
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)

my_sizeof()否则尝试在表达式中使用可能会导致错误。

解决方案 2:

#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)

my_sizeof()宏在下列情况下不起作用:

  1. sizeof 1- 4 字节(对于具有 4 字节的平台int

my_sizeof(1)- 根本无法编译。

  1. sizeof (int)- 4 字节(对于具有 4 字节的平台int

my_sizeof(int)- 根本无法编译代码。

它只适用于变量。它不适用于诸如intfloat等数据类型char,诸如、、等文字2,也不适用于诸如或之类的右值表达式3.4'A'`a+b`foo()

解决方案 3:

#define my_sizeof(x) ((&x + 1) - &x)

&x给出程序中声明的变量(假设为 double x)的地址,并将其加 1 给出可以存储类型 x 的下一个变量的地址(此处addr_of(x) + 8,double 的大小为 8Byte)。

差异得出的结果是,x在该内存量中可以存储多少个类型的变量,对于类型 x 来说,这个结果显然是 1(因为将其增加 1 并取差值就是我们所做的)。

#define my_size(x) ((char *)(&x + 1) - (char *)&x)

将其类型转换为char*并取差值将告诉我们char在给定的内存空间中可以存储多少个类型的变量(差值)。由于每个char变量仅需要 1 个字节的内存,因此 (内存量)/1 将给出传递给宏的变量类型的两个连续内存位置之间的字节数,从而给出类型变量所需的内存量x

但是您无法将任何文字传递给该宏并知道它们的大小。

解决方案 4:

sizeof运算符是 C(和 C++)语言规范的一部分,并在编译器(前端)内部实现。无法使用其他 C 构造来实现它(除非您使用 GCC 扩展,如typeof),因为它可以接受类型或表达式作为操作数,而不会产生任何副作用(例如sizeof((i>1)?i:(1/i)),当除以零时不会崩溃,i==0但您的宏my_sizeof会因除以零而崩溃)。另请参阅C 编码指南和维基百科。

您应该了解 C指针算法。例如,请参阅这个问题。指针差异以元素而不是字节表示。

解决方案 5:

但对于任何一种数据类型,它的结果总是为“1”

是的,这就是指针算法的工作原理。它以指向的类型为单位工作。因此,强制转换为以 为char *单位工作char,这正是您想要的。

解决方案 6:

这对于文字和变量都有效。

#define my_sizeof(x) (char*) (&(((__typeof__(x) *)0)[1])) - (char *)(&(((__typeof__(x) *)0)[0]))

解决方案 7:

#define my_sizeof(x) ((&x + 1) - &x)
  • 这基本上是(两个内存值的差异)/(数据类型的大小)。

  • 它给出可以存储多少个 x 类型元素的数字。即 1。您可以在此内存空间中容纳一个完整的 x 元素。

  • 当我们将其转换为其他数据类型时,它表示该内存空间中可以存储多少个该数据类型的元素。

#define my_size(x) ((char *)(&x + 1) - (char *)&x)
  • 将其类型转换为 (char *) 可以为您提供准确的内存字节数,因为 char 是一个字节。

#define my_sizeof(x) (unsigned int)(&x + 1) - (unsigned int)(&x)
  • 当您将指针类型转换为 int 时,它会导致编译错误。

解决方案 8:

#define MY_SIZEOF(type) (unsigned int)( (type*)0 + 1)

将 NULL(0) ptr 转换为类型,然后加一。由于指针算法,编译器会根据类型增加大小。然后将其转换回无符号整数,因为我们想要表示大小。

还:

#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)

依赖于正在定义的类型的变量。

来源:discord 上的 @Neo21。我的只是将其转换为unsigned int

解决方案 9:

我昨天搜索了这一点,发现了这个宏:

#define mysizeof(X)  ((X*)0+1)

它仅扩展 X 一次(没有像 x++ 这样的表达式双重评估那样的错误),并且到目前为止运行良好。

解决方案 10:

定义 my_sizeof(x) ((&x + 1) - &x)

&x 给出变量的地址,将其加一 (&x + 1) 将给出可以存储另一个类型 x 的变量的地址。现在,如果我们对这些地址进行算术运算,如 ((&x + 1) - &x),那么它将告诉我们,在 ((&x + 1) - &x) 地址范围内可以存储 1 个类型 x 的变量。

现在,如果我们用 (char ) 对该内存量进行类型转换 [因为 char 的大小为 1 个字节,而增加 char 只会移动一个字节],那么我们将得到类型 x 所消耗的字节数

解决方案 11:

#include<bits/stdc++.h>

using namespace std;
//#define mySizeOf(T) (char*)(&T + 1) - (char*)(&T)

        template<class T>
size_t mySizeOf(T)
{
        T temp1;
        return (char*)(&temp1 + 1) - (char*)(&temp1);
}
int main()
{
        int num = 5;
        long numl = 10;
        long long numll = 100;
        unsigned int num_un_sz = 500;

        cout<<"size of int="<<mySizeOf(num) << endl;
        cout<<"size of long="<<mySizeOf(numl) << endl;
        cout<<"size of long long ="<<mySizeOf(numll) << endl;
        cout<<"size of unsigned int="<<mySizeOf(num_un_sz) << endl;
        return 0;
}
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用