Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык программирования Сpp 25.09.11 (2).doc
Скачиваний:
16
Добавлен:
19.08.2019
Размер:
10.09 Mб
Скачать

1.5. Операции и выражения

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

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

i=1; /* читается как переменной с именем i присвоить значение равное единице */

j=2; /* переменной j присвоить значение равное 2 */

k=i+j; /*переменной k присвоить значение равное сумме значений двух предыдущих переменных */

radius=1.23;/* Переменной radius присвоили значение 1.23. Обратите внимание, что для отделения дробной части используется точка */

L_kruga =2* 3.1416*radius; // Нашли длину окружности с указанным

// выше радиусом

Вы уже наверное поняли, что переменным целого типа можно присваивать только целые значения, а переменным объявленным как переменные с плавающей точкой присваиваются дробные числа. Впрочем, последнее необязательно. Если вы запишите, что radius=2, то С++ поймет, что целое нужно преобразовать в дробь вида 2.0, если конечно radius объявлен как дробное число, например, типа double. Кроме того, вы видите, что оператор присваивания можно использовать в арифметических выражениях.

Операцию присваивания можно сочетать с объявлением типа переменных, например,

int i=1;

float pi=3.1416, e=2.718;

Присваивание первоначального значения называется инициализацией. В приведенном примере объявление и инициализация объеденены в одной строке.

Кроме того в С++ рарешены множественные присваивания, например,

int a,b,c;

a=b=c=0;

Множественное присваивание нельзя осуществлять вместе с объявлением.

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

В языке С++ определены 4 арифметических действия, или говоря иначе 4 операции. Это сложение, вычитание, умножение и деление. Для сложения используется знак «плюс» (+), для вычитания - «минус» (-), для умножения - «звездочка» (*), для деления – «косая черта» (/). Вообще говоря, есть еще одно действие - так называемое деление по модулю (%). Деление по модулю применяется для целых чисел. Результатом операции является остаток. Например, 5%2=1, 17%5=2 . Последовательность выполнения операций в С++ та же, что и в арифметике, т.е. сначала выполняется умножение и деление, затем сложение и вычитание. Например,

radius=dlinaOkruznosty/(2*pi);

perimeter=2*(L1+L2);

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

Мы уже сказали, что в данном примере представлены выражения. Давайте дадим определение этому понятию. Выражение это ограниченная точкой с запятой последовательность действий записанных с помощью операторов.

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

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

1) 2+3=5 5) 2.0*3=6.0

2) 2.0+5=5.0 6) 7/2=3

3) 2*3=6 7) 7.0/2=3.5

4) 2.0*3.0=6.0 8) 7/2.0=3.5

Обратите внимание на неожиданный результат примера 6. А вот пример в виде фрагмента программы

int n=1,m=2,k=3;

int l=3.94; // Возможна ошибка (l=3)

double x=4.0,y=5.0,z=6.0;

n=m+k; // n=5 результат int

n=n+2; // n=7 результат int

x=5.0*n; // x=35.0 результат double

y=m/3.0; // y=0.666667 результат double

z=m*z/(x+y); // z=0.336449 результат double

m=7.0/z; // Возможна ошибка (m=20 результат int)

n=z; // Возможна ошибка (n=0 результат int)

x=2; // Возможна ошибка (x=2.0 результат double)

. . . . . . .

При компилировании программы происходит проверка на соответствие типов. И большинство компиляторов укажет на ошибку во второй и в последних трех строках программы. Некоторые компиляторы сделают предупреждение о возможной ошибке. В «Borland 6» эти строки не будут рассматриваться как ошибка, переменные примут значения указанные в скобках. Этот компилятор автоматически преобразует результат в тип переменной которой он присваивается. Вообще правило таково - значение одного типа нельзя присваивать переменным другого типа.

Этот пример показывает, что при выполнении программы происходит неявное преобразование типов. Cначала результат преобразуется в тип который соответствует операнду с большим количеством занимаемо который памяти, затем в тип, который указан слева от знака присваивания =. Это естественно, т.к. для результата уже зарезервирован определенный размер памяти. Возвращаясь к примеру инструкция z=2/3 даст результатат z=0 в то время как при z=2.0/3 результат z=0.666667 . Иногда, особенно при проведении вычислений, требуется произвести явное преобразование типов, это можно сделать с помощью инструкции вида (имя типа)тип . Поясним это на уже приведенном примере z=(double) 2/3. В этом случае результат деления преобразуется в тип double, который присваивается переменной z. Обратите внимание, что результат явного преобразования должен быть присвоен соответствующей переменной, иначе компилятор будет рассматривать инструкцию как ошибку, т.е. запись (double) 2/3 считается ошибочной.

