为什么会这样呢?

时间:2019-05-28 09:17:45

标签: c++ pointers

关于堆栈?我认为最后一个*p++是不确定的。 *p++*(p++)还是*p;p++;的意思?

void test123()
{

    char s[] = "123", * p;
    p = s;
    // 1 2 3
    cout << *p++ << endl;
    cout << *p++ << endl;
    cout << *p++ << endl;

}
void test321()
{
    char s[] = "123", * p;
    p = s;
    //321
    cout << *p++ << *p++ << *p++ << endl;

}
int main(void)
{
    cout << "123:" << endl;
    test123();
    cout << "123:" << endl;
    test321();
    cout << "hello world" << endl;
    return 0;
}

我认为结果不确定。

2 个答案:

答案 0 :(得分:3)

*p++根据运算符优先级被评估为*(p++)p++的作用是将p加1,然后返回该值在该值之前

来自https://en.cppreference.com/w/cpp/language/operator_incdec

  

递增和递减后创建对象的副本,递增或递减对象的值,并从递增或递减之前返回副本。

即使在您提到的最后一行,p++也会返回位置s+2,因此取消引用位置我们将得到3,而不是下一个地址。

除了求值顺序(在test321中)之外,此代码中没有未定义的行为。

%如果表达式为*++p,它将按照您所说的进行操作(但是,由于每个字符串文字的末尾都为零(\0),因此表达式仍然是不确定的。

答案 1 :(得分:0)

*p++的意思是*(p++)*p;p++,因为它们是相同的。

第一个++的优先级高于*,因此首先计算。然后取消引用发生。在两种情况下。事实是,p++返回了增量之前的值,如C ++标准所述。

最后,正如在评论中所说的那样,在C ++ 17中,评估顺序得到了改进,因此test321行为得到了明确定义。在C ++ 11中,确实不是

p指向\0的事实在C ++ 17中也得到了很好的定义(在C ++ 11中它也指向相同的值,因为您有4个字符,而不仅仅是3个字符)。即使使用附加的++,它也仍然是明确定义的,除非您取消引用该值。但是,指向数组的末尾也定义得很好,这就是向量可以起作用的原因。