Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Штерн В. - Основы C++. Методы программной инженерии - 2003

.pdf
Скачиваний:
238
Добавлен:
13.08.2013
Размер:
28.32 Mб
Скачать

90

Hacih I «^ Вве,

охэгрс^;^л^ирово

 

 

short int X = 1, у = 3;

 

 

cout «

"Сумма равна " « x + у «", a ее размер равен

// выводит 4 и 4

 

" «

sizeof(x+y)«endl;

 

Вычисления выполняются не со значениями типа short, а с соответствующими

 

целочисленными значениями. Преобразование достаточно простое. На 16-разряд­

 

ной машине оно тривиально, поскольку типы short и int имеют один размер. На

 

32-разрядной машине к значению short добавляется еиде два байта, заполняемых

 

значением бита знака (О для положительного числа, 1 для отрицательного). При

 

таком приведении размера значение сохраняется.

 

 

Аналогично unsigned char и unsigned short int приводятся к int. На 32-раз­

 

рядной машине это не вызывает проблемы, так как диапазон целых здесь больше,

 

чем диапазон значений short, даже unsigned. На 16-разрядных машинах ситуация

 

иная. Максимальное значение unsigned short здесь равно 65 535, что больше

 

максимального значения int (32 767). Но причин для беспокойства нет. Если

 

значение не помендается в диапазон целого, то компилятор расширяет его до

 

unsigned int. Опять же приведение размера происходит прозрачно для про­

 

граммиста.

 

 

 

Для типов с плаваюидей точкой все происходит подобным же образом. Значения

 

float приводятся к размеру double. Со значениями float

вычисления не выполня­

ются. Когда такое значение считывается из памяти, оно преобразуется к double. Приведение размеров целых типов и типов с плаваюш,ей точкой — нудная

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

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

Компилятор выполняет неявные преобразования:

В выражениях с операндами разных типов

В присваиваниях (согласно типу целевой переменной)

Когда выражения содержат операнды числовых типов разного размера, к "ко­ ротким" операндам применяется "расширяюш,ее" преобразование размера — они приводятся к типу значений большего размера, после чего операция выполняется над операндами одного, большого размера. Если выражение состоит из несколь­ ких операций, то оно вычисляется по правилам ассоциирования операций (обычно слева направо), и на каждом шаге, если это необходимо, преобразуются размеры. Вот иерархия размеров для преобразования в выражениях:

i nt -> unsigned int -> long -> unsigned long -> float -> double -> long double

При таком неявном преобразовании сохраняется значение преобразуемого операнда, однако программист должен убедиться, что необходимое преобразова­ ние имеет место. В противном случае возможна потеря точности результата (см. листинги 3.6 и 3.7).

Преобразования присваивания изменяют тип правой части присваивания — она преобразуется к типу данных цели присваивания (левой части). Сама операция присваивания всегда выполняется с операндами одного типа. В случае усечения возможна потеря точности, но это не синтаксическая ошибка. Многие компилято­ ры по доброте дают предупреждение о потере точности, но в C + + такая операция вполне законна. Если программист этого хочет, то он это и получит. Другими сло­ вами, работаюш,ий с C + + программист имеет все права на подобные действия.

Глава 3 * Работа с данными и выражениями C^-t-

91

Кроме потери точности, неявное преобразо­ вание может давать еще два осложнения: влиять на скорость выполнения и корректность резуль­ татов.

Рассмотрим исходный код в листинге 3.6, преобразующий температуру из градусов по Цельсию в градусы по Фаренгейту. Пример вывода этой программы показан на рис. 3.5.

Введите, пожалуйста, значения в градусах Цельсия: 20 Значение в градусах поФаренгейту: 68

Рис. 3.5- Программа из листинга 3.6 дает корректные результат^ы при неявном преобразовании к double

Листинг 3.6. Демонстрация неявного преобразования типа

#inclucle

<iostream>

 

using namespace std;

 

int mainO

 

{

 

 

 

float

fahr, celsius;

 

cout

«

" Введите, пожалуйста, значения в градусах Цельсия: ";

cin

»

Celsius;

 

fahr = 1.8 * Celsius + 32;

/ / преобразование?

cout «

"Значение в градусах поФаренгейту: " «

fahr « endl;

return

0;

 

}

 

 

 

