Читаем Язык программирования C++. Пятое издание полностью

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

Совет. Краткость может быть достоинством

Такие выражения, как *iter++, могут быть не очевидны, однако они весьма популярны. Следующая форма записи проще и менее подвержена ошибкам:

cout << *iter++ << endl;

чем ее более подробный эквивалент:

cout << *iter << endl;

++iter;

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

Помните, что операнды могут быть обработаны в любом порядке

Большинство операторов не гарантирует последовательности обработки операндов (см. раздел 4.1.3). Отсутствие гарантированного порядка зачастую не имеет значения. Это действительно имеет значение в случае, когда выражение одного операнда изменяет значение, используемое выражением другого. Поскольку операторы инкремента и декремента изменяют свои операнды, очень просто неправильно использовать эти операторы в составных выражениях.

Для иллюстрации проблемы перепишем цикл из раздела 3.4.1, который преобразует в верхний регистр символы первого введенного слова:

for (auto it = s.begin(); it != s.end() && !isspace(*it) ; ++it)

 it = toupper(*it); // преобразовать в верхний регистр

Этот пример использует цикл for, позволяющий отделить оператор обращения к значению beg от оператора его приращения. Замена цикла for, казалось бы, эквивалентным циклом while дает неопределенные результаты:

// поведение следующего цикла неопределенно!

while (beg != s.end() && !isspace(*beg))

 beg = toupper(*beg++); // ошибка: это присвоение неопределенно

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

*beg = toupper(*beg);       // сначала обрабатывается левая сторона

*(beg + 1) = toupper(*beg); // сначала обрабатывается правая сторона

Или любым другим способом.

Упражнения раздела 4.5

Упражнение 4.17. Объясните различие между префиксным и постфиксным инкрементом.

Упражнение 4.18. Что будет, если цикл while из последнего пункта этого раздела, используемый для отображения элементов вектора, задействует префиксный оператор инкремента?

Упражнение 4.19. С учетом того, что ptr указывает на тип int, vec — вектор vector, a ival имеет тип int, объясните поведение каждого из следующих выражений. Есть ли среди них неправильные? Почему? Как их исправить?

(a) ptr != 0 && *ptr++     (b) ival++ && ival

(с) vec[ival++] <= vec[ival]

<p>4.6. Операторы доступа к членам</p>

Операторы точка (.) (dot operator) (см. раздел 1.5.2) и стрелка (->) (arrow operator) (см. раздел 3.4.1) обеспечивают доступ к члену. Оператор точка выбирает член из объекта типа класса; оператор стрелка определен так, что код ptr->mem эквивалентен коду (*ptr).mem.

string s1 = "a string", *p = &s1

auto n = s1.size(); // вызов функции-члена size() строки s1

n = (*p).size();    // вызов функции-члена size() объекта, на который

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных