Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
4.4. Инструкции
Выражение вычисляет значение по набору операндов, используя операторы наподобие упомянутых в разделе 4.3. А что делать, если требуется вычислить несколько значений? А что, если что-то необходимо сделать многократно? А как поступить, если надо сделать выбор из нескольких альтернатив? А если нам нужно считать входную информацию и вывести результат? В языке С++, как и во многих языках программирования, для создания таких выражений существуют специальные конструкции.
До сих пор мы сталкивались с двумя видами инструкций: выражениями и объявлениями. Инструкции первого типа представляют собой выражения, которые завершаются точкой с запятой.
a = b;
++b;
Выше приведен пример двух инструкций, представляющих собой выражения. Например, присваивание = — это оператор, поэтому a=b — это выражение, и для его завершения необходимо поставить точку с запятой a=b; в итоге возникает инструкция. Зачем нужна точка с запятой? Причина носит скорее технический характер.
Рассмотрим пример.
a = b ++ b; // синтаксическая ошибка: пропущена точка с запятой
Без точки с запятой компилятор не знает, что означает это выражение: a=b++; b; или a=b; ++b;. Проблемы такого рода не ограничиваются языками программирования. Например, рассмотрим выражение “Казнить нельзя помиловать!” Казнить или помиловать?! Для того чтобы устранить неоднозначность, используются знаки пунктуации. Так, поставив запятую, мы полностью решаем проблему: “Казнить нельзя, помиловать!” Когда инструкции следуют одна за другой, компьютер выполняет их в порядке записи. Рассмотрим пример.
int a = 7;
cout << a << 'n';
Здесь объявление с инициализацией выполняется до оператора вывода. В целом мы хотим, чтобы инструкция имела какой-то эффект. Без эффекта инструкции, как правило, бесполезны. Рассмотрим пример.
1+2; // выполняется сложение, но сумму использовать невозможно
a*b; // выполняется умножение, но произведение не используется
Такие инструкции без эффекта обычно являются логическими ошибками, и компиляторы часто предупреждают программистов об этом. Таким образом, инструкции, представляющие собой выражения, обычно являются инструкциями присваивания, ввода-вывода или вызова функции.
Упомянем еще об одной разновидности: пустой инструкции. Рассмотрим следующий код:
if (x == 5);
{ y = 3; }
Это выглядит как ошибка, и это почти правда. Точка с запятой в первой строке вообще-то не должна стоять на этом месте. Но, к сожалению, эта конструкция в языке С++ считается вполне допустимой. Она называется пустой инструкцией, т.е. инструкцией, которая ничего не делает. Пустая инструкция, стоящая перед точкой с запятой, редко бывает полезной. В нашем случае компилятор не выдаст никакого предупреждения об ошибке, и вам будет трудно понять причину неправильной работы программы.
Что произойдет, когда эта программа начнет выполняться? Компилятор проверит, равно ли значение переменной x числу 5. Если это условие истинно, то будет выполнена следующая инструкция (пустая). Затем программа перейдет к выполнению следующей инструкции, присвоив переменной y число 3. Если же значение переменной x не равно 5, то компилятор не будет выполнять пустую инструкцию (что также не порождает никакого эффекта) и присвоит переменной y число 3 (это не то, чего вы хотели, если значение переменной x не равно 5).
Иначе говоря, эта инструкция if присваивает переменной y число 3 независимо от значения переменной x. Эта ситуация типична для программ, написанных новичкам, причем такие ошибки трудно обнаружить.
Следующий раздел посвящен инструкциям, позволяющим изменить порядок вычислений и выразить более сложные вычисления, чем те, которые сводятся к последовательному выполнению ряда инструкций.
4.4.1. Инструкции выбора
В программах, как и в жизни, мы часто делаем выбор из нескольких альтернатив. В языке С++ для этого используются инструкции if и switch.
4.4.1.1. Инструкции if
Простейшая форма выбора в языке С++ реализуется с помощью инструкции if, позволяющей выбрать одну из двух альтернатив. Рассмотрим пример.
int main()
{
int a = 0;
int b = 0;
cout << "Пожалуйста, введите два целых числа n";
cin >> a >> b;
if (a<b) // условие
// 1-я альтернатива (выбирается, если условие истинно):
cout << "max(" << a << "," << b <<") равно " << b <<"n";
else
// 2-я альтернатива (выбирается, когда условие ложно):
cout << "max(" << a << "," << b <<") равно " << a << "n";
}
Инструкция if осуществляет выбор из двух альтернатив. Если его условие является истинным, то выполняется первая инструкция; в противном случае выполняется вторая. Это простая конструкция. Она существует в большинстве языков программирования. Фактически большинство основных конструкций в языках программирования представляют собой просто новое обозначение понятий, известных всем еще со школьной скамьи или даже из детского сада. Например, вам, вероятно, говорили в детском саду, что, для того чтобы перейти улицу, вы должны дождаться, пока на светофоре не загорится зеленый свет: “если горит зеленый свет, то можно переходить, а если горит красный свет, то необходимо подождать”. В языке С++ это можно записать как-то так:
if (traffic_light==green) go();
if (traffic_light==red) wait();
Итак, основное понятие является простым, но и это простое понятие можно использовать слишком наивно. Рассмотрим неправильную программу (ошибка в ней заключается не только в отсутствии директивы #include).
// преобразование дюймов в сантиметры и наоборот
// суффикс 'i' или 'c' означает единицу измерения на входе
int main()
{
const double cm_per_inch = 2.54; // количество сантиметров
// в дюйме
double length = 1; // длина в дюймах или
// сантиметрах
char unit = 0;
cout<< "Пожалуйста, введите длину и единицу измерения (c или i):n";
cin >> length >> unit;
if (unit == 'i')
cout << length << "in == " << cm_per_inch*length << "cmn";
else
cout << length << "cm == " << length/cm_per_inch << "inn";
}
На самом деле эта программа работает примерно так, как предусмотрено: введите 1i, и вы получите сообщение 1in==2.54cm введите