指向算术的指针

时间:2012-02-20 10:18:16

标签: c++ pointer-arithmetic

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

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

5 个答案:

答案 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;