
- •Лекция №6
- •Тема: Оператори вибору if, if … else …, switch
- •Логические операции
- •Условное выражение
- •Операция приведения к типу
- •Присваивание
- •Специальные случаи присваивания
- •Определенное присваивание
- •Рассмотрим объявления:
- •Класс Random и его функции
- •If(выражение_1) оператор_1
- •If(выражение1) if(выражение2) if(выражение3) ...
- •Оператор switch
Специальные случаи присваивания
В языке C++ для двух частных случаев присваивания предложен отдельный синтаксис. Язык C# наследовал эти полезные свойства. Для присваиваний вида "x=x+1", в которых переменная увеличивается или уменьшается на единицу, используются специальные префиксные и постфиксные операции "++" и "--". Другой важный частный случай - это присваивания вида:
X = X <operator> (expression)
Для таких присваиваний используется краткая форма записи:
X <operator>= expression
В качестве операции разрешается использовать арифметические, логические (побитовые) операции и операции сдвига языка C#. Семантика такого присваивания достаточно очевидна, и я ограничусь простым примером:
x += u+v; y /=(u-v);
b &= (x<y);
Однако и здесь есть один подводный камень, когда x= x+a не эквивалентно x +=a. Рассмотрим следующий пример:
byte b3 = 21;
b3 +=1; //Это допустимо
//b3 = b3+1; //А это недопустимо:результат типа int
Закомментированный оператор приведет к ошибке компиляции, поскольку правая часть имеет тип int, а неявное преобразование к типу byte отсутствует. Следует понимать, что преимущество первой формы записи - только кажущееся: если при инициализации переменная b получит допустимое значение 255, то следующий оператор присваивания в краткой форме не выдаст ошибки, но даст неверный результат, а это - самое худшее, что может случиться в программе. Так что надежнее пользоваться полной формой записи присваивания, не экономя на паре символов.
Определенное присваивание
Присваивание в языке C# называется определенным присваиванием (definite assignment). В этом термине отражен тот уже обсуждавшийся факт, что все используемые в выражениях переменные должны быть ранее инициализированы и иметь определенные значения. Единственное, за чем компилятор не следит, так это за инициализацией переменных массива. Для них используется инициализация элементов, задаваемая по умолчанию. Приведу пример:
//определенное присваивание
int an =0 ; //переменные должны быть инициализированы
for (int i= 0;i<5;i++)
{an =i+1;}
x+=an; z+=an; y = an;
string[] ars = new string[3];
double[] ard = new double[3];
for (int i= 0;i<3;i++)
{
//массивы могут быть без инициализации
ard[i] += i+1;
ars[i] += i.ToString()+1;
Console.WriteLine("ard[" +i + "]=" +ard[i] +
"; ars[" +i + "]=" +ars[i]);
}
Заметьте, в этом фрагменте переменная an обязана быть инициализированной, а массивы ard и ars не инициализируются и спокойно участвуют в вычислениях.
Рассмотрим объявления:
int x=3, y=5;
object obj1, obj2;
Здесь объявлены четыре сущности: две переменные значимого типа и две - объектного. Значимые переменные x и y проинициализированы и имеют значения, объектные переменные obj1 и obj2 являются пустыми ссылками со значением void. Рассмотрим присваивания:
obj1 = x; obj2 = y;
Эти присваивания ссылочные (из-за типа левой части), поэтому правая часть приводится к ссылочному типу. В результате неявного преобразования - операции boxing - в динамической памяти создаются два объекта, обертывающие соответственно значения переменных x и y. Сущности obj1 и obj2 получают значения ссылок на эти объекты.