5

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

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
4

5 回答 5

5

也许这会有所帮助。你的例子大致相当于这个:

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

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

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

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

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

于 2012-02-20T10:46:59.823 回答
3
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;

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

于 2012-02-20T10:52:17.323 回答
1

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

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

然而,在第二行 ( cout<<*p++<<std::endl;) 中,首先评估后增量(在检索 的旧值之后p),然后p递增,现在指向第二个数组。但在增量之前,p 的值用于表达式中,第二行的输出与第一行完全相同。

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

于 2012-02-20T10:49:52.680 回答
0

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

于 2012-02-20T10:24:03.573 回答
0

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

同样cout<<*p++<<std::endl;在输出后增加字符,因此最终cout<<++*p<<std::endl;结果为两个增量。

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

cout<<*(++p)<<std::endl; 
cout<<*(p++)<<std::endl; 
cout<<*(++p)<<std::endl; 
于 2012-02-20T10:24:04.273 回答