Указатель и адрес к этому указателю приводят к тому же
Когда я увидел эти строки:
BYTE MessageToProcess[MAX_MESSAGE_LENGTH];
TcpIpPacketHdr *pHdr = (TcpIpPacketHdr*)&MessageToProcess;
Я сказал себе, что вторая строка должна быть такой:
TcpIpPacketHdr *pHdr = (TcpIpPacketHdr*)MessageToProcess;
Но когда я проверил в режиме отладки, "pHdr" указывает на то же, что и "MessageToProcess" в обоих примерах, тогда как "&" перед MessageToProcess в первом коде, поэтому обычно pHdr должен содержать адрес MessageToProcess, а не адрес байта, который указывает, например, на первый элемент в messageToProcess.
Итак, вопрос Что происходит? мы имеем дело с указателями на байты, а не с функциями, поэтому добавляем и должны изменять уравнение.
Позже в коде мы используем pHdr следующим образом:
pHdr->size+2
Но сначала в первом коде он содержит адрес указателя, удерживающего адрес в первом байте массива.
Ответы
Ответ 1
Переменная MessageToProcess
- это массив. Он размещен где-то в памяти. Используя &MessageToProcess
, мы получаем адрес этого места в памяти, где хранится массив. Тип &MessageToProcess
- BYTE (*)[MAX_MESSAGE_LENGTH]
.
Когда вы используете MessageToProcess
без оператора адреса, он распадается на указатель на первый элемент, т.е. &MessageToProcess[0]
. Типом этого является BYTE *
.
Для чего-то простого, как примеры, показанные в вопросе, эти два адреса одинаковы. Разница возникает, когда вы пытаетесь сделать что-то еще с этими указателями. Например, если вы делаете (&MessageToProcess)[1]
, вы не получите то же самое, что при выполнении MessageToProcess[1]
.
Чтобы визуализировать это несколько, скажем, мы имеем следующее определение:
int a[4] = { 0, 1, 2, 3 };
Затем это примерно так:
&a &a+1
| |
v v
+---+---+---+---+
| 0 | 1 | 2 | 3 |
+---+---+---+---+
^ ^
| |
a a+1
Ответ 2
MessageToProcess
- это массив.
В случае массива базовый адрес массива может быть указан следующими способами:
&MessageToProcess
ИЛИ MessageToProcess
ИЛИ &MessageToProcess[0]
.