有人可以解释以下代码的输出吗
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
有人可以解释以下代码的输出吗
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
也许这会有所帮助。你的例子大致相当于这个:
++(*p);
cout << *p << '\n';
cout << *p << '\n';
++p;
++(*p);
cout << *p << '\n';
没有括号,*p++
被解析为*(p++)
因为后缀增量具有比取消引用运算符更高的优先级。不过,在整个表达式之后仍会进行增量。
另一方面,前缀增量和 * 具有相同的优先级,因此++*p
从右到左解析为++(*p)
. 知道前缀增量必须在表达式之前完成,您现在可以将整个图片放在一起。
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;
或其他各种方式(考虑到其他人所说的优先级)
根据 C++ 运算符优先级表,后自增的优先级高于解引用 (*) 运算符,并且前自增和解引用运算符具有相同的优先级。预增量和取消引用运算符也是从右到左关联的。
因此,在第一行 ( cout<<++*p<<std::endl;
) 中,* 和 ++ 从右到左计算(首先取消引用,然后递增)。现在p
仍然指向第一个数组(因为它没有改变),但是 (*p) 指向第一个字符串的第二个字母(输出显示了这个事实)。
然而,在第二行 ( cout<<*p++<<std::endl;
) 中,首先评估后增量(在检索 的旧值之后p
),然后p
递增,现在指向第二个数组。但在增量之前,p 的值用于表达式中,第二行的输出与第一行完全相同。
在第三行中,首先p
取消引用(指向第二个数组的第一个字母),然后递增(指向第二个数组的第二个字母),然后打印该值。
++*p
在打印之前执行。所以增加指针,然后打印。
*p++
打印后执行。打印,然后递增。
只是一个猜测,但我认为因为您正在使用 增加延迟指针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;