Нужно подчеркнуть, что правило явного преобазования справедливо для всех базовых типов, т.е. возможны преабразования (bool)char, (char)int, (double)char и т.п. Часто преобразования связаны с уменьшением объема памяти, например (short int) 3.14/2.87. Результат усечения зависит от реализации компилятора.

Не стоит полагаться на то, что компилятор правильно понимает ход ваших мыслей. Перед тем как записать в программе выражение для вычисления постарайтесь его упростить, и главным образом понять, как бы вы его сами вычислили. Указанное в программе выражение выполняется компьютером так, как оно записано, даже если его можно значительно упростить, приведя подобные члены, и сделав сокращения. Так, например, если вы запишите выражение (10+20)*x/10, то вместо того, чтобы вычислит значение 3*x компьютер будет производить лишние действия (в данном случае это сложение и деление), которые могут существенно увеличить время выполнения задачи, если такого рода вычисления многократно повторяются.

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

Вернемся теперь к программе, которую мы начали писать. Теперь ее можно завершить, например, так

/* Программа расчета длины окружности */

main{

float pi=3.1416, L_kruga, R_kruga;

R_kruga=10; /*присвоили переменной с плавающей точкой

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

* соответствующий вид */

L_kruga=2*pi* R_kruga; // Находим длину окружности

}

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

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

char symbol=’$’;

Обратите внимание на то, что присваиваемый символ записывается в одинарных кавычках.

Вообще все операции делятся на одноместные или унарные, двухместные или бинарные и трехместные или тернарные. С первыми двумя типами познакомимся поближе.

Унарные операции.

Вы уже поняли, что присваивание это унарная операция. Такого рода операций достаточно много. Например, присваивание нового значения переменной с использованием ее прежнего значения:

n=n+1; /* n увеличивается на единицу относительно своего

предыдущего значения*/

Напомним что в С++ знак = означает не равенство а присваивание.

k=k-5; /* k уменьшается на 5 относительно присвоенного ранее

значения*/

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

n++; // эквивалентно записи n=n+1;

++n; // тоже самое, что и в предыдущем случае.

Несмотря на то, что в обоих случаях n увеличивается на единицу, происходит это по-разному, и это можно показать на примере.

n=25; m=25;

k1=++n; /* сначала увеличивается n, затем происходит

присваивание вого значения, k1 становится равным 26,

n=26 */

k2=m++; /* сначала происходит присваивание старого значения

k2=25, затем увеличение m =26. */

Тоже самое можно повторить для операции декремент

k3= - -n; k4=n - -;

Если вы все поняли, то попробуйте определить значение

k5=++n++;

Не следует думать, что отныне инкремент и декремент нужно записывать только таким экзотическим способом использованием двух плюсов или минусов. Если вам понятнее запись:

n=n+1; m=m-1;

пользуйтесь ею.

Существуют и другие не менее экзотические унарные операции, некоторые из которых приведены в таблице

Пример

Эквивалент

n +=2;

n=n+2;

n -=2;

n=n-2;

n*=2;

nr=2* n;

n/=m;

n=n/m;

n %=100;

n=n%100;

m*=(n1+n2);

m=m*(n1+n2);

Числа n и m не обязательно должны иметь тип int.

В программах операции инкремента и декремента могут употребляться без знака равенства. Вот пример такой программы:

main{

int i=1,j=3;

i++; // i стало равным 2

j--; // j также равно 2

}

Бинарные операции.

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

z=x+y;

z=x-y;

z=x*y;

z=x/y;

Напомним, что для чисел типа int применима операция деления по модулю

z=i%j;

Удивительно, но операция

w=x+y+z;

также относится к бинарным. В ней всегда заняты 2 места, сначала складываются x и y, затем к результату добавляется z. Тернарные операции мы рассмотрим позднее, а сейчас займемся последовательностью выполнения операторов.

Читатель вероятно понял, что язык программирования был бы очень беден если бы он ограничивался только арифметическими операциями. На самом деле список операторов покрывает все требования программиста. И сейчас мы рассмотрим некоторые из них.