- •3. Лекция: Выражения и операции
- •Выражения
- •Приоритет и порядок выполнения операций
- •Перегрузка операций и методов
- •Преобразования типов
- •Организация программного проекта ConsoleExpressions
- •Операции высшего приоритета
- •Выражения в скобках
- •Операция индексации a[I, j]
- •Операция new
- •Операции sizeof и typeof
- •Операции "увеличить" и "уменьшить" (increment, decrement)
- •Унарные операции приоритета 1
- •Операция кастинга - приведения к типу
- •Проверяемые и непроверяемые блоки и выражения
- •Арифметические операции
- •Вычисление выражений
- •Память и время - два основных ресурса
- •Именованные константы
- •Операции отношения
- •Операции проверки типов
- •Операции сдвига
- •Логические операции
- •Логические операции над булевскими операндами
- •Логические операции над булевскими операндами и целыми числами. Работа со шкалами
- •Условное выражение
- •Операция присваивания
- •Операция ?? - новая операция c# 2.0
- •Лямбда-оператор - новая операция в c# 3.0
- •Преобразования внутри арифметического типа
- •Выражения над строками. Преобразования строк
- •Преобразования строкового типа в другие типы
- •Метод Parse
- •Преобразование в строковый тип
- •Класс Convert и его методы
- •Класс Console и его методы
- •Методы Read и ReadLine
- •Вывод данных на консоль. Методы Write и WriteLine
- •Вычисление выражений. Оценка времени вычислений
- •Геометрические фигуры
- •Преобразования типов
- •Проекты
-
Арифметические операции
В языке C# имеются обычные для всех языков арифметические операции - "+, -, *, /, %". Все они перегружены. Операции "+" и "-" могут быть унарными и бинарными. Унарные операции приписывания знака арифметическому выражению имеют наивысший приоритет среди арифметических операций. К следующему приоритету относятся арифметические операции типа умножения, к которому относятся три операции - умножения, деления и взятия остатка. Все эти операции перегружены и определены для разных подтипов арифметического типа. Следует, однако, помнить, что арифметические операции не определены над короткими числами (byte, short) и начинаются с типа int.
Операция деления "/" над целыми типами осуществляет деление нацело, для типов с плавающей и фиксированной точкой - обычное деление. Операция "%" возвращает остаток от деления нацело и определена не только над целыми типами, но и над типами с плавающей точкой. Тип результата зависит от типов операндов. Приведу пример вычислений с различными арифметическими типами:
/// <summary>
/// Арифметические операции
/// </summary>
public void Ariphmetica()
{
byte b1 = 7, b2 = 3, b3;
b3 = (byte)(b1 / b2);
int n = -7, m = 3, p, q, r;
p = n / m; q = n % m; r = p*m + q;
Console.WriteLine("Операции над типом int");
Console.WriteLine(
"n = {0}, m = {1}, p = n/m = {2}, " +
"q = n % m = {3}, r = p*m + q = {4}",
n, m, p, q, r);
Console.WriteLine("Операции над типом double");
double x = 7.5, y = 3.5, u, v, w;
u = x / y; v = u * y;
w = x % y;
Console.WriteLine(
"x = {0}, y = {1}, u = x/y = {2}, " +
"v = u*y = {3}, w = x % y = {4}",
x, y, u, v, w);
Console.WriteLine("Операции над типом decimal");
decimal d1 = 7.5M, d2 = 3.5M, d3, d4, d5;
d3 = d1 / d2; d4 = d3 * d2;
d5 = d1 % d2;
Console.WriteLine(
"d1 = {0}, d2 = {1}, d3 = d1/d2 = {2}, " +
"d4 = d3*d2 = {3}, d5 = d1 % d2 = {4}",
d1, d2, d3, d4, d5);
}//Ariphmetica
Результаты вычислений при вызове этого метода показаны на рис. 3.3.
увеличить изображение Рис. 3.3. Результаты работы метода Ariphmetica
Для целых типов можно исходить из того, что равенство истинно. Для типов с плавающей точкой выполнение точного равенства следует считать скорее случайным, а не закономерным событием. Законно невыполнение этого равенства, как это происходит при вычислениях с фиксированной точкой.
-
Вычисление выражений
Как уже говорилось, при записи выражения от программиста требуется знание всех операций, которые могут применяться в построении выражений, знание их точной семантики, понимание тех преобразований операндов, которые могут осуществляться при выполнении операций. Но есть и другие не менее важные цели, которые следует ставить на этом этапе.
-
Память и время - два основных ресурса
В распоряжении программиста при решении задач есть два основных ресурса - это память компьютера и его быстродействие. Кажется, что оба эти ресурса практически безграничны, и потому можно не задумываться о том, как они расходуются. Эти представления иллюзорны. Многие задачи, возникающие на практике, таковы, что имеющихся ресурсов не хватает и требуется жесткая их экономия. Вот два простых примера. Если в программе есть трехмерный массив A: double[,,]; A = new double[n,n,n], то уже при n =1000 оперативной памяти современных компьютеров не хватит для хранения элементов этого массива. Если приходится решать задачу, подобную задаче о "ханойской башне", где время решения задачи , то уже при n = 64 никакого быстродействия всех современных компьютеров не хватит для решения этой задачи в сколь-либо допустимые сроки. Программист обязан уметь оценивать объем ресурсов, требуемых программе.
Говоря о ресурсах, требуемых программе P, часто используют термины "временная" и "емкостная сложность" - T(P) и V(P). Выражения представляют хорошую начальную базу для оценивания этих характеристик.
Характеристики T(P) и V(P) обычно взаимосвязаны. Увеличивая расходы памяти, можно уменьшить время решения задачи или, выбирая другое решение, сократить расходы памяти, увеличивая время работы. Одна из реальных задач, стоящих перед профессиональным программистом - это нахождение нужного компромисса между памятью и временем. Помните:
"Выбора тяжко бремя - память или время!"
Как этот компромисс достигается на уровне выражений? Если в исходном выражении можно выделить повторяющиеся подвыражения, то для них следует ввести временные переменные. Увеличивая расходы памяти на введение дополнительных переменных, уменьшаем общее время вычисления выражения, поскольку каждое из подвыражений будет вычисляться только один раз. Этот прием целесообразно применять и тогда, когда не преследуется цель экономии времени. Введение дополнительных переменных уменьшает сложность выражения, что облегчает его отладку и способствует повышению надежности программы. Вероятность допустить ошибку в записи громоздкого выражения значительно выше, чем при записи нескольких простых выражений.