Почему мой оператор homespun sizeof нуждается в приведении char *? - PullRequest
3 голосов
/ 09 апреля 2010

Ниже приведена программа для определения размера структуры без использования оператора sizeof:

struct MyStruct
{
  int i;
  int j;
};

int main()
{
   struct MyStruct *p=0;
   int size = ((char*)(p+1))-((char*)p);
   printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);
   return 0;
}

Почему требуется приведение типов к типу char *

Если я не использую указатель char *, вывод равен 1 - почему?

Ответы [ 4 ]

2 голосов
/ 09 апреля 2010

Если я не использую указатель char *, вывод будет 1 - ПОЧЕМУ?
Потому что operator- подчиняется тем же арифметическим правилам указателя, что и operator+. Вы увеличили sizeof(MyStruct), когда добавили единицу к указателю, но без преобразования вы делите байтовую разницу на sizeof(MyStruct) в operator- для указателей.

Почему бы не использовать встроенный оператор sizeof()?

2 голосов
/ 09 апреля 2010

Потому что вы хотите размер вашей структуры в байтах. Арифметика указателей неявно использует размеры шрифтов.

int* p;
p + 5; // this is implicitly p + 5 * sizeof(int)

Применяя char *, вы обходите это поведение.

2 голосов
/ 09 апреля 2010

Потому что арифметика указателей работает в единицах указанного типа. Например:

int* p_num = malloc(10 * sizeof(int)); 
int* p_num2 = p_num + 5;

Здесь p_num2 не указывает пять байт за p_num, оно указывает пять целых за p_num. Если на вашей машине целое число имеет ширину четыре байта, адрес, сохраненный в p_num2, будет на двадцать байтов больше, чем в p_num. Причина этого в основном в том, что указатели могут быть проиндексированы как массивы. p_num[5] в точности эквивалентно *(p_num + 5), поэтому арифметика указателей не имеет смысла всегда работать в байтах, иначе p_num[5] даст вам некоторые данные, которые начинаются в середине второго целого числа, а не даст вам шестое целое число, как и следовало ожидать.

Чтобы переместить определенное число байтов за указатель, вам необходимо привести указатель в тип, который гарантированно будет иметь ширину ровно 1 байт (char).

Также у вас есть ошибка здесь:

printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);

У вас есть два спецификатора формата, но только один аргумент после строки формата.

1 голос
/ 09 апреля 2010

Арифметика указателя определяется в зависимости от размера типа указателя.Это то, что позволяет (например) эквивалентность между арифметикой указателя и подпиской массива - *(ptr+n) эквивалентно ptr[n].Когда вы вычитаете два указателя, вы получаете разницу как количество элементов, на которые они указывают.Приведение к pointer to char означает, что оно сообщает вам количество символов между этими адресами.Поскольку C делает char и byte по существу эквивалентными (т. Е. Байт является хранилищем, необходимым для одного символа), это также число байтов, занимаемых первым элементом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...