Организация программного проекта ConsoleExpressions
Как обычно, все примеры программного кода, появляющиеся в тексте, являются частью программного проекта. Опишу структуру используемого в этой лекции консольного проекта, названного ConsoleExpressions. Помимо созданного по умолчанию класса Program, в проект добавлены два класса с именами TestingExpressions и Scales. Каждый из методов класса TestingExpressions представляет тест, который позволяет анализировать особенности операций, используемых при построении выражений, так что этот класс представляет собой сборник тестов. Класс Scale носит содержательный характер, демонстрируя работу со шкалами, о которых пойдет речь в этой лекции. Чтобы иметь возможность вызывать методы этих классов, в процедуре Main класса Program объявляются и создаются объекты этих классов. Затем эти объекты используются в качестве цели вызова соответствующих методов. Общая схема процедуры Main и вызова методов класса такова:
static void Main(string[] args) { string answer = "Да"; do { try { TestingExpressions test = new TestingExpressions(); test.Casting(); //Вызов других методов … } catch (Exception e) { Console.WriteLine( "Невозможно нормально продолжить работу!"); Console.WriteLine(e.Message); } Console.WriteLine("Продолжим работу? (Да/нет)"); answer = Console.ReadLine(); } while (answer == "Да" || answer == "да" || answer == "yes"); }
Всякий раз, когда в тексте лекции нужно будет привести пример кода, будет приводиться либо полный текст вызываемого метода, например, метода Casting, либо отдельный фрагмент метода.
Рассмотрим подробнее операции из таблицы 3.1, отнесенные к высшему приоритету и выполняемые в первую очередь.
Любое выражение, взятое в скобки, получает высший приоритет и должно быть вычислено, прежде чем к нему будут применимы какие-либо операции. Скобки позволяют изменить стандартный порядок вычисления выражения и установить порядок, необходимый для вычисления в данном конкретном случае. В сложных выражениях скобки полезно расставлять даже в том случае, если стандартный порядок совпадает с требуемым, поскольку наличие "лишних" скобок зачастую увеличивает наглядность записи выражения.
Вот классический пример выражения со скобками:
result = (x1 + x2) * (x1 - x2);
Понятно, что если убрать скобки, то первой выполняемой операцией будет операция умножения и результат вычислений будет совсем другим.
Поскольку согласно стандартному порядку выполняются вначале арифметические операции, потом операции отношения, а затем логические операции, то можно было бы не ставить скобки в следующем выражении:
1.5.2. Операция вызова "точка" x.y, вызов функций F(x), вызов, инициируемый указателем x -> y
Несмотря на то, что точка - "малозаметный" символ, операция вызова x.y является одной из основных и важнейших операций в объектном программировании. Здесь x является целью вызова и представляет некоторый уже созданный объект, а y является свойством или методом этого объекта. Поскольку свойство объекта может задавать новый объект, может порождаться достаточно длинная цепочка вызовов (x.y1.y2.y3.y4), заканчивающаяся, как правило, терминальным свойством.
Если объект вызывает не свойство, а метод, то вызов метода сопровождается заданием фактических аргументов:
x.M(a1, … ak)
Когда такой вызов встречается в выражениях, метод должен возвращать значение, отличное от void (быть функцией), чтобы такое выражение могло быть использовано в качестве операнда какой-либо операции. Вызов метода, возвращающего значение void, используется как отдельный оператор, что неоднократно встречалось в наших примерах.
В качестве цели вызова может применяться не только имя объекта, но и имя класса. В этом случае вызывается статическое свойство или статический метод этого класса. Для каждого класса, у которого есть статические поля и статические методы, автоматически создается специальный объект (модуль), содержащий статические поля, к которым относятся и константы класса. Имя этого объекта совпадает с именем класса. Вот несколько примеров подобных вызовов:
Здесь в качестве цели вызовов выступают классы Console и Convert, вызывающие статические методы этих классов.
Если цель вызова указана, то такой вызов называется квалифицированным. Когда целью вызова является текущий объект, ее (цель) можно опускать, делая вызов неквалифицированным. Такой вызов всегда можно сделать квалифицированным, указав this в качестве имени текущего объекта:
result += this.n * this.m;
В данном случае можно было бы опустить имя текущего объекта и записать выражение следующим образом:
result += n * m;
Рассмотрим выражение:
result += x2 * x2 + F(x1) - x1 * x1;
Здесь все вызовы свойств x1, x2, метода F(x) записаны без квалификации, но можно превратить их в квалифицированные, показав явным образом, что реально при вычислении выражения используется операция вызова "точка". В последних примерах предполагается, что n, m, x1, x2 являются полями класса, а F - методом класса.
В неуправляемом коде, который появляется в блоках, объявленных как небезопасные, разрешена работа с указателями. Вызов полей и методов объекта, когда целью является указатель, задается операцией "стрелка" x -> y, где x - это указатель, а y - поле объекта, на который указывает указатель. Переходя от указателей к объекту, операцию "стрелка" можно заменить операцией "точка" следующим образом: (*x).y
В нашем курсе работа с указателями рассматриваться не будет.
1.5.3. Операция индексации a[i, j]
О массивах подробно поговорим в одной из ближайших лекций этого курса. Сейчас скажем, что если уже объявлен массив, то в выражении можно использовать элемент этого массива, задав индексы этого элемента. Так, например, если объявлен одномерный массив w, содержащий n элементов, то выражение w[i] будет определять i-й элемент этого массива, где индекс принимает значения от 0 до n-1.