指针算术增加后/预修复

时间:2017-11-02 17:16:31

标签: c++ pointers pointer-arithmetic

我无法完成下面某段特定代码的逻辑。

int i[] = { 21, 4, -17, 45 };

int* i_ptr = i;

std::cout << (*i_ptr)++ << std::endl;   // 21

std::cout << *i_ptr << std::endl;       // 22

std::cout << *i_ptr++ << std::endl;     // 22

std::cout << *(i_ptr - 1) << std::endl; // 22

std::cout << *i_ptr << std::endl;       // 4

std::cout << ++*i_ptr << std::endl;     // 5

std::cout << *++i_ptr << std::endl;     // -17

system("pause");

我的问题是这段代码是如何从22 ...

std::cout << *(i_ptr - 1) << std::endl; // 22

至4。

std::cout << *i_ptr << std::endl;       // 4

然后到5。

std::cout << ++*i_ptr << std::endl;     // 5

当我第一次看到这段代码时,我认为22将会从22变为21.我明白这与C ++运算符优先级有关,但这对我来说毫无意义。

4 个答案:

答案 0 :(得分:5)

std::cout << (*i_ptr)++ << std::endl;   // 21
//i_ptr points to i[0], which is increased from 21 to 22

std::cout << *i_ptr << std::endl;       // 22
//prints i[0], which is 22

std::cout << *i_ptr++ << std::endl;     // 22
//prints i[0] and increments i_ptr to point to i[1]

std::cout << *(i_ptr - 1) << std::endl; // 22
//prints i[0], i_ptr points to i[1], so i_ptr - 1 points to i[0]

std::cout << *i_ptr << std::endl;       // 4
//prints i[1], which is 4

std::cout << ++*i_ptr << std::endl;     // 5
//prints the incremented i[1], which was 4 and is 5 now

std::cout << *++i_ptr << std::endl;     // -17
//increment i_ptr to point to i[2] and prints the value

答案 1 :(得分:1)

表达式*i_ptr++递增指针。它使它指向数组的第二个元素(值为4)。

这当然意味着i_ptr - 1必须指向i_ptr当前指向的元素之前的元素,这是第一个元素(值22)。

请记住,对于任何指针或数组p和索引i,表达式p[i]*(p + 1)完全相同。

另一种看待它的方法,你从

开始
+-----+-----+-----+-----+
|  21 |   4 | -17 |  45 |
+-----+-----+-----+-----+
^
|
i_ptr

然后执行(*i_ptr)++,增加i_ptr指向的值:

+-----+-----+-----+-----+
|  22 |   4 | -17 |  45 |
+-----+-----+-----+-----+
^
|
i_ptr

然后你*i_ptr++首先取消引用i_ptr值(导致22)和然后增量指针:

+-----+-----+-----+-----+
|  22 |   4 | -17 |  45 |
+-----+-----+-----+-----+
      ^
      |
      i_ptr

现在你基本上做i_ptr[-1]

+-----+-----+-----+-----+
|  22 |   4 | -17 |  45 |
+-----+-----+-----+-----+
^     ^
|     |
|     i_ptr
|
i_ptr - 1

负面索引 是好的并且定义良好,只要它们不会越界。

答案 2 :(得分:0)

已经在这一行之后

std::cout << *i_ptr++ << std::endl;     // 22

i_ptr指向4。因此,在您重新获得22之前打印一个元素的下一行:

std::cout << *(i_ptr - 1) << std::endl; // 22

现在i_ptr仍然指向4

std::cout << *i_ptr << std::endl;       // 4

答案 3 :(得分:0)

这与这三行有关:

std::cout << *i_ptr++ << std::endl;     // 22
std::court << *(i_ptr - 1) << std::endl; // 22
std::cout << *i_ptr << std::endl;       // 4

以下是发生的事情:

std::cout << *i_ptr++ << std::endl;     // 22

在这里,这被解释为*(i_ptr++),这意味着“将ptr前进指向下一个元素,然后将指针移回指向i_ptr用于指向的地方,并将其推导出来。”换句话说,之后该行完成执行,指针ptr指向元素4,但是行打印22,因为这是ptr用来指向的地方。这很重要,因为这意味着我们已经改变了我们正在寻找的位置,即使输出没有立即显示出来。

让我们看看下一行:

std :: cout&lt;&lt; *(i_ptr - 1)&lt;&lt;的std :: ENDL; // 22

这说“在i_ptr看之前打印出一个点的元素。”请记住,此时i_ptr正在查看4,所以通过查看列表中的一个元素,我们看到值22。

最后,我们这样做:

std::cout << *i_ptr << std::endl;       // 4

这说“打印出i_ptr正在看的东西。”因为我们正在看4 - 并且已经有一段时间了 - 这就是我们在这里看到的。