Выражения
Как уже было упомянуто в предыдущих главах (в истории ООП), одним из наиболее значимых нововведений языков программрования высокого уровня, стала возможность записи арифметических выражений в естественной для человека форме, с использованием операторов и функций. Для того чтобы посчитать значение выражения, теперь программисту требуется лишь правильно записать его, не заботясь о том, как оно будет вычисляться. Всю работу по разбору такого выражения, определению очередности выполнения операций берет на себя компилятор языка.
В этой главе мы узнаем, что такое выражения с точки зрения языка К++, как они формируются и на что нужно обращать внимание при их записи. Кратко будет затронута тема операторов, будут даны основные сведения о них. Более подробно, операторы как элемент языка К++, будут рассмотрены в конце книги, в отдельном разделе.
Арифметические операции
Наиболее простой и понятный тип выражений — это самые обычные арифметические выражения:
<source lang="kpp"> var x = 2 + 3 * 4; var y = (2 + 3) * 4; </source>
Для простоты мы используем хорошо нам известную конструкцию объявления переменной, но на этот раз в инициализаторе мы указываем не одну константу, вроде строки "hello world", а целое выражение. Выражением считается все, что записано между знаком "=" и точкой с запятой ";", которая завершает конструкцию.
При вычислении значения выражения применяются те же самые правила что и в обычной математике, то есть операции имеют приоритет и выполняются строго в порядке убывания приоритета. В первом случае, сначала будет вычислено подвыражение 3 * 4, к значению которого будет добавлено число 2; сумма будет установлена как значение переменной. Во втором случае, приоритет операций был изменен введением круглых скобок, которые имеют тот же смысл, что и в математике: сначала вычисляется значение в скобках, а затем остальные операции, опять же в порядке их приоритета. Скобок в выражение может быть сколько угодно, допускается вложенность.
...Таким образом, переменной x будет присвоено значение 14, а переменная y будет равна 20.
В выражениях могут указываться не только числовые константы. Так же как и в математике, в выражениях можно использовать переменные.
При вычислении выражения вмсето имени переменной подставляется ее значение. Таким образом, если в ходе рассчетов выражения, переменная изменит свое значение, то вместе следующего вхождения переменной может быть подставлено уже новое значение. А чтобы с уверенностью сказать "может быть подставлено" или "будет подставлено" нужно смотреть, какой именно код записан в выражении. С этим моментом связана известная проблема неоднозначности выражений. Забежав вперед, можно рассмотреть связанный с данным вопросом пример применения операторов в выражении:
<source lang="kpp"> var i = 5; var x = ++i + ++i; </source>
Как вы думаете, какое значение будет иметь переменная x после выполнения вышеприведенного кода? Программист, знающий только Паскаль при виде этого примера скорее всего впадет в ступор, поскольку этот язык не имеет оператора ++, либо он сочтет что выражение записано ошибочно.
Новичок, изучающий язык C++, но уже кое-что знающий о нем, может рассуждать так: «Оператор ++ — это оператор инкремента. В зависимости от того где он расположен в выражении, будет зависеть то как он изменяет переменную; если оператор находится слева он переменной, то сначала будет произведена операция инкремента, а затем новое значение будет использоваться при расчете выражения. В нашем случае это именно так. Стало быть, при рассчете выражения, в обоих случаях значение переменной i будет увеличено на единицу и будет использовано в рассчете. В результате мы получим выражение x = 6 + 7 = 13»
Опытный программист на C++, первым делом спросит как реализованы операторы ++ и +, и происходит ли копирование аргументов. Если копирование происходит, то значение будет таким же как у новичка, то есть 13. Если же оператор работает с самой переменной, то произойдет следующее:
Первый оператор ++ увеличит значение переменной i на единицу, которое теперь будет равно 6. Поскольку мы имеем дело со ссылкой на переменную то это значение не будет нигде сохраняться. Далее, при вычислении значения второго слагаемого сработает уже второй оператор ++, который так же увеличит (уже увеличенное значение!) переменную на 1, и вернет результат 6 + 1, то есть 7. При вычислении итогового значения мы получаем выражение 7 + 7, то есть 14.
Получается что сколько человек, столько и мнений. А самое интересное, что каждый из них прав. Их рассуждения логичны с учетом того, с какой позиции смотреть на проблему. В такой неразберихе не мудрено запутаться. Если читатель еще не сбит с толку окончательно, то можно продолжить и рассмотреть эту задачу с точки зрения языка К++.
В случае с языком К++ вычисление значения будет происходить по второму сценарию. То есть, результат такого выражения будет равен 14.
Вызов функций
Вызов функций в выражениях осуществляется путем записи имени функции, следом за которым в круглых скобках перечисляются ее аргументы. При этом, при вычислении выражения, вместо самой функции будет подставлено ее значение:
<source lang="kpp"> const pi = 3.1415926; var x = 10; var y = x * sin(pi); </source>
Доступ к полям
Доступ к полям и свойствам классов осуществляется путем записи имени объекта, следом закоторым ставится оператор точка ".", а затем идентификатор поля либо метода. Если ссылаемое поле само имеет свойства или поля, то к ним так же можно ссылаться, поставив вторую точку и указав идентификатор и т. д.
<source lang="kpp" line="1"> class MyClass {
var m_Field = "hello world"; property field read m_Field write m_Field; public function SetField(const string what = "world") { m_Field = "hello " + what; }
}
function caller() {
var object = new MyClass; puts(object.field); object.field = "hello everyone!"; object.SetField("universe"); object.SetField();
} </source>
- 1-7
- Мы объявляем некоторый класс MyClass, который имеет поле m_Field и свойство field, связанное с полем. Так же имеется метод SetField(), который устанавливает новое значение свойства, которое определяется выражением в строке 5. Значение свойства складывается из строковой константы "hello ", к которой добавляется значение параметра what.
- 9-15
- В этой функции приводится пример применения вышеописанного класса. Сначала мы создаем инстанцию класса MyClass с помощью оператора new. Затем вызывается функция puts(), которая печатает значение свойства объекта. В третьей строке мы присваиваем свойству field (а значит и полю m_Field) новое значение. Последние две строки показывают пример вызова метода с явным аргументом и с аргументом по умолчанию.
Good points all aorund. Truly appreciated.