Размер указателя объекта указывает на - PullRequest
0 голосов
/ 06 апреля 2019

Я немного озадачен размером указателя элемента. Включая некоторый основной код для визуализации.

uint8_t var1;
uint8_t var2;

uint8_t *p[2]={&var1,&var2};

Результат sizeof (* p) равен 4 вместо 1, почему?

uint8_t var1;
uint8_t *p=&var1;

В этом коде правильный размер (* p) равен 1.

Чего мне не хватает?

Ответы [ 4 ]

1 голос
/ 06 апреля 2019

Обратите внимание, что массив p распадается на указатель, и, поскольку сам массив является массивом указателей, это тоже указатель.

#include <stdio.h>

int main(void)
{
    char var1;
    char var2;
    char *p[2] = { &var1, &var2 };
    printf("%zu\n", sizeof(*p));    // size of each element
    printf("%zu\n", sizeof(**p));   // size of dereferenced element
    return 0; 
}

Вывод программы

4
1
0 голосов
/ 07 апреля 2019
sizeOf(*p)

Это вычисляет размер типа по адресу, который хранится в значении p ... т.е. указатель на uint8_t.

sizeOf(*p[0])

Это размер типа по адресу, который хранится в значении нулевого элемента массива, который начинается с адреса, хранящегося в значении p.

uint8_t *p[2]={&var1,&var2};

Это объявляет, что значение p является адресом первого объекта в массиве указателей на uint8_t.

Это НЕ разыменование p. Ни *, ни [] не имеют такого значения для lvalues.

Семантика оператора разыменования имеет больше смысла, если вместо того, чтобы рассматривать его как команду, вы воспринимаете его как математический термин, с которым вы делаете алгебру с ...

"√ 2"         : "the square root of 2"
" *p"         :  "the dereference of p"
...
"x = *p"      : "set the value of x to the dereference of p"
"int *p"      : "has type int: the dereference of p"
0 голосов
/ 06 апреля 2019

Это не размер указателя, а размер ссылочного объекта.

в первом примере это указатель, во втором uint8_t

легко подтвердить:

uint8_t v8;
uint16_t v16;
uint32_t v32;
uint64_t v64;

double vd;
float vf;

uint8_t *v8p = &v8;
uint16_t *v16p = &v16;
uint32_t *v32p = &v32;
uint64_t *v64p = &v64;

double *vdp = &vd;
float *vfp = &vf;


volatile size_t sizes[] = {sizeof(*v8p), sizeof(*v16p), sizeof(*v32p), sizeof(*v64p), sizeof(*vdp), sizeof(*vfp)};

и результат: (используя M4 uC - STM32F476) enter image description here

0 голосов
/ 06 апреля 2019

Это потому, что в вашем первом примере, грубо говоря, p - это так называемый двойной указатель или указатель на указатель, потому что он определен как указатель на массив.Таким образом, когда вы отменяете ссылку, *p вы получаете указатель, а не объект типа uint8_t.

Таким образом, размер указателя на ARM M4 на самом деле составляет 4 байта.

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