sizeof 运算符的实现

2024-11-08 09:04:00
admin
原创
187
摘要:问题描述:我尝试实现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;
}
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用