0

int * ptr,array[10]; ptr= array;. 现在,阵列连续位置中的每个存储单元都有固定的大小。如果第一个单元格的地址是 1234,那么下一个单元格的地址必须是 1238。但是我们使用指针作为访问它*(ptr+1)。我对此感到困惑。任何来源或答案?谢谢。

4

8 回答 8

5

来自 C11标准: §6.5.2.1

后缀表达式后跟方括号 [] 中的表达式是数组对象元素的下标指定。下标运算符 [] 的定义是 E1[E2] 等同于 (*((E1)+(E2)))。由于适用于二元 + 运算符的转换规则,如果 E1 是数组对象(等效地,指向数组对象的初始元素的指针)并且 E2 是整数,则 E1[E2] 指定第 E2 个元素E1(从零开始计数)。

EG 你正在做的基本上是[]已经做的

此外(相同的标准)解释了为什么指针会像您注意到的那样增加:§6.5.6

当一个整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向与原始元素偏移的元素,使得结果和原始数组元素的下标之差等于整数表达式。换句话说,如果表达式 P 指向数组对象的第 i 个元素,则表达式 (P)+N(等效于 N+(P))和 (P)-N(其中 N 的值为 n)指向分别到数组对象的第 i+n 个和第 i-n 个元素,前提是它们存在。此外,如果表达式 P 指向数组对象的最后一个元素,则表达式 (P)+1 指向数组对象的最后一个元素,如果表达式 Q 指向数组对象的最后一个元素,则表达式 (Q)-1 指向数组对象的最后一个元素。如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则计算不应产生溢出;否则,行为是未定义的。如果结果指向数组对象的最后一个元素,则不应将其用作计算的一元 * 运算符的操作数。行为未定义。如果结果指向数组对象的最后一个元素,则不应将其用作计算的一元 * 运算符的操作数。行为未定义。如果结果指向数组对象的最后一个元素,则不应将其用作计算的一元 * 运算符的操作数。

于 2013-08-02T15:13:36.203 回答
3

编译器知道这ptr是一个指向 4 字节类型的指针,因此它知道它ptr+1在内存中还有 4 个字节。

如果您想一想,很明显必须如此,否则您将无法在不知道系统上(例如)整数大小的情况下编写可移植代码。

此外,数组索引在幕后完全是指针运算 - 也就是说,array[3]*(array + 3)

于 2013-08-02T15:13:53.797 回答
1

当索引一个指针时,编译器知道索引应该提前单元格的大小,在这种情况下,一个 4 字节的指针。

于 2013-08-02T15:13:38.593 回答
1

指针算法考虑了指向类型的大小。例如,如果 的值为ptr1234因为ptris 的类型为int*,那么 的值为p + 11234 + 1 * sizeof(int) == 1234 + 1 * 4 = 1238假设sizeof(int) == 4)。

于 2013-08-02T15:15:26.523 回答
0

指针算术与普通算术不同。在指针算术中,一个参数必须是指针类型,另一个必须是整数类型:

  1. intA + intB: 普通算术,结果是总和。
  2. intA + pointerB: 指针运算,执行的计算是sizeof(*pointerB)*intA + pointerB
  3. pointerA + intB: 指针运算,执行的计算是pointerA + sizeof(*pointerA)*intB
  4. pointerA + pointerB: 非法的

pointerA[intB]只是 case 2 ( pointerA + intB) 的简写,这就是为什么它等同于intB[pointerA](resolves to case 3),但这仅在 IOCCC 中使用。

于 2013-08-02T15:31:56.017 回答
0

+ 运算符的右操作数,我们称之为 x,并不是您移动指针的实际量。因为 int 是 4 个字节,编译器知道实际跳到 x*4。

于 2013-08-02T15:17:33.423 回答
0

我的猜测是,根据你 (ptr + 1)应该给你1235,但显然它没有。

除了其他人给出的关于它为什么添加4和给你的答案之外1238,考虑一下它给你的情况12351235你没有整数元素(即数组的第二个元素)。但是你的指针应该指向一个整数。因此,这种方式行不通。

于 2013-08-02T15:26:57.933 回答
0

指针算术的单位是指向对象,而不是字节。

如果p指向int对象,则p+1p+2p+3指向连续的int对象,而不是连续的字节。如果p指向一个大型结构,则它们指向该结构的连续实例。

编译器在幕后进行工作,将指针算术转换为机器地址算术。因此,它根据需要将偏移量相乘,以将对象单位转换为字节单位。

于 2013-08-02T15:22:37.600 回答