我无法完成下面某段特定代码的逻辑。
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 ++运算符优先级有关,但这对我来说毫无意义。
答案 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 - 并且已经有一段时间了 - 这就是我们在这里看到的。