c программа может `uint8_t` указывать на адрес размером 32 бита

В приведенном ниже коде get_pic() возвращает указатель uint8_t type.

Затем в main() вызывается get_pic(), и его возвращаемое значение приводится к переменной address, которая является unsigned int.

Указатель, который возвращает get_pic(), относится к глобальному массиву, который оказывается по адресу a8000f80.

Мой вопрос в том, что адрес a8000f80 является 32-битным числом. Следовательно, как указатель, возвращаемый get_pic(), может указывать на этот адрес, если он имеет тип uint8_t, состоящий всего из 8 бит?

//Function declaration
uint8_t* get_pic(int *piclen);

main() {

  unsigned int address, value;
  address = (unsigned int) get_pic((int*)& value);
}

person logitech mouse    schedule 02.11.2016    source источник
comment
Не путайте размер указателя на что-то с размером этого чего-то. (Я уверен, что адрес вашего дома — возможно, несколько десятков символов — намного меньше вашего дома.)   -  person molbdnilo    schedule 02.11.2016
comment
Обратите внимание, что предположение, что указатель на что-либо вписывается в unsigned int, не является соответствующим предположением. Если вам нужно сохранить указатель в целое число, используйте intptr_t или uintptr_t. И то строго только для void *...   -  person DevSolar    schedule 02.11.2016
comment
адреса не обязательно должны быть 32-битными. Это может быть 8, 16, 20, 24, 48 или 64 бита.   -  person phuclv    schedule 02.11.2016
comment
... хотя, если у вас есть 8-битные указатели, у вас есть только 256 ячеек памяти, и вам, вероятно, не следует использовать C. :-)   -  person Lee Daniel Crocker    schedule 02.11.2016


Ответы (3)


uint8_t не может никуда указывать, потому что это не указатель. Но uint_8* (указатель на uint8_t) может.

Вы, вероятно, хотите этого:

uint8_t* get_pic(int *piclen);

main() {
  uint8_t *address;
  int value;

  address = get_pic(&value);
}

get_pic возвращает uint8_t *, то есть указатель на uint8_t), поэтому тип address должен быть uint8_t *.

Параметр, передаваемый в getpic, имеет тип указателя на int (int*), поэтому value также должен иметь тип int*.

person Jabberwocky    schedule 02.11.2016

Он возвращает указатель на значение типа uint8_t; это ничего не говорит о размере самого указателя.

person Scott Hunter    schedule 02.11.2016

Размер указателя никак не связан с размером объекта, на который он указывает. Таким образом, фактически для большинства (то есть почти всех) реализаций sizeof($anything *) является константой (для любого $anything, не являющегося функцией).

So sizeof(uint8_t _*) == sizeof(uint32_t *) == sizeof(unsigned int *) == sizeof(struct foo *).

uint8_t * get_pic(int * piclen);

Это возвращает указатель на некоторые данные. Если эти данные uint32_t, то их можно присвоить uint32_t *, в C приведение не требуется (но компиляторы могут предупредить):

int len;
uint32_t * address = get_pic(&len);

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

Также обратите внимание на ответ Майкла Уолца, он написал мне параллельно ;)

person Bodo Thiesen    schedule 02.11.2016
comment
sizeof — это оператор времени компиляции, а $anything выглядит... странно... в контексте C. - person DevSolar; 02.11.2016
comment
Я знаю, мне все еще нравится писать sizeof(stuff) вместо sizeof stuff. - person Bodo Thiesen; 02.11.2016
comment
Точнее, как вы понимаете, что оператор времени компиляции может иметь непостоянный результат? - person DevSolar; 02.11.2016
comment
Это мета-говорение и ясно дает понять, что здесь может быть что угодно. - person Bodo Thiesen; 02.11.2016
comment
Где я могу указать или предложить, что sizeof может возвращать результаты переменной времени выполнения? Кстати: он может: int dynamic[num]; size_t num_dependant = sizeof dynamic; - person Bodo Thiesen; 02.11.2016
comment
Как, по-вашему, get_pic() возвращает указатель на uint32_t данные, когда объявлено, что он возвращает uint8_t *? Как, по-вашему, безопасно приводить последнее к первому? Извините, этот ответ везде... - person DevSolar; 02.11.2016
comment
Какую часть Если эти данные uint32_t вы не поняли? uint32_t определяется как 32-битный без знака без заполнения, uint8_t определяется как 8-битный без знака без заполнения, поэтому приведение между ними четко определено. - person Bodo Thiesen; 02.11.2016
comment
Давайте продолжим это обсуждение в чате. - person Bodo Thiesen; 02.11.2016