Литерал 1.8 имеет тип double. Переменная celsius типа float перед умноже­ нием преобразуется к типу double. Литерал 32 имеет тип int и преобразуется перед сложением к double. В итоге складываются операнды одного типа. Резуль­ тат вычисления будет иметь тип double. Так как переменная fahr имеет тип float, то результат вычислений перед присваиванием снова преобразуется. Конечно, эти

. преобразования выполняются очень быстро, но если объем вычислений велик и они многократно повторяются, то быстродействие программы может снизиться. Программист, использующий C+-t-, не должен забывать о производительности или, по крайней мере, быть готовым к обсуждению связанных с нею вопросов.

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

Вот пример использования явных суффиксов типов:

float

fahr,,celsius; ...

 

fahr

= 1.8f * Celsius + 32f;

/ / float приводится к double

A вот пример вычислений с типами double:

 

 

float fahr,

celsius; ...

 

 

 

fahr

= 1.8

* Celsius + 32.0;

/ / преобразований нет

 

 

Даже если производительность — не первоочередная проблема (нередко так оно

 

 

и есть), программу необходимо писать с учетом удобства ее чтения. Для этого

 

 

нужно помнить о вопросах, связанных с неявными преобразованиями. Например,

 

 

при

стандартном преобразовании

значения температуры из градусов Цельсия

 

 

в шкалу Фаренгейта используется коэффициент 9/5. Здесь он для простоты пре­

 

 

вращен в 1,8. Обычно предпочтительнее не считать ничего вручную и реализо­

Введите,

пожалуйста,

значения в градусах Цельсия: 20

вать программу, как показано в листинге 3.7.

Кроме того, это интерактивная программа и в

Значение

в градусах

по Фаренгейту: 52

ней тратится время на ожидание ввода от поль­

 

 

 

 

 

зователя и отображения результата. В таком

Рис. 3 . 6 . Б результат,е

*'опплоэюенного"

случае несколько преобразований ничего не

 

преобразования

к double

меняют. Тот же результат программы пред­

 

программа из лист,инга 3.7 дает

ставлен на рис. 3.6.

 

некорректные

результаты

 

 

92

Часть I # Введение в програ1У1мирование но С^^

Листинг 3.7. Пример потери точности при целочисленных вычислениях

#inclucle

<iostream>

 

using namespace std;

 

int mainO

 

{

 

 

double fahr, Celsius;

 

cout «

" Введите, пожалуйста, значения в градусах Цельсия: ";

Gin »

Celsius;

// точность?

fahr = 9 / 5 * Celsius + 32;

cout «

"Значение в градусах поФаренгейту: " «

fahr << endl;

return 0;

 

}

 

 

Причина некорректности вывода в том, что, вопреки ожиданиям, преобразо­ вание из целого в double здесь не выполняется. Поскольку двоичные операции ассоциируются слева направо, целое 9 делится на целое 5 и результатом станет единица. Если же записать строку так:

fahr = Celsius * 9 / 5 + 32; / / точность?

то все будет иначе. Здесь переменная Celsius имеет тип double и все вычисления выполняются с типом double.

Как можно видеть, программисту требуется инструментальное средство, обес­ печивающее необходимые преобразования. В C++ для этого предлагается приве­ дение типа (cast) — унарная операция высокого приоритета. Она позволяет явно управлять преобразованиями числовых типов. Операция приведения типа состоит из имени типа в скобках перед преобразуемым значением. Например, (double) 9 преобразует целое 9 к double 9.0, а (int) 1.8 преобразует double 1.8 в целое 1. Теперь небольшое пояснение. Все сказанное соответствует тому, как описывают приведение типа программисты. На самом деле 9 ни во что не преобразуется, оно так и остается целым. В программе создается новое значение типа double, числен­ но эквивалентное целому 9.

Внимание говорят, что приведение типа преобразует значение.

На самом деле оно создает значение целевого типа и инициализирует его с помощью числового содержимого операции приведения типа.

Проблемную строку в листинге 3.7 можно переписать, используя явное приве­ дение типа:

fahr = (double)9 / (double)5 * Celsius + (double)32;

Ha самом деле, чтобы избежать проблемы усечения, можно написать:

