Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Книга C++.doc
Скачиваний:
24
Добавлен:
10.11.2019
Размер:
2.48 Mб
Скачать

Выражения

В C++ имеется множество форм операторов и выражений. Например, присваивание является выражением. Следующее допустимо в C++:

а = b + (с = d + 3);

Использование арифметических выражений в C++ согласуется с обычной практикой, Одно важное отличие состоит в том, что результат оператора деления ( / ) зависит от типа аргументов.

а = 3 / 2; //Результат деления - 1

а = 3 / 2.0; //Результат деления – 1.5

Второе важное отличие заключается в том, что в C++ принята терпимая позиция по отношению к смешению типов и автоматическому преобразованию, C++ допускает расширяющие преобразования типов, так что int может быть расширен до double при присваивании. С другой стороны, в C++ разрешаются присваивания с преобразованием к более узкому типу; так, double может быть присвоен типу int и даже char.

int i ;

char ch;

double b =1.9;

i = b / 2.0; //i присвоено значение 0

ch ='A' + 1.0; //ch равно 'В'

Такое либеральное отношение C++ к преобразованиям потворствует плохому стилю программирования и не должно поощряться. Сужающие тип преобразования и смешанные типы могут влиять на правильность программы и должны применяться с осторожностью.

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

Операторы сравнения: меньше (<), больше(>), меньше или равно (<=), больше или равно (>=)

Операторы равенства: равно (==), не равно (!=).

Логические операторы: (унарное)отрицание (!), логическое и (&&), логическое или(||)

Для операторов сравнения, равенства и логических, также как и для всех остальных, существуют правила приоритета и порядка выполнения, точно определяющие, как должны вычисляться выражения, содержащие эти операторы. Оператор отрицания ! является унарным (т.е. выполняется над одним данным). Все остальные операторы сравнения, равенства и логические операторы — бинарные (т.е. выполняется над двумя данными). Они действуют на выражения и вырабатывают булевские значения false или true. Это заменяет более раннее соглашение C++, когда типа bool в языке не существовало, и за false принимался ноль, а за true —не ноль. Однако там, где ожидается логическое значение, арифметическое выражение автоматически преобразуется в соответствии с этим соглашением, так что ноль понимается как false, а не ноль — как true. To есть старый стиль программирования по-прежнему работает корректно.

Одна из "ловушек" C++ заключается в том, что операторы равенства и присваивания визуально похожи. Выражение а = = b является проверкой на равенство, тогда как а = b — это выражение присваивания. Одна из наиболее распространенных ошибок программирования на C++ может выглядеть как-нибудь так:

if (i = 1)

//делать что-нибудь

Конечно, подразумевалось

if (i == 1)

//делать что-нибудь

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

Логические операторы !, && и || вырабатывают булевское значение true или false. Логическое отрицание может быть применено к любому выражению. Если выражение имело значение false, то его отрицание выработает true.

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

При вычислении выражений, являющихся операндами && и ||, процесс вычисления прекращается, как только известен результат, true или false. Это называется вычислением по короткой схеме (short-circuit evaluation). Пусть expr1 и expr2 — выражения. Если expr1 имеет значение false, то в

expr1 && expr2

expr2 не будет вычисляться, поскольку значение логического выражения уже определено как false. Аналогично, если expr1 есть true, то в

expr2 || expr2

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

Из всех операторов C++ у оператора запятая самый низкий приоритет. Это бинарный оператор с выражениями в качестве операндов. В выражении с запятой вида

expr1 , expr2

первым вычисляется expr1, затем expr2. Все выражение с запятой в целом имеет значение и тип своего правого операнда. Например,

sum = 0, i = 1

Если i была объявлена как целое, то данное выражение с запятой имеет значение 1 и тип int.. Порядок выполнения операторов запятая — слева направо.

Условный оператор ? : необычен тем, что это тройной оператор. Он принимает в качестве операндов три выражения. В конструкции

expr1 ? expr2 : ехрr3

первым вычисляется выражение expr1. Если оно истинно, то вычисляется expr2, и оно становится значением условного выражения в целом. Если expr1 ложно, то вычисляется ехрr3, и уже оно становится значением условного выражения в целом.

В следующем примере условный оператор используется для присваивания переменной х наименьшего из двух значений:

х = (у < z) ? у : z;

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

Тип условного выражения expr1 ? expr2 : ехрr3 определяется операндами expr2 и ехрr3. Если они разных типов, то применяются обычные правила преобразования. Тип условного выражения не может зависеть от того, какое из двух выражений expr2 или ехрr3 будет вычислено. Порядок выполнения условных операторов ? : — справа налево.

В C++ также имеется оператор sizeof, который используется для определения того, сколько байт потребуется для хранения конкретного объекта.

i= sizeof(int); //переменной i присвоится значение 4

double dbl;

i=sizeof(dbl); // переменной i присвоится значение 8