指针到指针的算术

发布于 2025-01-07 23:38:00 字数 356 浏览 0 评论 0 原文

有人可以解释以下代码的输出吗

char* a[] = {"ABC123", "DEF456", "GHI789"};
char **p = a;
cout<<++*p<<std::endl;
cout<<*p++<<std::endl;
cout<<++*p<<std::endl;

输出:

BC123
BC123
EF456

让我感到困惑的是 ++*p 和 *p++ 的不同行为。我期望输出是:

ABC123
DEF456
GHI789

Can someone explain the output of the following code

char* a[] = {"ABC123", "DEF456", "GHI789"};
char **p = a;
cout<<++*p<<std::endl;
cout<<*p++<<std::endl;
cout<<++*p<<std::endl;

Output:

BC123
BC123
EF456

What is confusing to me is the different behavior of ++*p and *p++. I was expecting the output to be:

ABC123
DEF456
GHI789

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

橘亓 2025-01-14 23:38:00

也许这会有所帮助。您的示例大致相当于:

++(*p);
cout << *p << '\n';

cout << *p << '\n';
++p;

++(*p);
cout << *p << '\n';

没有括号,*p++ 被解析为 *(p++) 因为后缀增量的优先级高于解引用运算符。不过,在整个表达式之后仍然会进行增量。

另一方面,前缀增量和 * 具有相同的优先级,因此 ++*p 从右到左解析为 ++(*p)。知道前缀增量必须在表达式之前完成,您现在可以将整个图片放在一起。

Perhaps this will help. You example is roughly equivalent to this:

++(*p);
cout << *p << '\n';

cout << *p << '\n';
++p;

++(*p);
cout << *p << '\n';

Without parentheses, *p++ is parsed as *(p++) since suffix increment has got higher precedence than dereference operator. Increment is still done after the whole expression, though.

On the other hand, prefix increment and * have got same precedence, so ++*p is parsed right-to-left as ++(*p). Knowing that prefix increment has to be done before the expression, you can now put the whole picture together.

自我难过 2025-01-14 23:38:00
char* a[] = {"ABC123", "DEF456", "GHI789"};
char **p = a;
cout<<++*p<<std::endl; // 1
cout<<*p++<<std::endl; // 2
cout<<++*p<<std::endl; // 3

第 1 行第一个 *p 将指向数组 "ABC123" 中的元素,++ 向前移动一个,因此 'BC123 ' 被打印。

在第 2 行,*p 仍然指向 BC123,因此会打印该内容,然后在打印后执行 ++。这会将指针移动到数组中的第二个元素。

在第 3 行,它与第 1 行相同。您已获取 p 的内容(现在是数组中的第二个元素),并将一个字符移动到该字符串,从而打印 EF456

(也可以看看这里字符串类型数组上的指针算术,C++如何处理这个?因为我认为了解正在发生的事情可能很有用)

要打印您期望的内容,以下内容会起作用:

cout<<*p++<<std::endl;
cout<<*p++<<std::endl;
cout<<*p++<<std::endl;

或者

cout<<*p<<std::endl;
cout<<*(++p)<<std::endl;
cout<<*(++p)<<std::endl;

或各种其他方式(考虑到其他人所说的优先级)

char* a[] = {"ABC123", "DEF456", "GHI789"};
char **p = a;
cout<<++*p<<std::endl; // 1
cout<<*p++<<std::endl; // 2
cout<<++*p<<std::endl; // 3

On line 1 first *p will be pointing to the element in the array "ABC123" and the ++ moves one forward and so 'BC123' is printed.

On line 2 *p is still pointing to BC123 so this is printed and then once printed the ++ is carried out. This moves the pointer to the 2nd element in the array

On line 3 it is the same as line 1. You have taken the contents of p (Now the 2nd element in the array) and moved one character in that string, thus printing EF456

(Also have a look at here Pointer arithmetic on string type arrays, how does C++ handle this? as I think it might be useful to get an understanding of what is happening)

To print what you expected the following would work:

cout<<*p++<<std::endl;
cout<<*p++<<std::endl;
cout<<*p++<<std::endl;

Or

cout<<*p<<std::endl;
cout<<*(++p)<<std::endl;
cout<<*(++p)<<std::endl;

Or various other ways (taking into account precedence as others have said)

握住你手 2025-01-14 23:38:00

根据C++运算符优先级表,后自增运算符的优先级高于解引用(*)运算符,预自增和解引用运算符的优先级相同。预递增和解引用运算符也是从右到左关联的。

因此,在第一行 (cout<<++*p<) 中,* 和 ++ 从右向左计算(首先取消引用,然后递增)。现在 p 仍然指向第一个数组(因为它没有改变),但是 (*p) 指向第一个字符串的第二个字母(输出显示了这一事实)。

在第二行 (cout<<*p++<) 中,首先计算后增量(在检索 p 的旧值之后) >) 并且 p 递增,现在指向第二个数组。但在递增之前,p 的值用于表达式中,第二行的输出与第一行完全相同。

在第三行中,首先对 p 进行取消引用(指向第二个数组的第一个字母),然后递增(指向第二个数组的第二个字母),并打印该值。

According to C++ operator precedence table, precedence of post-increment is higher than dereference (*) operator, and pre-increment and dereference operator have same precedence. Also pre-increment and dereference operator are right-to-left associative.

So in the first line (cout<<++*p<<std::endl;), * and ++ are evaluated from right to left (first dereference, then increment). Now p still point to the first array (because it has not changed),but (*p) points to the second letter of the first string (the output shows this fact).

In second line (cout<<*p++<<std::endl;) however post-increment is evaluated first (after retrieving the old value of p) and the p is incremented and now points to the second array. But before increment, the value of p is used in the expression and output of the second line is exactly as the first line.

In third line, first the p is dereferenced (point to the first letter of the second array), then incremented (point to the second letter of the second array), and the value is printed.

呆萌少年 2025-01-14 23:38:00

++*p 在打印之前执行。所以增加指针,然后打印。
*p++ 打印后执行。打印,然后递增。

++*p is executed before printing. So increment pointer, then print.
*p++ is executed after printing. Print, then increment.

自此以后,行同陌路 2025-01-14 23:38:00

只是一个猜测,但我认为因为您正在使用 cout<<++*p< 增加引用指针,所以您实际上所做的是增加p 指向的字符串的开头,然后将其输出到标准输出。

类似地,cout<<*p++<在输出后递增字符,因此最终的cout<<++*p< 产生两个增量。

你应该尝试这个,看看它是否有效

cout<<*(++p)<<std::endl; 
cout<<*(p++)<<std::endl; 
cout<<*(++p)<<std::endl; 

Just a guess, but I think because you are incrementing the deferenced pointer using cout<<++*p<<std::endl;, what you are actually doing is incrementing the character at the start of the string that p points to then outputting this to the standard output.

Similarly cout<<*p++<<std::endl; is incrementing the character after outputting so the final cout<<++*p<<std::endl; results in two increments.

You should try this instead and see if it works

cout<<*(++p)<<std::endl; 
cout<<*(p++)<<std::endl; 
cout<<*(++p)<<std::endl; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文