Операции инкремента и декремента
Операции инкремента (++) и декремента (--) дают возможность компактной и удобной записи для изменения значения переменной на единицу. Чаще всего они используются при работе с массивами и коллекциями – для изменения величины индекса, указателя или итератора:
#include <vector> #include <cassert> int main() { int ia[10] = {0,1,2,3,4,5,6,7,8,9}; vector<int> ivec( 10 ); int ix_vec = 0, ix_ia = 9; while ( ix_vec < 10 ) ivec[ ix_vec++ ] = ia[ ix_ia-- ]; int *pia = &ia[9]; vector<int>::iterator iter = ivec.begin(); while ( iter != ivec.end() ) assert( *iter++ == *pia-- ); |
}
Выражение
ix_vec++
является постфиксной формой оператора инкремента. Значение переменной ix_vec
увеличивается после того, как ее текущее значение употреблено в качестве индекса. Например, на первой итерации цикла значение ix_vec
равно 0. Именно это значение применяется как индекс массива ivec, после чего ix_vec
увеличивается и становится равным 1, однако новое значение используется только на следующей итерации. Постфиксная форма операции декремента работает точно так же: текущее значение ix_ia берется в качестве индекса для ia, затем ix_ia
уменьшается на 1.
Существует и префиксная форма этих операторов. При использовании такой формы текущее значение сначала уменьшается или увеличивается, а затем используется новое значение. Если мы пишем:
// неверно: ошибки с границами индексов в // обоих случаях int ix_vec = 0, ix_ia = 9; while ( ix_vec < 10 ) |
ivec[ ++ix_vec ] = ia[ --ix_ia ];
значение ix_vec
увеличивается на единицу и становится равным 1 до первого использования в качестве индекса. Аналогично ix_ia
получает значение 8 при первом использовании. Для того чтобы наша программа работала правильно, мы должны скорректировать начальные значения переменных ix_ivec и ix_ia:
// правильно int ix_vec = -1, ix_ia = 8; while ( ix_vec < 10 ) |
ivec[ ++ix_vec ] = ia[ --ix_ia ];
В качестве последнего примера рассмотрим понятие стека. Это фундаментальная абстракция компьютерного мира, позволяющая помещать и извлекать элементы в последовательности LIFO (last in, fist out – последним вошел, первым вышел). Стек реализует две основные операции – поместить (push) и извлечь (pop).
Текущий свободный элемент называют вершиной стека. Операция push присваивает этому элементу новое значение , после чего вершина смещается вверх (становится на 1 больше). Пусть наш стек использует для хранения элементов вектор. Какую из форм операции увеличения следует применить? Сначала мы используем текущее значение, потом увеличиваем его. Это постфиксная форма:
stack[ top++ ] = value;
Что делает операция pop? Уменьшает значение вершины (текущая вершина показывает на пустой элемент), затем извлекает значение. Это префиксная форма операции уменьшения:
int value = stack[ --top ];
(Реализация класса stack
приведена в конце этой главы. Стандартный класс stack
рассматривается в разделе 6.16.)
Упражнение 4.8
Как вы думаете, почему язык программирования получил название С++, а не ++С?