fahr = (double)9 / 5 * Celsius + 32;

При этом целое 9 преобразуется в double 9.0 и , следовательно, целое значение 5 будет неявно преобразовано в double 5.0.

Такая форма приведения типа унаследована C++ из языка С. Язык C++ под­ держивает еще одну форму приведения типа, аналогичную по синтаксису вызову функции. В ней имя типа указывается без скобок, а операнд заключается в скобки. Если использовать приведение типа C+ + , то вычисления из листинга 3.7 будут выглядеть так:

fahr = double(9) / 5 * Celsius + 32;

Глава 3 • Работа с данньши и выраженияг^и С+4-

93

Кроме того, C++ поддерживает еще четыре дополнительных вида приведения типа: dynamic_cast, static_cast, reinterpret_cast и const_cast. О них будет рассказано позднее. Чтобы показать свои намерения сопровождающему ПО программисту, некоторые применяют явные преобразования к типу, который соответствует выражению. Другие считают, что это только отягощает код и за­ трудняет задачу сопровождения программы. Третьи вовсе не применяют приведе­ ния типа, чтобы не набирать лишнего на клавиатуре.

И еще замечание по вычислению выражений. Уже упоминалось, что операнды обрабатываются слева направо. Это может создать впечатление, что компоненты выражения также вычисляются слева направо, что неверно. C++ не берет на себя никаких обязательств относительно порядка вычисления компонентов выра­ жения. Соблюдается лишь порядок выполнения операций в выражении.

Данное обстоятельство иногда ускользает от внимания программистов. Часто это не важно. Например, в выражении, преобразующем температуру по Цельсию в градусы по Фаренгейту, операции выполняются слева направо. Неважно, в ка­ ком порядке вычисляются значения 9, 5, Celsius и 32. Они не зависят друг от друга. Важно, когда операции с побочными эффектами используются в другом выражении. Каким, например, будет результат в этом случае?

i nt

num = 5, t o t a l ;

 

t o t a l

= num + num++;

/ / 10 или 11?

cout

«

"Сумма равна " « total «

endl;

Поскольку здесь применяется постфиксная операция, значение num использу­ ется в выражении перед инкрементом, поэтому total будет равно 10. Но это предполагает, что компоненты выражения вычисляются слева направо. При вы­ числении справа налево num++ подсчитывается первым. Тогда значение 5 сохраня­ ется для использования в вычислениях, а num становится равным 6. Затем вычисляется левый операнд num, но его значение уже равно 6, поэтому total ста­ новится равным 11, а не 10.

На моей машине результат равен 10. Возможно, на вашей он будет таким же. Это не означает, что C++ делает "незаконной" любую программу, вычисляющую компоненты выражения слева направо. Как преодолеть проблему? Как сделать так, чтобы на всех машинах получалось 10? Вот как:

int num = 5, t o t a l ;

 

// 10, a не 11num++;

total = num + num;

total «

cout «

"Сумма равна " «

endl;

Нужно получить на всех машинах 11 ? Легко:

int num = 5, total;

 

 

int olcl_num = num; num++;

 

 

t o t a l

= num + old_num;

 

/ / 11, a не 10

cout

«

"Сумма равна " «

total «

endl;

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

Итоги

Итак, в C++ достаточно типов и вычислений выражений. Как можно видеть, всегда полезно подумать о диапазоне используемых типов. Это важно как с точки зрения переносимости программы, так и для корректности результатов. Если нет веских причин делать обратное (например, таково желание вашего начальника), то используйте типы int и double, но убедитесь, что они работают корректно.

94 Часть ! # Введение в програ^г^ироеоние на C++

Эта глава охватывала большой объем тем, для усваивания данного материала потребуется некоторое время. Поэкспериментируйте с примерами, вернитесь к главе 2 — используйте ее как основу для работы с С+4-. Не торопитесь при­ менять слишком много продвинутых средств.

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

Убедитесь, что вы знаете, что делаете.

^ ^ / ^

#

• - ^ правление ходом выполнения программы С+ +

Темы данной главы

•^ Операторы и выражения •^ Условные операторы »<^ Итерация

ь^ Операторы перехода в С++

^Итоги

) ^ \ ^

предыдуш,ей главе обсуждались основы программирования на C+ + :

