Результаты печати указателей объектов в обратном порядке - PullRequest
0 голосов
/ 18 мая 2018

Я пытался использовать указатель для перебора массива объектов.Кажется, что печать значений по одному работает нормально, но это дает результат в обратном порядке, когда я пытаюсь распечатать их все вместе.

#include<iostream>
using namespace std;

class car{
    int tires;
public:
    car(int a) {tires = a;};
    int GetTires(){return tires;};
};

int main() {
    car array[4] = { 2, 4, 6, 8 };
    car *p;

    p = array;
    cout << ((p++)->GetTires()) << " " << ((p++)->GetTires()) << " " << ((p++)->GetTires())  << " "  << ((p++)->GetTires()) << endl;
   //Prints: 8 6 4 2 

    p = array;
    cout << ((p++)->GetTires()) << " ";
    cout << ((p++)->GetTires()) << " ";
    cout << ((p++)->GetTires()) << " ";
    cout << ((p++)->GetTires()) << " " << endl;
    //Prints: 2 4 6 8

    return 0;
}

Использование функции C printf также дает тот же результат.Кто-нибудь может объяснить, почему это происходит?ТИА.

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Код

cout << ((p++)->GetTires()) << " " << ((p++)->GetTires()) << " " << ((p++)->GetTires())  << " "  << ((p++)->GetTires()) << endl;

не делает то же самое, что и

    cout << ((p++)->GetTires()) << " ";
    cout << ((p++)->GetTires()) << " ";
    cout << ((p++)->GetTires()) << " ";
    cout << ((p++)->GetTires()) << " " << endl;

Вот как выглядит типичный оператор << 100 * <pre>ostream& operator<<(ostream& os, const Type& dt) { os << dt.value; return os; }

Что происходит в первой строкеэтот компилятор будет оценивать все подвыражения, которые содержат оператор приращения.Порядок оценки не определен стандартом, но может не соответствовать направлению исполнения.В результате первое подвыражение вычисляется первым, а приращение переносится в третье третье выражение и т. Д.

0 голосов
/ 18 мая 2018

Если вы используете компилятор старше C ++ 17, то порядок (p++)->GetTires() вычислений в std::cout::operator << не определен.Таким образом, ваш код производит неопределенное поведение.Другой компилятор или ваш компилятор с другими настройками компилятора может выдавать другой вывод из-за другого порядка оценки.

Между предыдущей и следующей точкой последовательности, предыдущее значение скалярного объекта, которое модифицируется вычислениемвыражение, должно быть доступно только для определения значения, которое будет сохранено.Если к нему обращаются любым другим способом, поведение не определено.

cout << i << i++; // undefined behavior (until C++17)
a[i] = i++; // undefined behavior (until C++17)

Рекомендовать прочитать: Какие гарантии порядка оценки введены в C ++ 17?

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