Почему этот результат? - PullRequest
0 голосов
/ 28 мая 2019

Это о стеке? Я думаю, что последний *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 ]

3 голосов
/ 28 мая 2019

*p++ оценивается как *(p++) в соответствии с приоритетом оператора.И что p++ делает то, что увеличивает p на 1 и возвращает значение до увеличения .

С https://en.cppreference.com/w/cpp/language/operator_incdec

Постинкременти пост-декремент создает копию объекта, увеличивает или уменьшает значение объекта и возвращает копию до увеличения или уменьшения.

Даже в последней строке, которую вы упомянули, p++возвращает позицию s+2, поэтому разыменовывая ее, мы получаем 3, а не следующий ей адрес.

За исключением порядка вычисления (в test321), в этом коде нет неопределенного поведения.

% Если бы выражение было *++p, оно бы сделало именно то, что вы сказали (однако оно по-прежнему не определено, поскольку каждый строковый литерал заканчивается на ноль (\0).

0 голосов
/ 28 мая 2019

*p++ означает *(p++) и *p;p++, потому что они одинаковы.

Первый ++ имеет более высокий приоритет над *, поэтому он вычисляется первым. Тогда происходит разыменование. В обоих случаях. Дело в том, что p++ возвращает значение до приращения, как объяснено в стандарте C ++.

Наконец, как было сказано в его комментариях, в C ++ 17 порядок оценки был улучшен, так что поведение test321 четко определено. В C ++ 11 это действительно , а не .

Тот факт, что p указывает на \0, также хорошо определен в C ++ 17 (он также будет указывать на то же значение в C ++ 11, потому что у вас есть 4 символа, а не только 3). Даже с дополнительным ++ оно все равно будет четко определено, если только вы не разыменуете значение. Но просто указание на конец массива также хорошо определено, и поэтому векторы могут работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...