ш ^5fc-'^^"bi данных и операции, позволяющие комбинировать значения раз-

^^^^^^^^ личных типов в выражения. В данной главе рассматривается следую­ щий уровень программирования — реализация алгоритмов для принятия решений и выполнения различных сегментов кода в зависимости от внешних обстоятельств.

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

Когда один сегмент программы выполняется после того или иного сегмента, то наборов начальных условий несколько и возможных результатов вычислений тоже несколько. Запоминать все эти альтернативы становится трудно. Програм­ мисты делают ошибки при разработке программы, а те, кто занимается ее сопро­ вождением, ошибаются при чтении исходного кода и внесении изменений. Вот почему современные языки программирования ограничивают возможности про­ граммиста при передаче управления от одного сегмента программы к другому. Такой подход называется структурным программированием. Программист использует лишь небольшой набор строго заданных конструкций (циклов и опе­ раторов условия), и каждый сегмент программного кода имеет только один вход (или два) и один выход (или два).

96ль I« ВшвА^име в програ1У1^ирование на C++

ВC + + реализован компромиссный подход. Он предлагает богатый набор конструкций, позволяющий управлять выполнением программы. Эти конструк­ ции обладают достаточной гибкостью и мощностью для реализации сложных вариантов принятия решений в программе. В то же время они достаточно строгие

ине способствуют чрезмерной изощренности программы, затрудняющей ее пони­ мание и сопровождение.

Операторы и выражения

в отличие от других языков в C + + разница между выражением и выполняе­ мым оператором мала: любое выражение можно превратить в оператор, добавив точку с запятой. Вот некоторые примеры допустимых выражений и допустимых в C + + выполняемых операторов:

X * у

/ /

выражение,

которое можно использовать в других выражениях

X * у;

/ /

оператор (достаточно бесполезный)

а = X * у

/ /

выражение,

которое можно использовать в других выражениях

а = X * у;

/ /

оператор,

полезный и распространенный

X++

/ /

выражение,

которое можно использовать в других

 

/ /

выражениях

(только аккуратно)

Х++;

/ /

оператор,

полезный и распространенный

foo()

/ /

вызов функции,

возвращающей значение (допустимое выражение)

foo();?

/ /

вызов функции, возвращающей неиспользуемое значение

 

/ /

(допустимый оператор)

;

/ /

пустой оператор, допустимый, но только запутывающий

Как и в других языках, в C + +

операторы выполняются последовательно,

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

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

Объединение операторов в блок дает два важных преимущества. Во-первых, можно использовать блок с несколькими операторами в том месте, где допускает­ ся только один оператор. Во-вторых, можно определять в блоке локальные пере­ менные. Имена таких переменных не будут конфликтовать с именами переменных, определенных в другом месте программы. Первое свойство критически важно для написания управляющих операторов. Без этого невозможно было бы создать ни­ какой реальной программы. Второе свойство имеет важное значение при написа­ нии функций. Без него также не написать реальной программы. Вот обобщенная синтаксическая форма составного оператора:

{ локальные определения и объявления (если они имеются);

 

 

операторы завершаются точкой с запятой; }

/ /

в конце нет

 

/ /

точки с запятой

Составной оператор можно использовать как тело функции, как вложенный блок внутри функций или как тело управляющего оператора. Если поставить после завершающей фигурной скобки точку с запятой, то в большинстве случаев это не повредит. Появится лишь пустой оператор, не генерирующий объектный код. Но иногда такая точка с запятой может изменить смысл операторов, так что лучше не использовать ее после закрывающей фигурной скобки (нужно запомнить исключения, когда такая точка с запятой необходима, как, например, в определе­ нии класса и в некоторых других случаях).

Глава4 • Управление ходом выполнения программы C+-f

97

Составные операторы вычисляются как один оператор — после предыдущего оператора и перед следующим. Внутри блока выполнение также происходит по­ следовательно, в лексическом порядке операторов.

