我很难理解下面一段特定代码的逻辑。
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++运算符的优先级有关,但这对我来说毫无意义
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
表达式*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
负索引是可以的,并且定义良好,只要它们不越界。
已经在此行之后
std::cout << *i_ptr++ << std::endl; // 22
CCD_ 16指向CCD_。因此,在下一行中,当您在再次获得22
:之前打印一个元素时
std::cout << *(i_ptr - 1) << std::endl; // 22
现在CCD_ 19仍然指向CCD_
std::cout << *i_ptr << std::endl; // 4
这与以下三行有关:
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*(i_ptr-1)<lt;std::endl;//22
这表示"在i_ptr查找的位置前一点打印出元素。"请记住,此时i_ptr正在查找4,因此通过在列表中查找一个元素,我们可以看到值22。
最后,我们这样做:
std::cout << *i_ptr << std::endl; // 4
上面写着"打印出i_ptr正在查看的内容。"由于我们正在查看4,并且已经查看了一段时间,所以我们在这里看到了这一点。