2015-05-11 3 views
0

Что произойдет Если мы нажмем 32-битный указатель на 8 бит?Кастинг-указатели?

Я предполагаю, что, например, у нас есть 0x8000 0000, и если мы отбрасываем до 8 бит, значение нового указателя будет 0x00. Я прав?

+0

Это зависит от реализации, я думаю. – Barmar

+1

Что такое указатель '8 бит'? или вы имели в виду указатель на тип данных «8 бит»? –

+0

думаю байт данные type. – Lazar

ответ

0

Указатель - указатель, в зависимости от платформы. На 32-битном процессоре указатель всегда 32 бит.

void *temp = 0x8000000; 
uint8_t *temp = 0x8000000; 
uint16_t *temp = 0x8000000; 

Если вы указали указатель, вы измените размер заостренного значения.

void *temp = 0x80000000; 
uint8_t temp2 = *((char *)(temp)); // return a single char (8 bits) at 0x80000000 
uint16_t temp3 = *((short *)(temp)); // return a single short (16 bits) at 0x80000000 
+0

Я использую 32-битный процессор ARM Cortex-M3. Я просто запутался в том, что если использовать 32-битный указатель на 8 бит, мы будем читать с неправильного адреса, потому что 0x8000 0000 и 0x00 указывает на разные ячейки памяти, ofc зависит от сопоставления памяти. – Lazar

+0

@ Lazar, указатель на 8-битное значение все еще 32/64-бит, и это можно легко проверить, проверив sizeof. То есть. sizeof (int *), sizeof (uint8_t *) и т. д. Размер указателя-указателя не имеет никакого отношения к размеру указателя. – domen

+0

@domen Так, например, (uint8_t *) данные представляют собой 32-битный указатель на 8-битное значение? – Lazar

0

На процессоре архитектуры x86 указатель представляет собой целое число, указывающее на область памяти. То, что вы действительно спрашиваете, я думаю, и надеюсь, если возможно иметь указатель на целое число, а затем направить его на указатель на символ.

Вы можете заглянуть внутрь битов целого числа, создав указатель на него и применив его к более узкому типу, например char, а затем увеличьте его.

В принципе, если вы увеличиваете указатель на char, вы перемещаете только один байт внутри целого числа.

0

Ну, на самом деле есть архитектуры, которые имеют разные указатели разного размера. Классический x86 должен иметь ближние и дальние указатели. Первый имел 16 бит и был ограничен определенной областью памяти. Любое использование за пределами этой области было бы неопределенным. Дальний указатель состоял из двух 16-битовых значений (сегмент: смещение) в 32-битной переменной. Сегментная часть упрощала область памяти, на которую указывал указатель, в то время как смещение фактически было идентично ближнему указателю.

Однако это было (и не) является частью стандарта C, но имеет характерные для архитектуры расширения. Поскольку это могло быть принято как решающее для платформы, оно было поддержано всеми доступными инструментами, но все равно ничего стандартного.

Для ваших указателей вы должны - в общем - никогда не возиться с указателем, прежде всего никогда не применяйте его к типу, который не может содержать все биты, необходимые для указателя. Если по какой-то причине вам нужно сохранить указатель в целочисленной переменной, используйте uintptr_t или intptr_t, которые определены в stdint.h по стандарту C99. Однако они не являются обязательными, поэтому ваша инструментальная цепочка может не поддерживать их (gcc для экземпляров, а не идея, что Microsoft уже успела добавить этот заголовок в VS).

Помните, что значение, хранящееся в uintptr_t (например), может не совпадать с прямым приведением другого целочисленного типа (но для ARM это так, как я знаю сам).

Если вы спрашиваете, как сжать значение указателя, вы можете сначала направить его на unitptr_t, а затем сжать целочисленное значение с использованием одного из известных алгоритмов (Huffman и т. Д.).