Подтвердить что ты не робот

Пост-инкремент и концепция предварительного инкремента?

Я не понимаю понятия постфикса и приращения приращения или уменьшения. Может ли кто-нибудь дать лучшее объяснение?

4b9b3361

Ответ 1

Все четыре ответа пока неверны в том смысле, что они утверждают определенный порядок событий.

Полагая, что "городская легенда" привела многих начинающих (и профессиональных) в заблуждение, то есть к бесконечному потоку вопросов о неопределенном поведении в выражениях.

Так.

Для встроенного префиксного оператора C++,

++x

увеличивает x и производит (как результат выражения) x как lvalue, тогда как

x++

увеличивает x и выдает (как результат выражения) исходное значение x.

В частности, для x++ нет никакого временного упорядочения, подразумеваемого для приращения и получения исходного значения x. Компилятор может свободно генерировать машинный код, который выдает исходное значение x, например, он может присутствовать в каком-либо регистре и который задерживает приращение до конца выражения (следующей точки последовательности).

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

Ответ 2

int i, x;

i = 2;
x = ++i;
// now i = 3, x = 3

i = 2;
x = i++; 
// now i = 3, x = 2

"Сообщение" означает "после", то есть приращение выполняется после считывания переменной. "Pre" означает раньше - поэтому значение переменной сначала увеличивается, а затем используется в выражении.

Ответ 3

Никто не ответил на вопрос: Почему это понятие запутывает?

В качестве основного специалиста в области компьютерных наук мне потребовалось некоторое время, чтобы понять это из-за способа чтения кода.

Неправильно следующее:


x = y ++

X равно y пост. Что логически показалось бы, что X равно значению Y после, выполняется операция приращения. Опубликовать значение после.

или

x = ++ y
X равно y pre -increment. Что логически показалось бы, что X равно значению Y до, выполняется операция приращения. Pre означает до.


Как это работает, на самом деле наоборот. Эта концепция запутанна, потому что язык вводит в заблуждение. В этом случае мы не можем использовать слова для определения поведения.
x = ++ y фактически считывается, поскольку X равно значению Y после приращения.
x = y ++ фактически считывается, поскольку X равно значению Y до приращения.

Слова pre и post назад относительно семантики английского. Они означают только то, где ++ есть отношение Y. Больше ничего.

Лично, если бы у меня был выбор, я бы переключил значения ++ y и y ++. Это всего лишь пример идиомы, которую я должен был изучить.

Если есть метод этого безумия, я хотел бы знать простым языком.

Спасибо за чтение.

Ответ 4

Разница между приращением постфикса, x++ и приращением префикса, ++x, находится точно в , как, два оператора оценивают свои операнды. Постерическое приращение концептуально копирует операнд в память, увеличивает исходный операнд и, наконец, дает значение копии. Я думаю, это лучше всего иллюстрируется реализацией оператора в коде:

int operator ++ (int& n)  // postfix increment
{
    int tmp = n;
    n = n + 1;
    return tmp;
}

Вышеприведенный код не будет компилироваться, потому что вы не можете переопределять операторы для примитивных типов. Компилятор также не может сказать здесь, что мы определяем постфиксный оператор, а не префикс, но допустим, что это правильный и действительный С++. Вы можете видеть, что постфиксный оператор действительно действует на свой операнд, но он возвращает старое значение до приращения, поэтому результатом выражения x++ является значение до приращения. x, однако, увеличивается.

Приращение префикса также увеличивает его операнд, но он дает значение операнда после приращения:

int& operator ++ (int& n)
{
    n = n + 1;
    return n;
}

Это означает, что выражение ++x оценивается значением x после приращения.

Легко думать, что выражение ++x поэтому эквивалентно присваиванию mnet (x=x+1). Это не совсем так, потому что приращение - это операция, которая может означать разные вещи в разных контекстах. В случае простого примитивного целого, действительно, ++x подставляется под (x=x+1). Но в случае типа класса, такого как итератор связанного списка, приращение приставки итератора наиболее определенно не означает "добавление одного к объекту".

Ответ 5

Это довольно просто. Оба будут увеличивать значение переменной. Следующие две строки равны:

x++;
++x;

Разница заключается в том, что вы используете значение переменной, которая увеличивается:

x = y++;
x = ++y;

Здесь обе линии увеличивают значение y на единицу. Однако первый присваивает значение y до приращения к x, а второе присваивает значение y после приращения к x.

Таким образом, существует только разница, когда приращение также используется как выражение. Приращения после инкремента после возврата значения. Предварительное приращение увеличивается до.

Ответ 6

