指针算术递增 post/pre-fix
Pointer Arithmetic Incrementing post/pre-fix
我无法理解下面一段特定代码的逻辑。
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++ 运算符优先级有关,但这对我来说毫无意义。
表达式 *i_ptr++
递增 指针 。它指向数组的 second 元素(值为 4
)。
这当然意味着i_ptr - 1
必须指向i_ptr
当前指向的位置之前的元素,即第一个元素(值为22
)。
请记住,对于 any 指针或数组 p
和索引 i
,表达式 p[i]
和 *(p + 1)
是完全相等。
另一种看待它的方式,你从
开始
+-----+-----+-----+-----+
| 21 | 4 | -17 | 45 |
+-----+-----+-----+-----+
^
|
i_ptr
然后您执行 (*i_ptr)++
这会增加 i_ptr
指向的值:
+-----+-----+-----+-----+
| 22 | 4 | -17 | 45 |
+-----+-----+-----+-----+
^
|
i_ptr
然后你做 *i_ptr++
,它首先取消引用 old 值 i_ptr
(结果是 22
)和 然后 递增指针:
+-----+-----+-----+-----+
| 22 | 4 | -17 | 45 |
+-----+-----+-----+-----+
^
|
i_ptr
现在你基本上i_ptr[-1]
:
+-----+-----+-----+-----+
| 22 | 4 | -17 | 45 |
+-----+-----+-----+-----+
^ ^
| |
| i_ptr
|
i_ptr - 1
负索引 可以并且定义明确,只要它们不超出范围即可。
已经在这一行之后
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
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
这与这三行有关:
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 << *(i_ptr - 1) << std::endl; // 22
这表示“打印出 i_ptr 查找位置之前的元素。”请记住,此时 i_ptr 正在查看 4,因此通过查看列表中的一个元素,我们会看到值 22。
最后,我们这样做:
std::cout << *i_ptr << std::endl; // 4
这表示“打印出 i_ptr 正在查看的任何内容。”因为我们正在看 4 - 已经有一段时间了 - 这就是我们在这里看到的。
我无法理解下面一段特定代码的逻辑。
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++ 运算符优先级有关,但这对我来说毫无意义。
表达式 *i_ptr++
递增 指针 。它指向数组的 second 元素(值为 4
)。
这当然意味着i_ptr - 1
必须指向i_ptr
当前指向的位置之前的元素,即第一个元素(值为22
)。
请记住,对于 any 指针或数组 p
和索引 i
,表达式 p[i]
和 *(p + 1)
是完全相等。
另一种看待它的方式,你从
开始+-----+-----+-----+-----+ | 21 | 4 | -17 | 45 | +-----+-----+-----+-----+ ^ | i_ptr
然后您执行 (*i_ptr)++
这会增加 i_ptr
指向的值:
+-----+-----+-----+-----+ | 22 | 4 | -17 | 45 | +-----+-----+-----+-----+ ^ | i_ptr
然后你做 *i_ptr++
,它首先取消引用 old 值 i_ptr
(结果是 22
)和 然后 递增指针:
+-----+-----+-----+-----+ | 22 | 4 | -17 | 45 | +-----+-----+-----+-----+ ^ | i_ptr
现在你基本上i_ptr[-1]
:
+-----+-----+-----+-----+ | 22 | 4 | -17 | 45 | +-----+-----+-----+-----+ ^ ^ | | | i_ptr | i_ptr - 1
负索引 可以并且定义明确,只要它们不超出范围即可。
已经在这一行之后
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
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
这与这三行有关:
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 << *(i_ptr - 1) << std::endl; // 22
这表示“打印出 i_ptr 查找位置之前的元素。”请记住,此时 i_ptr 正在查看 4,因此通过查看列表中的一个元素,我们会看到值 22。
最后,我们这样做:
std::cout << *i_ptr << std::endl; // 4
这表示“打印出 i_ptr 正在查看的任何内容。”因为我们正在看 4 - 已经有一段时间了 - 这就是我们在这里看到的。