我很难理解指针的算术。
设int B=0, *p=&B, **V=&p
和sizeof(int)=4, sizeof(*int)=8
指令(*V)[1]
的作用是什么?对我来说,我看到的是(*V)[1]
等价于*(*V+1)
,所以应该发生的是,我们取消引用V(它是指向int的指针的指针(,并对该变量的内容求和1,即地址。这个变量是一个指针,我们假设sizeof(*int)=8
,所以理论上我们应该将1 * sizeof(*int)
(即8(与指针V指向的指针p中存储的任何地址相加。
然而,解决方案是求和4(1 + sizeof(int)
(。是错了还是我的想法错了?
您引用的解决方案是正确的。
表达式*V
的类型为int *
,因此它指向一个包含1个或多个int
的数组。因此,因为它指向int
,当指针算术发生时,它所指向的数据类型的大小(sizeof(int)
,即4(乘以给定值(1(。因此,如果打印*V
和*V + 1
的值,您会发现它们相差4。
然而,(*V)[1]
(相当于*(*V + 1)
(存在一个问题。由于*V
指向B
,因此*V + 1
指向B
之后的一个元素。这是合法的,因为指针可以指向数组末尾之后的一个元素(或者等效地指向被视为大小为1的数组的单个对象(。然而,不合法的是取消引用该指针。这样做会调用未定义的行为。
(*V)[1]
实际上相当于*(*V+1)
。
由于V
是&p
(通过初始化(,所以*V
是p
。所以我们有*(p+1)
。
注意,*V
和p
都具有类型int *
。它们指向一个int
,所以p+1
指向"下一个"int
。
由于p
指向B
(通过初始化(,并且B
是单个int
,所以p+1
刚好指向B
的末尾(如果我们有一个int
数组而不是单个int
,则"下一个int"将在此处(。
这"刚好超过B
的末尾"是指针所允许的,这是您的源为解决方案所指的位置,(*V)[1]
有效地将四个字节添加到*V
所指向的位置。
然而,虽然允许引用B
结束后的对象,但C标准没有定义试图访问那里的对象的行为。(*V+1)
是已定义的指针,但*(*V+1)
不是该位置的对象的已定义表达式。它的行为不是由C标准定义的。