int i = 1;
int j = 1;

int k = i++; // post increment
int l = ++j; // pre increment

std::cout << k; // prints 1
std::cout << l; // prints 2

Приращение вставки означает, что значение i увеличивается после того, как ему присвоено значение k. Однако предварительное приращение означает, что значение j увеличивается до того, как оно назначено на l.

То же самое относится к декременту.

Ответ 7

Сообщение приращение (a++)

Если int b = a++, то это означает

int b = a;

a = a+1;

Здесь мы добавляем 1 к значению. Значение возвращается до увеличения

Например, а = 1; b = a++;

Тогда б = 1 и а = 2

Предварительное увеличение (++a)

Если int b = ++a; тогда это значит

a=a+1;

int b=a ;

Предварительное увеличение: это добавит 1 к основному значению. Значение будет возвращено после увеличения, для a = 1; b = ++a; Тогда b = 2 и a = 2.

Ответ 8

Поскольку теперь у нас есть встроенные фрагменты JavaScript, я мог бы также добавить интерактивный пример увеличения до и после. Это не C++, но концепция остается прежней.

let A = 1;
let B = 1;

console.log('A++ === 2', A++ === 2);
console.log('++B === 2', ++B === 2);

Ответ 9

Постинкрементный (x++) инкремент происходит при следующей инструкции:

Пример пост-увеличения:

  static void Main(string[] args)
    {
        int x = 0;
        int y= Method(x++);//x=0
        Console.WriteLine(x);// now x=1
        Console.WriteLine(y);// but y=0;
    }
    public static int  Method(int x)
    {
       //when called value of x=0;
        return x;//returns 0

    }

Приращение Pre_increament (++x) происходит в текущем операторе

Пример предварительного увеличения:

  static void Main(string[] args)
    {
        int x = 0;
        int y= Method(++x);//x=1
        Console.WriteLine(x);// now also  x=1
        Console.WriteLine(y);//y is 1
    }
    public static int  Method(int x)
    {

       //inside x=1;
        return x; //returns 1

    }

Ответ 10

Из стандарта C99 (С++ должен быть тем же самым, если запретить странную перегрузку)

6.5.2.4 Операторы приращения и уменьшения постфикса

Ограничения

1 Операнд пошагового приращения или декремент должен иметь квалифицированных или неквалифицированных реальных или тип указателя и должен быть модифицируемым именующий.

Семантика

2 Результат postfix ++ оператор - значение операнда. После того как результат будет получен, значение операнда увеличивается. (То есть значение 1 к нему добавляется соответствующий тип.) См. обсуждения аддитивных операторов и составное назначение для информацию об ограничениях, типах и конверсий и эффектов операции над указателями. Сторона эффект обновления сохраненного значения операнд должен происходить между предыдущей и следующей точки последовательности.

3 Постфикс-оператор аналогичен оператору postfix ++, кроме что значение операнда уменьшается (т.е. значение 1 из соответствующий тип вычитается от него).

6.5.3.1 Операторы приращения и уменьшения префиксов

Ограничения

1 Операнд приращения префикса или декремент должен иметь квалифицированных или неквалифицированных реальных или тип указателя и должен быть модифицируемым именующий.

Семантика

2 Значение операнда Оператор prefix ++ увеличивается. результатом является новое значение операнда после инкремента. Выражение ++ E эквивалентно (E + = 1). См. Обсуждения аддитивных операторов и сложное присвоение информации о ограничения, типы, побочные эффекты и конверсий и эффектов операции с указателями.

3 Префикс - оператор аналогичен для оператора prefix ++, за исключением того, что значение операнда убавления.

Ответ 11

Предварительное инкремент до значения приращения ++ например:

(++v) or 1 + v

Пошаговое приращение после увеличения значения ++ например:

(rmv++) or rmv + 1

Программа:

int rmv = 10, vivek = 10;
cout << "rmv++ = " << rmv++ << endl; // the value is 10
cout << "++vivek = " << ++vivek; // the value is 11

Ответ 12

Вы также должны знать, что поведение операторов postincrement/decment отличается в C/С++ и Java.

Учитывая

  int a=1;

в C/С++ выражение

 a++ + a++ + a++

оценивается до 3, а в Java - до 6. Угадайте, почему...

Этот пример еще более запутанным:

cout << a++ + a++ + a++ << "<->" << a++ + a++ ;

печатает 9 ↔ 2!! Это связано с тем, что вышеупомянутое выражение эквивалентно:

operator<<( 
  operator<<( 
    operator<<( cout, a++ + a++ ), 
    "<->"
  ), 
  a++ + a++ + a++ 
)