Подтвердить что ты не робот

Размер типа данных без использования sizeof

У меня есть тип данных, скажем X, и я хочу знать его размер без объявления переменной или указателя этого типа и, конечно, без использования оператора sizeof.

Возможно ли это? Я думал об использовании стандартных файлов заголовков, которые содержат размер и диапазон типов данных, но которые не работают с определенными пользователем типами данных.

4b9b3361

Ответ 1

На мой взгляд, это вписывается в категорию "как добавить два ints без использования ++, + = или +?". Это пустая трата времени. Вы можете попытаться избежать монстров поведения undefined, выполнив что-то вроде этого.

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

Обратите внимание, что я не объявляю переменную типа или указателя на X.

Ответ 2

Ну, я любитель... но я опробовал эту проблему, и я получил правильный ответ, не используя sizeof. Надеюсь это поможет.. Я пытаюсь найти размер целого числа.

int *a,*s, v=10;

a=&v;

s=a;

a++;

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

printf("%d",intsize);

Ответ 3

Посмотрите, sizeof - это язык для этого. Единственный, так что это единственный переносимый способ добиться этого.

Для некоторых специальных случаев вы можете создать непереносимый код, который использовал какую-то другую эвристику, чтобы понять размер конкретных объектов [*] (возможно, заставляя их отслеживать свой собственный размер), но вам придется делать все бухгалтерия.

[*] Объекты в очень общем смысле, а не в смысле ООП.

Ответ 4

Правильный ответ на этот вопрос интервью: "Зачем мне это делать, когда sizeof() делает это для меня и является единственным переносным способом?"

Ответ 5

Возможность заполнения предотвращает все надежды без знания правил, используемых для ее введения. И они зависят от реализации.

Ответ 6

Вы можете решить эту проблему, прочитав ABI для своего конкретного процессора, в котором объясняется, как структуры выложены в памяти. Это потенциально различно для каждого процессора. Но если вы не пишете компилятор, удивительно, что вы не хотите просто использовать sizeof, который является одним правильным способом для решения этой проблемы.

Ответ 7

Попробуйте следующее:

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

Ответ 8

Посмотрите на источники компилятора. Вы получите:

  • размер стандартных типов данных.
  • правила для заполнения структур

и из этого ожидаемого размера ничего.

Если вы могли бы по крайней мере выделить место для переменной и заполнить в ней какое-то контрольное значение, вы можете поменять его по биту и посмотреть, изменится ли значение, но это все равно не сообщит вам никакой информации о заполнении.

Ответ 9

если X является типом данных:

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

если X - переменная:

#define SIZEOF(X) (unsigned int)( (char *)(&X+1)-(char *)(&X) )

Ответ 10

Попробуйте следующее:

 #include<stdio.h>

int main(){

  int *ptr = 0;

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

  return 0;

Ответ 11

Это код: Хитрость заключается в том, чтобы создать объект-указатель, сохранить его адрес, увеличить указатель и затем вычесть новый адрес из предыдущего. Ключевым моментом является то, что указатель увеличивается, он фактически перемещается на размер, равный объекту, который он указывает, поэтому здесь размер класса (из которого указывает объект).

#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);
}

Привет

Ответ 12

Многие из этих ответов предполагают, что вы знаете, как будет выглядеть ваша структура. Я считаю, что этот вопрос интервью предназначен для того, чтобы просить вас думать нестандартно. Я искал ответ, но не нашел решений, которые мне понравились. Я сделаю лучшее предположение, говоря

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);

Предполагая, что моя арифметика указателя правильно, это должен быть билет - и его портативный! К сожалению, такие вещи, как прокладка, настройки компилятора и т.д., Тоже будут играть роль

Мысли?

Ответ 13

Доступно с разрешения C89, которое в коде пользователя:

  • Не объявляет переменную типа X.
  • Не объявляет указатель на тип X.
  • Без использования оператора sizeof.

Достаточно легко использовать стандартный код, как это намечено @steve jessop

offsetof(type, member-designator)

который расширяется до целочисленного константного выражения, имеющего тип size_t, значение которого является смещением в байтах, члену структуры..., с самого начала его структуры... C11 §7.19 3

#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;
}

Примечание. В этом коде используется "%zu", для которого требуется C99.

Ответ 14

поместите это в свой код

затем проверьте вывод компоновщика (файл карты)

unsigned int  uint_nabil;
unsigned long  ulong_nabil;

вы получите что-то вроде этого:

uint_nabil 700089a8 00000004
ulong_nabil 700089ac    00000004

4 - размер!

Ответ 15

Один простой способ сделать это - использовать массивы. Теперь мы знаем, что в массивах элементы одного и того же типа данных хранятся в непрерывном блоке памяти. Итак, используя этот факт, я придумал следующее:

#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;
}

Надеюсь, что это поможет.

Ответ 16

Попробуйте это,

#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

Ответ 17

Это учитывает, что байт С++ не всегда является 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>.

Ответ 18

# include<stdio.h>

struct node
{
  int a;
  char c;
};

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

Ответ 19

#include <stdio.h>

struct {
  int a;
  char c;
};

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

Ответ 20

    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);
    }

В этом коде script размер любых данных может быть рассчитан без оператора sizeof. Просто измените float в строке 1 на тип, размер которого вы хотите вычислить