Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Каждый объект в множественном операторе присвоения должен иметь тип, совпадающий с типом соседа справа, или допускать преобразование в него (раздел 4.11):
int ival, *pval; // ival имеет тип int; pval имеет тип указателя на int
ival = pval = 0; // ошибка: переменной типа int нельзя присвоить
// значение указателя
string s1, s2;
s1 = s2 = "OK"; // строковый литерал "OK" преобразован в строку
Первое присвоение некорректно, поскольку объекты ival
и pval
имеют разные типы и не существует преобразования типа int*
( pval
) в тип int
( ival
). Оно некорректно, несмотря на то, что значение нуль может быть присвоено любому объекту.
Второе присвоение, напротив, вполне допустимо. Строковый литерал преобразуется в значение типа string
, которое и присваивается переменной s2
типа string
. Результат этого присвоения — строка s2
— имеет тот же тип, что и строка s1
.
Присвоения нередко происходят в условиях. Поскольку оператор присвоения имеет относительно низкий приоритет, его обычно заключают в скобки, чтобы он работал правильно. Чтобы продемонстрировать, чем присвоение может быть полезно в условии, рассмотрим следующий цикл. Здесь необходимо вызывать функцию до тех пор, пока она не возвратит желаемое значение, скажем 42.
// подробный, а потому более подверженный ошибкам
// способ написания цикла
int i = get_value(); // получить первое значение
while (i != 42) {
// выполнить действия ...
i = get_value(); // получить остальные значения
}
Код начинается с вызова функции get_value()
, затем следует цикл, условие которого использует значение, возвращенное этим вызовом. Последним оператором этого цикла является еще один вызов функции get_value()
, далее цикл повторяется. Этот код можно переписать более непосредственно:
int i;
// лучший вариант цикла, теперь вполне понятно, что делает условие
while ((i = get_value()) != 42) {
// выполнить действия ...
}
Теперь условие вполне однозначно выражает намерение разработчика: необходимо продолжать, пока функция get_value()
не возвратит значение 42
. В ходе вычисления условия результат вызова функции get_value()
присваивается переменной i
, значение которой затем сравнивается со значением 42
.
Без круглых скобок операндами оператора !=
было бы значение, возвращенное функцией get_value()
и 42
, а результат проверки ( true
или false
) был бы присвоен переменной i
, чего явно не планировалось!
Поскольку приоритет оператора присвоения ниже, чем у операторов отношения, круглые скобки вокруг присвоений в условиях обычно необходимы.
Тот факт, что присвоение возможно в условии, зачастую имеет удивительные последствия:
if (i = j)
Условие оператора if
присваивает значение переменной j
переменной i
, а затем проверяет результат присвоения. Если значение переменной j
отлично от нуля, то условие истинно. Однако автор этого кода почти наверняка намеревался проверить равенство значений переменных i
и j
так:
if (i == j)
Ошибки такого рода хоть и известны, но трудны для обнаружения. Некоторые, но не все компиляторы достаточно "любезны", чтобы предупредить о таком коде, как в этом примере.
Довольно нередки случаи, когда оператор применяется к объекту, а полученный результат повторно присваивается тому же объекту. В качестве примера рассмотрим программу из раздела 1.4.2:
int sum = 0;
// сложить числа от 1 до 10 включительно
for (int val = 1; val <= 10; ++val)
sum += val; // эквивалентно sum = sum + val
Подобный вид операций характерен не только для сложения, но и для других арифметических и побитовых операторов, которые рассматриваются в разделе 4.8. Соответствующие составные операторы присвоения (compound assignment) существуют для каждого из этих операторов.
+= -= *= /= %= // арифметические операторы
<<= >>= &= ^= |= // побитовые операторы; см. p. 4.8
Каждый составной оператор по сути эквивалентен обычному, за исключением того, что, когда используется составное присвоение, левый операнд обрабатывается (оценивается) только однажды.
Но эти формы имеют одно очень важное различие: в составном операторе присвоения левый операнд вычисляется только один раз. По существу, он эквивалентен следующему:
а = а оператор b;
Если используется обычное присвоение, операнд а
обрабатывается дважды: один раз в выражении с правой стороны и во второй раз — как операнд слева. В подавляющем большинстве случаев это различие несущественно, возможно, кроме тех, где критически важна производительность.
Упражнение 4.13. Каковы значения переменных i
и d
после каждого присвоения?
int i; double d;
(a) d = i = 3.5; (b) i = d = 3.5;
Упражнение 4.14. Объясните, что происходит в каждом из следующих операторов if
?
if (42 = i) // ...
if (i = 42) // ...
Упражнение 4.15. Следующее присвоение недопустимо. Почему? Как исправить ситуацию?
double dval; int ival; int *pi;
dval = ival = pi = 0;
Упражнение 4.16. Хотя ниже приведены вполне допустимые выражения, их поведение может оказаться не таким, как предполагалось. Почему? Перепишите выражения так, чтобы они стали более понятными.
(a) if (p = getPtr() != 0)
(b) if (i = 1024)
4.5. Операторы инкремента и декремента
Операторы инкремента ( ++
) и декремента ( --
) позволяют в краткой и удобной форме добавить или вычесть единицу из объекта. Эта форма записи обеспечивает не только удобство, она весьма популярна при работе с итераторами, поскольку большинство итераторов не поддерживает арифметических действий.
Эти операторы существуют в двух формах: префиксной и постфиксной. До сих пор использовался только префиксный оператор инкремента (prefix increment). Он осуществляет инкремент (или декремент) своего операнда и возвращает измененный объект как результат. Постфиксный оператор инкремента (postfix increment) (или декремента) возвращает копию первоначального операнда неизменной , а затем изменяет значение операнда.
int i = 0, j;
j = ++i; // j = 1, i = 1: префикс возвращает увеличенное значение
Интервал:
Закладка: