2016-03-03 165 views
-1

当我看到这这些行同样的事情:指针和地址,该指针导致

BYTE MessageToProcess[MAX_MESSAGE_LENGTH]; 
TcpIpPacketHdr *pHdr = (TcpIpPacketHdr*)&MessageToProcess; 

我对自己说,第二行必须是这样的:

TcpIpPacketHdr *pHdr = (TcpIpPacketHdr*)MessageToProcess; 

但是,当我在调试模式下检查“pHdr”指向与两个示例中的“MessageToProcess”相同的事物,而在第一个代码中的MessageToProcess之前有一个“&”,所以通常pHdr应该包含MessageToProcess的地址,而不是它指向的字节,例如第一个messageToProcess中的元素。

所以这个问题发生了什么?我们正在处理指向字节而不是函数的指针,所以添加&必须改变公式。

在我们使用PHDR这样的代码之后:

pHdr->size+2 

但在最初,第一个代码,它包含指针保存的地址到阵列的第一个字节的地址。

+0

数组衰变为指针。你会在任何书中找到关于该语言的解释。 –

+0

和例如char **,指针类型的指针是不同于指针类型 – Aminos

+0

此代码可能具有未定义的行为,请检查[严格别名规则](http://stackoverflow.com/questions/98650) /是什么 - 是最严格走样规则)。 – Lundin

回答

8

变量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 
+0

因此,如果MessageToProcess是动态数组BYTE * MessageToProcess = new BYTE [MAX_MESSAGE_LENGTH],则上面的第一个代码应该是无效的:TcpIpPacketHdr * pHdr =(TcpIpPacketHdr *)&MessageToProcess;不再正确。我对吗 ? – Aminos

+1

@Aminos这是正确的。如果'MessageToProcess'是一个指针变量,那么'&MessageToProcess'就是指针变量的指针,即一个'BYTE **'。 –

+0

现在一切都很清楚。我很惊讶我仍然在C/C++中发现事物。我明白为什么像Java和Python这样的新语言现在更受青睐。 – Aminos

3

MessageToProcess是一个数组。

在阵列的情况下,阵列的基址可以通过交替地按以下方式表示:

&MessageToProcess OR MessageToProcess OR &MessageToProcess[0]

+0

我认为&MessageToProcess [0]与&MessageToProcess不同,但由于MessageToProcess不是BYTE *,所以它们是相同的。事实上,数组和指针之间存在差异 – Aminos