С-(-+ предусматривает стандартный набор операторов управления, которые могут менять ход выполнения программы. Они включают в себя:

условные операторы: if, if-else циклы: while, do-while, for

переходы: операторы goto, break, continue, return

код с несколькими точками входа: оператор switch с ветвями case

В конструкции с условиями, в зависимости от булева выражения в условии, оператор может выполняться один раз или пропускаться. В цикле оператор вы­ полняется один или несколько раз, в зависимости от булева выражения цикла. Булево выражение — это выражение, возвращающее true или false. Его часто называют логическим выражением, выражением условия или просто выражением. В C-f-f любое выражение можно использовать как булево, что значительно уве­ личивает гибкость операторов условия и циклов. В других языках применение небулева выражения там, где предполагается булево выражение, даст синтаксиче­ скую ошибку.

В операторе switch в зависимости от результата вычисления целочисленного выражения выбираются соответствующие ветви case. Операторы перехода меня­ ют ход выполнения программы без всякого условия. Часто они используются в сочетании с некоторыми другими управляющими конструкциями (условным оператором, оператором цикла или переключателем switch).

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

В остальной части данной главы рассмотрены отдельные типы операторов управления выполнением программы С+Н-, даны конкретные рекомендации, что делать и что не следует делать при применении этих управляющих операторов в коде C+-f.

Условные операторы

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

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

Стандартные формы условных операторов

Условные операторы в СН-+ в своей наиболее общей форме имеют две ветви: ветвь true и ветвь false. При выполнении условного оператора отрабатывается только одна ветвь.

Вот несколько примеров условных операторов в контексте с предшествующим и последующим операторами:

г

98

1 4 - I W I O I

 

'гшлтроваиив не

^^^^^^^^^

предыдущии_оператор;

/ /

ключевого слова then в C++ нет

 

i f (выражение)

 

onepaTop_true;

/ /

обратите

внимание на точку с запятой

перед else

else

/ /

обратите

внимание на необязательный

отступ

onepaTop_false;

следующий_оператор;

Ключевые слова if и else должны записываться в нижнем регистре. Ключевое слово then в C++ отсутствует. Выражение должно заключаться в круглые скобки.

После выполнения предыдущего_оператора (им может быть все, что угодно, включая одну из управляющих конструкций) вычисляется выражение в скобках. Логически это булево выражение: нужно знать, принимает условие значение true или false. Еслиусловие дает true, то выполняется onepaTop_true, а onepaTop_falseпропускается. Если условие равно false, то выполняется onepaTOp_false, а операTOp_true пропускается. Поскольку мы изучаем C + + , а не Паскаль, Бейсик, Java или PL/I, ТО выражение в условии не обязано быть булевым. Это может быть любое выражение любой сложности. Вычисляется его значение, и любое ненулевое значение (не обязательно целое) интерпретируется как true, а нулевое — false.

После выполнения одного из операторов (onepaTop_false или onepaTop_true) независимо от условия выполняется следующий_оператор. Опять же этим операто­ ром может быть все, что угодно, включая одну из конструкций управления.

В листинге 4.1 показана программа, запрашивающая у пользователя темпера­ туру в градусах Цельсия, а затем сообщающая, действительно ли это значение (выше абсолютного нуля, т. е. -273 градуса по Цельсию).

Листинг 4 . 1 . Оператор условия

#inclucle <iostream> using namespace std;

int main

()

 

 

 

 

 

 

{

 

 

 

 

 

 

 

 

int

eels;

 

 

 

 

 

 

cout

«

"\пВведите температуру в градусах Цельсия: ";

 

 

cin

»

eels;

 

eels « endl;

 

 

cout «

"\пВы ввели значение " «

 

 

if (eels < -273)

 

"недопустимо\п"

 

 

cout «"\пЗначение " «eels «

/ /

нет ;

else

«

"Оно меньше абсолютного нуля\п";

/ /

один оператор

 

cels«" - допустимая температура\п";

 

 

cout «

 

 

cout «

"Спасибо, чтовоспользовались программой" «endl;

 

 

return 0;

 

 

 

 

 

 

 

 

 

Обратите внимание на использование ESC-последовательности перевода на

 

 

 

новую строку в начале и в конце строк в двойных кавычках, выводимых объектом

 

 

 

cout, а также на применение манипулятора endl в конце программы. Если опера­

Введите температуру в градусах Цельсия: 20

 

ционная система не использует буферизацию вывода,

 

то ме>кду ESC-символом новой строки ' /п' и манипу­

Вы ввели значение 20

 

 

лятором endl разницы нет. При буферизации endl

20 -допустимая температура

программой

 

посылает вывод в буфер и "сбрасывает" его, когда

Спасибо, что

воспользовались

 

он заполняется. Иногда это повышает производитель­

 

 

 

 

 

 

ность программы, но многие программисты не беспо­

Рис. 4.1. Вывод

программЫу

 

коятся об этой разнице.

 

 

 

Вывод программы представлен на рис. 4.1.

представленной

в листинге

4.1

 

 

 

Глава 4 • Управление ходогм! вьтоАнеиия программы C++

99

Обратите внимание на отступы в обобщенном примере условного

оператора

и в листинге 4.1. Обычно ключевые слова if и else

выравниваются

на тот же

уровень, что и предыдущий оператор. OnepaTop_true и onepaTOp_false

часто вы­

равнивают на несколько позиций вправо. Это делает программу более понятной

для сопровождающего ее программиста (и для самого разработчика во время от­

ладки). Глубина выравнивания — дело вкуса. По идее, двух пробелов достаточно.

При более глубоком отступе уменьшится размер строки, особенно, если исполь­

зуются вложенные управляющие конструкции, либо сами операторы

t r u e / f a l s e

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

 

Заметим, что когда вводится недопустимое значение температуры,

программа

выводит две строки. Для этого выполняются операторы:

 

cout «'ЛпЗначение " «eels « " недопустимо\п";

/ / ; в конце

 

cout «

"Оно меньше абсолютного нуля\п";

 

 

 

 

/ /

2 оператора

 

Если

операторы

записываются

таким

образом, то они должны

заключаться

 

в фигурные скобки, т. е. оформляться как составной оператор. Причина в том, что

 

когда программный код используется как часть условного оператора, в каждой

 

ветви есть место только для одного оператора, а не для двух.

 

 

 

А в листинге 4.1 используется

другая техника. Оператор cout может быть

 

сколь угодно длинным и занимать несколько строк (важно лишь, чтобы разрыв

 

строки попадал между компонентами оператора, а не оказывался в середине

 

лексемы). Это означает, что некорректно разбивать строку посередине. Но если

 

нужно выводить две строки, то с этим все в порядке.

 

 

 

 

OnepaTop_false не обязателен. Если некоторые действия должны

выполняться

 

только тогда, когда булево выражения равно true, его можно опустить. Вот обоб­

 

щенная форма условного оператора без onepaTopa_f alse:

 

 

 

предыдущий_оператор;

 

 

 

 

 

 

 

 

i f (выражение)

 

 

 

 

 

 

 

 

 

onepaTop_true;

 

 

 

 

 

 

 

 

 

следующий_оператор;

 

 

 

 

 

 

 

 

Этот условный оператор не содержит ключевых слов

Введите температуру

в градусах

Цельсия: 20

then или else .

Листинг 4.2

показывает

урезанную

 

 

 

 

 

 

 

версию программы из листинга 4.1. Пользователь по­

Вы ввели значение 20

 

 

 

лучает предупреждение о неверном вводе (т. е. тем­

Спасибо, что

воспользовались программой

пература ниже абсолютного нуля), но программа

 

 

 

 

 

 

 

выполняет свою

задачу. (Для простоты здесь ото-

п.,^

>i о

г,

г»

 

 

 

^

 

1

ч тл

гИС. A.Z.

Вывод

программы,

 

бражается только заключительная фраза.) Результат

 

 

 

представленной

в листинге 4.2

выполнения показан на рис. 4.2.

 

 

 

 

 

 

 

 

Листинг 4.2.

Условный оператор без части else

 

 

 

 

 

 

 

#inclucle <iostream> using namespace std;

#define ABSOLUTE_ZERO -273 int main ()

{

int eels;

cout «

"\пВведите температуру в градусах Цельсия: ";

 

cin »

eels;

eels « endl;

 

cout «

"\пВы ввели значение " «

 

if (eels < ABSOLUTE.ZERO)

" недопустимо\п"

 

cout «"\пЗначение " «eels «

// 1 оператор

cout «

« "Оно меньше абсолютного нуля\п";

"Спасибо, чтовоспользовались программой" «endl;

 

return 0;

 

 

Соседние файлы в предмете Программирование на C++