Опубликован: 18.09.2006 | Уровень: специалист | Доступ: свободно | ВУЗ: Московский государственный университет имени М.В.Ломоносова
Лекция 10:

Основные конструкции языков Java и C#

Инструкции и выражения

Выражения

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

  • x.y — оператор уточнения имени, служит для получения ссылки на элемент пространства имен или типа, либо для получения значения поля (или свойства в C# );
  • f(x) — оператор вызова метода (а также делегата в C# ) с заданным набором аргументов;
  • a[x] — оператор вычисления элемента массива (а также обращения к индексеру в C# );
  • new — оператор создания нового объекта (или значения в C# ), используется вместе с обращением к одному из конструкторов типа — new MyType("Yes", 2)Java с его помощью нельзя создавать значения примитивных типов );
  • ++, -- — префиксные и постфиксные унарные операторы увеличения/уменьшения на 1 ;
  • (T)x — оператор явного приведения к типу T ;
  • +, -унарные операторы сохранения/изменения знака числа;
  • ! — унарный оператор логического отрицания;
  • ~унарный оператор побитового отрицания;
  • *, /, %, +, -бинарные операторы умножения, деления, взятия остатка по модулю, сложения и вычитания;
  • <<, >>бинарные операторы побитовых сдвигов влево/вправо;
  • <, >, <=, >=бинарные операторы сравнения по порядку;
  • ==, !=бинарные операторы сравнения на равенство/неравенство;
  • &, |, ^бинарные операторы логических или побитовых операций: конъюнкции, дизъюнкции, сложения по модулю 2;
  • &&, ||бинарные операторы условных конъюнкции и дизъюнкции, (x && y) эквивалентно (x?y:false), a (x || y) — (x?true:y) ;
  • ?: — тернарный условный оператор, выражение a?x:y вычисляет значение a, если оно true, то вычисляется и возвращается значение x, иначе вычисляется и возвращается значение y ;
  • =, *=, /=, %=, +=, -=, <<=, >>=, &=, |=, ^=бинарные операторы присваивания, все они, кроме первого, сначала производят некоторую операцию над старым значением левого операнда и значением правого, а затем присваивают полученный результат левому операнду.
Таблица 10.1. Приоритет и ассоциативность операторов
Операторы Ассоциативность
x.y, f(x), a[x], new, x++, x--
+, -, !, ~, ++x, --x, (T)x
*, /, % левая
+, - левая
<<, >> левая
<, >, <=, >= левая
==, != левая
& левая
^ левая
| левая
&& левая
|| левая
?: правая
=, *=, /=, %=, +=, -=, <<=, >>=, &=, |=, ^= правая

В табл. 10.1 операторы перечисляются сверху вниз в порядке уменьшения их приоритета, а также приводится ассоциативность всех операторов. Оператор op называется левоассоциативным, если выражение (x op y op z) трактуется компилятором как ((x op y) op z), и правоассоциативным, если оно трактуется как (x op (y op z)).

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

Получение объекта, представляющего тип, связано с механизмом рефлексии (reflection), имеющимся в обоих языках. Этот механизм обеспечивает отображение сущностей языка (типов, операций над ними, полей их данных и пр.) в объекты самого языка. В обоих языках операция получения объекта, представляющего тип, входит в группу операций с высшим приоритетом.

Любой тип Java однозначно соответствует некоторому объекту класса java.lang.Class, любой метод описывается с помощью одного из объектов класса java.lang.reflect.Method, любое поле — с помощью одного из объектов класса java.lang.reflect.Field.

Получить объект типа Class, представляющий тип T (даже если T = void), можно с помощью конструкции T.class.

В C# типы представляются объектами класса System.Type, методы — объектами System.Reflection.MethodInfo, а поля — объектами System.Reflection.FieldInfo.

Объект типа System.Type, представляющий тип T, можно получить при помощи конструкции typeof(T).

Для проверки того, что выражение x имеет тип T, в Java используется конструкция

(x instanceof T),

возвращающая значение логического типа.

В обоих языках операция проверки типа имеет такой же приоритет, как операторы <, >, <=, >=.

Для проверки того, что выражение x имеет тип T, в C# используется конструкция

(x is T),

имеющая логический тип.

Эта проверка использует естественные преобразования типов (подтипа в более общий тип или наоборот, если точный тип объекта является подтипом T ) и автоупаковку/распаковку, не затрагивая определенных пользователем неявных преобразований.

В C# имеется и другой оператор, связанный с преобразованием типа.

Для преобразования объекта x к заданному ссылочному типу T можно использовать конструкцию

(x as T),

тип результата которой — T.

Если в результате естественных преобразований типов и автоупаковки/распаковки, значение x не преобразуется к типу T, то результат этого выраженияnull.

Приоритет этого оператора такой же, как у оператора is, а ассоциативность — левая.

В Java есть дополнительный оператор сдвига числового значения вправо >>>, заполняющий освобождающиеся слева биты нулями.

Он имеет такой же приоритет, как и остальные операторы сдвига, и левую ассоциативность.

Соответствующий оператор присваивания >>>= имеет такой же приоритет, как и другие операторы присваивания, и правую ассоциативность.

В C# можно строить выражения, в рамках которых переполнения при арифметических действиях вызывают (или не вызывают) исключения при помощи оператора

checked(x) (unchecked(x)),

где xвыражение, контекст вычисления которого мы хотим определить (см. раздел о целочисленных типах).

Оба этих оператора входят в группу операторов с высшим приоритетом.

Выражение default(T) используется в C# 2.0 для получения значения типа T по умолчанию.

Для ссылочных типов это null, для числовых типов — 0, для логического типа — false, a для остальных типов значений определяется на основе их структуры.

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

Этот оператор входит в группу с высшим приоритетом.

Оператор ?? (null coalescing operator) используется в C# 2.0 в следующем смысле. Выражение (x??y) эквивалентно ((x == null)?y:x), только значение x вычисляется однократно, т.е., если значение x не равно null, то результатом этой операции является x, а иначе y.

Этот оператор имеет приоритет меньший, чем приоритет условной дизъюнкции ||, но больший, чем приоритет условного оператора ?:. Он правоассоциативен.

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

Дело в том, что в C# при разрешении имен, построенных с помощью точек, разделяющих идентификаторы, возможны многочисленные проблемы, связанные с непредвиденными модификациями библиотек.

Например, если мы написали директиву using System.IO;, чтобы использовать класс FileStream с коротким именем, и одновременно определяем в этом контексте класс EmptyStream, то, если в будущем в System.IO появится класс EmptyStream, полученный код перестанет компилироваться.

Эту ситуацию можно разрешить при помощи синонимов, определив, например, для System.IO синоним SIO, а для нашей собственной библиотеки, куда входит EmptyStream, синоним MIO, и используя имена классов только вместе с синонимами — SIO.FileStream, MIO.EmptyStream. Однако если в одной из используемых библиотек будет введено пространство имен MIO, проблема возникнет вновь.

Чтобы однозначно отделить типы из внешних библиотек от внутрипрограммных, можно использовать оператор ::. При этом левый аргумент такого оператора может иметь два вида. Либо он имеет значение global — тогда имя, заданное правым аргументом, ищется в глобальном пространстве имен и конфликтует с внутренними именами. Либо он является именем синонима — тогда имя, заданное правым аргументом, ищется только в пространстве имен, определяемом этим синонимом.

Этот оператор входит в группу с высшим приоритетом.

Тип или часть его операций, или даже отдельный блок в C# могут быть помечены модификатором unsafe. При этом содержимое помеченного типа, операции или блока попадает в небезопасный контекст (unsafe context). В рамках небезопасного контекста можно использовать указатели и операции над указателями, в частности, доступ к элементу данных по указателю с помощью оператора ->, построение указателей на данные и разыменование указателей, арифметические действия над указателями.

В данном курсе мы не будем больше касаться правил написания небезопасного кода в C#, предоставляя заинтересованному читателю самому разобраться в них с помощью [8].

Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!

Лариса Парфенова
Лариса Парфенова

1) Можно ли экстерном получить второе высшее образование "Программная инженерия" ?

2) Трудоустраиваете ли Вы выпускников?

3) Можно ли с Вашим дипломом поступить в аспирантуру?