通过指针访问数组

时间:2013-08-02 15:09:32

标签: c++ c pointers

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

8 个答案:

答案 0 :(得分:5)

来自C11 standard:§6.5.2.1

  

post fi x表达式后跟方括号[]中的表达式是下标   指定数组对象的元素。下标运算符[]的定义   是E1 [E2]与(*((E1)+(E2)))相同。由于转换规则   应用于二进制+运算符,如果E1是一个数组对象(等效地,指向   数组对象的初始元素),E2是整数,E1 [E2]表示E2   E1的元素(从零开始计数)。

E.G。你正在做的基本上是[]已经做了什么

同样(相同的标准)解释了为什么指针会在你注意到的时候递增:§6.5.6

  

当指针中添加或减去具有整数类型的表达式时,   result具有指针操作数的类型。如果指针操作数指向的元素   一个数组对象,并且该数组足够大,结果指向一个偏移的元素   原始元素使得结果和原始的下标不同   数组元素等于整数表达式。换句话说,如果表达式P指向   数组对象的第i个元素,表达式(P)+ N(等效地,N +(P))和   (P)-N(其中N具有值n)分别指向第i + n和第i-n个元素   数组对象,只要它们存在。而且,如果表达式P指向最后一个   数组对象的元素,表达式(P)+1指向一个过去的最后一个元素   数组对象,如果表达式Q指向一个数组对象的最后一个元素,   表达式(Q)-1指向数组对象的最后一个元素。如果两个指针   操作数和结果指向同一个数组对象的元素,或者指向最后一个数组对象的元素   数组对象的元素,评估不得产生溢出;否则,   行为未定。如果结果指向一个超过数组对象的最后一个元素的那个,那么   不得用作被评估的一元*运算符的操作数。

答案 1 :(得分:3)

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

如果你想了一下,很明显这一定是这样的,否则如果你不知道系统中整数(例如)的大小就无法编写可移植代码。

此外,数组索引正是封面下的指针算法 - 即array[3]*(array + 3)完全相同

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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

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

答案 6 :(得分:0)

我的猜测是根据你(ptr + 1)应该给你1235,但显然不是。{1}}

除了其他人提供的关于为什么会添加4并为您提供1238的答案之外,如果它在12351235给了{{1}},请考虑一下没有整数元素(即数组的第二个元素)。 但是你的指针应该指向一个整数。因此它不会以这种方式运作。

答案 7 :(得分:0)

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

  1. intA + intB:正常算术,结果是总和。
  2. intA + pointerB:指针算术,执行的计算是sizeof(*pointerB)*intA + pointerB
  3. pointerA + intB:指针算术,执行的计算是pointerA + sizeof(*pointerA)*intB
  4. pointerA + pointerB:非法
  5. pointerA[intB]只是案例2(pointerA + intB)的简写,这就是为什么它等同于intB[pointerA](解析为案例3),但这仅用于IOCCC