有人可以解释以下代码的输出
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
答案 0 :(得分:4)
也许这会有所帮助。你的例子大致相当于:
++(*p);
cout << *p << '\n';
cout << *p << '\n';
++p;
++(*p);
cout << *p << '\n';
如果没有括号,*p++
将被解析为*(p++)
,因为后缀增量的优先级高于取消引用运算符。但是,在整个表达之后仍然会进行增量。
另一方面,前缀增量和*具有相同的优先级,因此++*p
从右到左解析为++(*p)
。知道必须在表达式之前完成前缀增量,现在可以将整个图片放在一起。
答案 1 :(得分: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
,因此会打印出来然后打印完++
p
。这会将指针移动到数组中的第二个元素
在第3行,它与第1行相同。您已获取EF456
的内容(现在是数组中的第2个元素)并在该字符串中移动了一个字符,从而打印cout<<*p++<<std::endl;
cout<<*p++<<std::endl;
cout<<*p++<<std::endl;
< / p>
(另请查看Pointer arithmetic on string type arrays, how does C++ handle this?,因为我认为了解正在发生的事情可能有用。
要打印您期望的内容,以下内容将起作用:
cout<<*p<<std::endl;
cout<<*(++p)<<std::endl;
cout<<*(++p)<<std::endl;
或者
{{1}}
或其他各种方式(考虑到其他人所说的优先顺序)
答案 2 :(得分:1)
根据C ++运算符优先级表,后增量的优先级高于解除引用(*)运算符,而预增量和解引用运算符具有相同的优先级。预增量和解除引用运算符也是从右到左的关联。
所以在第一行(cout<<++*p<<std::endl;
)中,*和++从右到左进行评估(首先取消引用,然后是增量)。现在p
仍然指向第一个数组(因为它没有改变),但是(* p)指向第一个字符串的第二个字母(输出显示了这个事实)。
在第二行(cout<<*p++<<std::endl;
)中,首先评估后递增(在检索p
的旧值之后),p
递增,现在指向第二个数组。但在增量之前,p的值在表达式中使用,第二行的输出与第一行完全相同。
在第三行中,首先取消引用p
(指向第二个数组的第一个字母),然后递增(指向第二个数组的第二个字母),并打印该值。
答案 3 :(得分:0)
++*p
。所以增加指针,然后打印。
打印后执行*p++
。打印,然后递增。
答案 4 :(得分: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;