不使用sizeof的数据类型的大小

问题描述 投票:19回答:21

我有一个数据类型,比如X,我想知道它的大小而不声明该类型的变量或指针,当然不使用sizeof运算符。

这可能吗?我想过使用标准头文件,其中包含数据类型的大小和范围,但不适用于用户定义的数据类型。

c sizeof
21个回答
43
投票

在我看来,这符合“如何在不使用++,+ =或+?”的情况下添加两个整数的类别。这是浪费时间。你可以尝试通过做这样的事情来避免未定义行为的怪物。

size_t size = (size_t)(1 + ((X*)0));

请注意,我没有声明类型的变量或指向X的指针。


1
投票

试试这个:

 #include<stdio.h>

int main(){

  int *ptr = 0;

  ptr++;
  printf("Size of int:  %d",ptr);

  return 0;

1
投票

自用户代码中的C89解决方案可用:

  1. 不声明X类型的变量。
  2. 不声明指向X的类型的指针。
  3. 不使用sizeof运算符。

很容易使用@steve jessop暗示的标准代码

offsetof(type, member-designator)

它扩展为一个整数常量表达式,其类型为size_t,其值是以字节为单位的偏移量,从结构的开始...到结构成员......C11§7.193

#include <stddef.h>
#include <stdio.h>

typedef struct {
  X member;
  unsigned char uc;
} sud03r_type;

int main() {
  printf("Size X: %zu\n", offsetof(sud03r_type, uc));
  return 0;
}

注意:此代码使用需要C99的"%zu"


0
投票

这是代码:诀窍是创建一个指针对象,保存其地址,递增指针,然后从前一个地址中减去新地址。关键点是当指针递增时,它实际上移动的大小等于它指向的对象,所以这里是类的大小(它指向的对象)。

#include<iostream>
using namespace std;
 class abc
    {
           int a[5];
           float c;           
    };
main()
{
    abc* obj1;
    long int s1;
    s1=(int)obj1; 
    obj1++;
    long int s2=(int)obj1;
    printf("%d",s2-s1);
}

问候


0
投票

很多这些答案都假设你知道你的结构会是什么样子。我相信这个面试问题的目的是要求你跳出框框思考。我正在寻找答案,但没有找到我喜欢的任何解决方案。我会做出更好的假设

struct foo {
  int a;
  banana b;
  char c;
  ...
};

通过创建foo [2],我现在将在内存中有2个连续的foo对象。所以...

foo[2] buffer = new foo[2];
foo a = buffer[0];
foo b = buffer[1];

return (&b-&a);

假设我的指针算法正确,这应该是票 - 它的便携性!不幸的是,诸如填充,编译器设置等等也都会起作用

思考?


0
投票

把它放到你的代码中

然后检查链接器输出(映射文件)

unsigned int  uint_nabil;
unsigned long  ulong_nabil;

你会得到这样的东西;

uint_nabil 700089a8 00000004
ulong_nabil 700089ac    00000004

4是大小!!


0
投票

一种简单的方法是使用数组。现在,我们知道在数组中,相同数据类型的元素存储在连续的内存块中。所以,通过利用这个事实我想出了以下内容:

#include <iostream>
using namespace std;

int main()
{
    int arr[2];
    int* ptr = &arr[0];
    int* ptr1 = &arr[1];
    cout <<(size_t)ptr1-(size_t)ptr;
}

希望这可以帮助。


-1
投票

试试这个,

#define sizeof_type( type )  ((size_t)((type*)1000 + 1 )-(size_t)((type*)1000))

对于以下用户定义的数据类型,

struct x
{
    char c;
    int i;
};

sizeof_type(x)          = 8
(size_t)((x*)1000 + 1 ) = 1008
(size_t)((x*)1000)      = 1000

-1
投票

这考虑到C ++字节并不总是8个二进制位,并且只有无符号类型具有明确定义的溢出行为。

#include <iostream>
int main () {
    unsigned int i = 1;
    unsigned int int_bits = 0;
    while (i!=0) {
        i <<= 1;
        ++int_bits;
    }

    unsigned char uc = 1;
    unsigned int char_bits = 0;
    while (uc!=0) {
        uc <<= 1;
        ++char_bits;
    }

    std::cout << "Type int has " << int_bits << "bits.\n";
    std::cout << "This would be  " << int_bits/8 << " IT bytes and "
              << int_bits/char_bits << " C++ bytes on your platform.\n";
    std::cout << "Anyways, not all bits might be usable by you. Hah.\n";
}

当然,你也可以只是#include <limit><climits>


-1
投票
    main()    
    {
    clrscr();
    int n;
    float x,*a,*b;//line 1
    a=&x;
    b=(a+1);
    printf("size of x is %d",
    n=(char*)(b)-(char*)a);
    }

通过此代码脚本,可以在不使用sizeof运算符的情况下计算任何数据的大小。只需要更改第1行中的float,其类型为要计算的大小


-1
投票
#include <stdio.h>

struct {
  int a;
  char c;
};

void main() {
  struct node*temp;
  printf("%d",(char*)(temp+1)-(char*)temp);
}

12
投票

看,sizeof是这方面的语言设施。唯一的,所以它是实现这一目标的唯一便携方式。

对于某些特殊情况,您可以生成不可移植的代码,使用其他启发式来了解特定对象的大小[*](可能通过让它们跟踪自己的大小),但您必须自己完成所有的簿记。

[*]对象在一般意义上而不是OOP意义上。


-1
投票
# include<stdio.h>

struct node
{
  int a;
  char c;
};

void main()
{
   struct node*ptr;
   ptr=(struct node*)0;
   printf("%d",++ptr);
}

-2
投票
#include <bits/stdc++.h> 

using namespace std; 

int main() 
{ 

    // take any datatype hear 
    char *a = 0; // output: 1

    int  *b = 0;  // output: 4

    long *c = 0; // output: 8

    a++;

    b++;

    c++;

    printf("%d",a);

    printf("%d",b);

    printf("%d",c);

    return 0; 
}

10
投票

好吧,我是一个业余爱好者..但我尝试了这个问题,我得到了正确的答案,没有使用sizeof。希望这会有所帮助..我试图找到一个整数的大小。

int *a,*s, v=10;

a=&v;

s=a;

a++;

int intsize=(int)a-(int)s;

printf("%d",intsize);

5
投票

这个采访问题的正确答案是“为什么我会这样做,当sizeof()为我这样做,并且这是唯一可行的方法吗?”


4
投票

填充的可能性在不知道用于引入它的规则的情况下阻止了所有希望。这些都是依赖于实现的。


3
投票

你可以通过阅读特定处理器的ABI来解决它,这解释了结构如何在内存中布局。每个处理器可能有所不同。但除非您正在编写编译器,否则您不希望仅使用sizeof,这是解决此问题的一种正确方法。


3
投票

试试这个:

int a;
printf("%u\n", (int)(&a+1)-(int)(&a));

2
投票

查看编译器源代码。你会得到 :

  • 标准数据类型的大小。
  • 填充结构的规则

从这个,任何东西的预期大小。

如果你至少可以为变量分配空间,并在其中填充一些sentinel值,你可以一点一点地改变它,看看值是否改变,但是这仍然不会告诉你任何关于填充的信息。


2
投票

如果X是数据类型:

#define SIZEOF(X) (unsigned int)( (X *)0+1 )

如果X是变量:

#define SIZEOF(X) (unsigned int)( (char *)(&X+1)-(char *)(&X) )
© www.soinside.com 2019 - 2024. All rights reserved.