Задание 2.3. Объясните, почему операция (byte)i вместо ожидаемого значения -4 дала нам в качестве результата значение 252. Лабораторная работа №2. Тема: Разработка библиотек dll на с#. Операции и операторы языка C# Внимание! Рекомендации о порядке защиты лабораторной работы указаны в конце текста! Часть 1. Разработка dll на С# Задание: Разработать библиотеку dll для работы с комплексными числами и единственной операцией сложения. - Создание библиотеки dll с помощью Visual Studio (2010 и выше). Выберите пункт меню ФайлàСоздатьàПроект
 - Выберите проект «Библиотека классов». (Расширение dll). Укажите Имя проекта и расположение проекта.
 - Введите текст класса приведенного класса. В обучающих целях ряд ключевых и воспроизводимых из контекста слов заменены «……»
____________________________________________________________ ….. System; ….. ComplexClass { ….. class Complex { double re, im; public Complex(….. r, ….. i) { re = r; im = i; } public static ….. sum(Complex C1, Complex C2) { return new …..(C1.re + C2.re, C1.im + C2.im); } public ….. ….. ToString() { ….. ""+re+" "+im; } } } ____________________________________________________________________________ - Устанавливаем конфигурацию решения в состояние «Release». Выбираем пункт меню ПостроениеàПостроить решение:
 - Для тестирования созданной dll библиотеки добавляем новый проект «Консольное приложение»:
 - Введите текст класса приведенного класса. В обучающих целях ряд ключевых и воспроизводимых из контекста слов заменены «……»
_________________________________________________________________________ using System; ….. ComplexClass; namespace TestComlex { ….. Program { static void Main(string[] args) { Complex t1 = new …..(1,1); ….. t2 = new Complex(2,3),t3; t3 = Complex……..(t1,t2); …...WriteLine(t1); …...WriteLine(t2); …........(t3); } } } - Подключаем к проекту созданную ранее библиотеку. Для этого необходимо указать ссылку на файл построенный на шаге 4.
 - Постройте проект и протестируйте его работу. Убедитесь, что класс и функции описанные во внешней библиотеке функционирую нормально.
Часть 2. Операции языка C# Полный список операций языка С# в соответствии с их приоритетами (по убыванию приоритетов, операции с разными приоритетами разделены чертой) приведен в следующей таблице: Операция | Описание | . | Доступ к элементу | x() | Вызов метода или делегата | x[] | Доступ к элементу | x++ | Постфиксный инкремент | x— | Постфиксный декремент | New | Выделение памяти | Typeof | Получение типа | Checked | Проверяемый код | Unchecked | Непроверяемый код | + | Унарный плюс | - | Арифметическое отрицание | ! | Логическое отрицание | ~ | Поразрядное отрицание | ++x | Префиксный инкремент | --x | Префиксный декремент | (тип) x | Преобразование типа | * | Умножение | / | Деление | % | Остаток от деления | << | Сдвиг влево | >> | Сдвиг вправо | < | Меньше | > | Больше | <= | Меньше или равно | >= | Больше или равно | is | Проверка принадлежности типу | as | Приведение типа | == | Равно | != | Не равно | & | Поразрядное И | ^ | Поразрядное исключающее ИЛИ | | | Поразрядное ИЛИ | && | Логическое И | || | Логическое ИЛИ | ? : | Условная операция | = | Простое присваивание | *= | Умножение с присваиванием | /= | Деление с присваиванием | %= | Остаток от деления с присваиванием | += | Сложение с присваиванием | -= | Вычитание с присваиванием | <<= | Сдвиг влево с присваиванием | >>= | Сдвиг вправо с присваиванием | &= | Поразрядное И с присваиванием | ^= | Поразрядное исключающее ИЛИ с присваиванием | |= | Поразрядное ИЛИ с присваиванием | В данном разделе мы подробно рассмотрим только часть операций, остальные операции будут вводиться по мере необходимости. Если после изучения других языков операции покажутся Вам знакомыми, то соответствующие из них можно пропустить. Но! Внимание!! Вы должны быть уверены, что сможете объяснить те явления, которые описываются в соответствующем задании!!! Замечание. Операции можно классифицировать по количеству операндов на: унарные – воздействуют на один операнд, бинарные – воздействуют на два операнда, тернарные – воздействует на три операнда. Некоторые символы используются для обозначения как унарных, так и бинарных операций. Например, символ «минус» используется как для обозначения унарной операции – арифметического отрицания, так и для обозначения бинарной операции вычитание. Будет ли данный символ обозначать унарную или бинарную операцию, определяется контекстом, в котором он используется. 1. Инкремент (++) и декримент(--). Эти операции имеют две формы записи — префиксную, когда операция записывается перед операндом, и постфиксную – операция записывается после операнда. Префиксная операция инкремента (декремента) увеличивает (уменьшает) свой операнд и возвращает измененное значение как результат. Постфиксные версии инкремента и декремента возвращают первоначальное значение операнда, а затем изменяют его. Рассмотрим эти операции на примере. static void Main() { int i = 3, j = 4; Console.WriteLine(«{0} {1}», i, j); Console.WriteLine(«{0} {1}», ++i, --j); Console.WriteLine(«{0} {1}», i++, j--); Console.WriteLine(«{0} {1}», i, j); } | Результат работы программы: 3 4 4 3 4 3 5 2 | Замечание. Префиксная версия требует существенно меньше действий: она изменяет значение переменной и запоминает результат в ту же переменную. Постфиксная операция должна отдельно сохранить исходное значение, чтобы затем вернуть его как результат. Для сложных типов подобные дополнительные действия могут оказаться трудоемки. Поэтому постфиксную форму имеет смысл использовать только при необходимости. 2. Операция new. Используется для создания нового объекта. С помощью ее можно создавать как объекты ссылочного типа, так и размерные, например: object z=new object(); int i=new int(); // то же самое, что и int i =0; 3. Отрицание: Арифметическое отрицание (-) – меняет знак операнда на противоположный. Логическое отрицание (!) – определяет операцию инверсия для логического типа. Рассмотрим эти операции на примере. static void Main() { int i = 3, j=-4; bool a = true, b=false; Console.WriteLine(«{0} {1}», -i, -j); Console.WriteLine(«{0} {1}», !a, !b); } | Результат работы программы: -3 4 False True | 4. Явное преобразование типа. Используется для явного преобразования из одного типа в другой. Формат операции: (тип) выражение; Рассмотрим эту операцию на примере. static void Main() { int i = -4; byte j = 4; int a = (int)j; //преобразование без потери точности byte b = (byte)i; //преобразование с потерей точности Console.WriteLine(«{0} {1}», a, b); } | Результат работы программы: 4 252 | 5. Умножение (*), деление (/) и деление с остатком (%). Операции умножения и деления применимы для целочисленных и вещественных типов данных. Для других типов эти операции применимы, если для них возможно неявное преобразование к целым или вещественным типам. При этом тип результата равен «наибольшему» из типов операндов, но не менее int. Если оба операнда при делении целочисленные, то и результат тоже целочисленный. Рассмотрим эти операции на примере. static void Main() { int i = 100, j = 15; double a = 14.2, b = 3.5; Console.WriteLine(«{0} {1} {2}», i*j, i/j, i%j); Console.WriteLine(«{0} {1} {2}», a * b, a / b, a % b); } Результат работы программы: \ 1500 6 10 49.7 4.05714285714286 0.1999999999999999 6. Сложение (+) и вычитание (-). Операции сложения и вычитания применимы для целочисленных и вещественных типов данных. Для других типов эти операции применимы, если для них возможно неявное преобразование к целым или вещественным типам. 7. Операции отношения ( <, <=, >, >=, ==, !=). Операции отношения сравнивают значения левого и правого операндов. Результат операции логического типа: true – если значения совпадают, false – в противном случае. Рассмотрим операции на примере: static void Main() { int i = 15, j = 15; Console.WriteLine(i<j); //меньше Console.WriteLine(i<=j); //меньше или равно Console.WriteLine(i>j); //больше Console.WriteLine(i>=j); //больше или равно Console.WriteLine(i==j); //равно Console.WriteLine(i!=j); //не равно } | Результат работы программы: False True False True True False | 8. Логические операции: И (&&), ИЛИ (||). Логические операции применяются к операндам логического типа. Результат логической операции И имеет значение истина тогда и только тогда, когда оба операнда принимают значение истина. Результат логической операции ИЛИ имеет значение истина тогда и только тогда, когда хотя бы один из операндов принимает значение истина. Рассмотрим операции на примере: static void Main() { Console.WriteLine(«x y x и y x или y»); Console.WriteLine(«{0} {1} {2} {3}», false, false, false&&false, false||false); Console.WriteLine(«{0} {1} {2} {3}», false, true, false&&true, false||true); Console.WriteLine(«{0} {1} {2} {3}», true, false, true&&false, true||false); Console.WriteLine(«{0} {1} {2} {3}», true, true, true&&true, true||true); } Результат работы программы: x y x и y x или y False False False False False True False True True False False True True True True True Замечание. Фактически была построена таблица истинности для логических операций И и ИЛИ. 9. Условная операция. Формат: (<операнд1>)? <операнд2> : <операнд3>; Операнд1 – это логическое выражение, которое оценивается с точки зрения его эквивалентности константам true и false. Если результат вычисления операнда1 равен true, то результатом условной операции будет значение операнда2, иначе — операнда3. Фактически условная операция является сокращенной формой условного оператора if, который будет рассмотрен позже. Пример использования условной операции: static void Main() { int x=5; int y=10; int max = (x > y) ? x : y; Console.WriteLine(max); } 10. Операции присваивания: =, +=, -= и т.д. Формат операции простого присваивания (=): операнд_2 = операнд_1; В результате выполнения этой операции вычисляется значение операнда_1, и результат записывается в операнд_2. Возможно связать воедино сразу несколько операторов присваивания, записывая такие цепочки: a=b=c=100. Выражение такого вида выполняется справа налево: результатом выполнения c=100 является число 100, которое затем присваивается переменной b, результатом чего опять является 100, которое присваивается переменной a. Кроме простой операции присваивания существуют сложные операции присваивания, например, умножение с присваиванием (*=), деление с присваиванием (/=), остаток от деления с присваиванием (%=), сложение с присваиванием (+=), вычитание с присваиванием (-=) и т.д. В сложных операциях присваивания, например, при сложении с присваиванием, к операнду_2 прибавляется операнд_1, и результат записывается в операнд_2. То есть, выражение с += а является более компактной записью выражения с = с + а . Кроме того, сложные операции присваивания позволяют сгенерировать более эффективный код, за счет того, что в простой операции присваивания для хранения значения правого операнда создается временная переменная, а в сложных операциях присваивания значение правого операнда сразу записывается в левый операнд. Рассмотренные операции приведены с учетом убывания приоритета. Если в одном выражении соседствуют операции одного приоритета, то операции присваивания и условная операции выполняются справа налево, а остальные наоборот. Если необходимо изменить порядок выполнения операций, то в выражении необходимо поставить круглые скобки. Задания к части №2 Задание 2.1. Выясните, допустимы ли следующие способы записи ++(++i), (i--)--, ++(i--) и т.д. И почему. Задание 2.2. Выясните, допустимы ли следующие способы записи !(-i), -(!a). И почему. Задание 2.3. Объясните, почему операция (byte)i вместо ожидаемого значения -4 дала нам в качестве результата значение 252. Задание 2.4. Выясните, чему будет равен результат операции: 1) 1.0/0; 2) 1/0 И объясните, как получился данный результат. Задание 2.5. Выясните, чему равен результат данного выражения: 1) i<j<k 2) true<false И объясните, как получился данный результат. Задание 2.6. Объясните, какое значение примет переменная t в данном фрагменте программы: int a=10, b=3; bool t=(a>=b && a!=2*b || a<0); Задание 2.7. Измените программу так, чтобы: static void Main() { int x=5; int y=10; int max = (x > y) ? x : y; Console.WriteLine(max); } 1) вычислялось наименьшее значение из двух вещественных чисел x и y; 2) если число двузначное, то на экран выводилось «Да», и «Нет» в противном случае. Задание 2.8. Объясните, какие значения примут переменные t и b после выполнения данного фрагмента программы: int a=10, b=3; int t=(a++)-b; int b+=t*a; Часть 3. Операторы языка C# Программа на языке С# состоит из последовательности операторов, каждый из которых определяет законченное описание некоторого действия и заканчивается точкой с запятой. Все операторы можно разделить на 4 группы: операторы следования, операторы ветвления, операторы цикла и операторы передачи управления. 1. Операторы следования Операторы следования выполняются компилятором в естественном порядке: начиная с первого до последнего. К операторам следования относятся: выражение и составной оператор. Любое выражение, завершающееся точкой с запятой, рассматривается как оператор, выполнение которого заключается в вычислении значения выражения или выполнении законченного действия, например, вызова метода. Например: ++i; //оператор инкремента x+=y; //оператор сложение с присваиванием Console.WriteLine(x); //вызов метода x=Math.Pow(a,b)+a*b; //вычисление сложного выражения Частным случаем оператора выражения является пустой оператор ; Он используется тогда, когда по синтаксису оператор требуется, а по смыслу — нет. В этом случае лишний символ ; является пустым оператором и вполне допустим, хотя и не всегда безопасен. Например, случайный символ ; после условия оператора while или if может совершенно поменять работу этого оператора. 2. Составной оператор или блок представляет собой последовательность операторов, заключенных в фигурные скобки {}. Блок обладает собственной областью видимости: объявленные внутри блока имена доступны только внутри данного блока или блоков, вложенных в него. Составные операторы применяются в случае, когда правила языка предусматривают наличие только одного оператора, а логика программы требует нескольких операторов. Например, тело цикла while должно состоять только из одного оператора. Если заключить несколько операторов в фигурные скобки, то получится блок, который будет рассматриваться компилятором как единый оператор. 3. Операторы ветвления Операторы ветвления позволяют изменить порядок выполнения операторов в программе. К операторам ветвления относятся условный оператор if и оператор выбора switch. 3.1.Условный оператор if Условный оператор if используется для разветвления процесса обработки данных на два направления. Он может иметь одну из форм: сокращенную или полную. Форма сокращенного оператора if: if (B) S; где В – логическое или арифметическое выражение, истинность которого проверяется; S – оператор: простой или составной. При выполнении сокращенной формы оператора if сначала вычисляется выражение B, затем проводится анализ его результата: если B истинно, то выполняется оператор S; если B ложно, то оператор S пропускается. Таким образом, с помощью сокращенной формы оператора if можно либо выполнить оператор S, либо пропустить его. Форма полного оператора if: if (B) S1; else S2; где B – логическое или арифметическое выражение, истинность которого проверяется; S1, S2- оператор: простой или составной. При выполнении полной формы оператора if сначала вычисляется выражение B, затем анализируется его результат: если B истинно, то выполняется оператор S1, а оператор S2 пропускается; если B ложно, то выполняется оператор S2, а S1 – пропускается. Таким образом, с помощью полной формы оператора if можно выбрать одно из двух альтернативных действий процесса обработки данных. Рассмотрим несколько примеров записи условного оператора if: if (a > 0) x=y; // Сокращенная форма c простым оператором if (++i) {x=y; y=2*z;} // Сокращенная форма c составным оператором if (a > 0 || b<0) x=y; else x=z; // Полная форма с простым оператором if (i+j-1) { x= 0; y= 1;} else {x=1; y:=0;} // Полная форма с составными операторами Рассмотрим пример использования условного оператора. static void Main() { Console.Write(«x= «); float x = float.Parse(Console.ReadLine()); Console.Write(«y=»); float y = float.Parse(Console.ReadLine()); if (x < y ) Console.WriteLine(«min= «+x); else Console.WriteLine(«min= «+y); } Результат работы программы: x y min 0 0 0 1 -1 -1 -2 2 -2 Операторы S1 и S2 могут также являться операторами if. Такие операторы называют вложенными. При этом ключевое слово else связывается с ближайшим предыдущим словом if, которое еще не связано ни с одним else. Рассмотрим пример программы, использующей вложенные условные операторы. Пример: Дана мишень.  Подсчитать количество очков после выстрела по данной мишени. static void Main() { int Ball=0; Console.Write(«x= «); float x = float.Parse(Console.ReadLine()); Console.Write(«y= «); float y = float.Parse(Console.ReadLine()); if (x * x + y * y <=1) Ball = 10; //окружность с радиусом 1 else if (x * x + y * y <= 4) Ball = 5; //окружность с радиусом 2 Console.WriteLine(«Ball= «+ Ball); } Результат работы программы: x y Ball 0 0 10 1 -1 5 -2 2 0 3.2.Оператор выбора switch Оператор выбора switch предназначен для разветвления процесса вычислений по нескольким направлениям. Формат оператора: switch ( <выражение> ) { case <константное_выражение_1>: [<оператор 1>]; <оператор перехода>; case <константное_выражение_2>: [<оператор 2>]; <оператор перехода>; ... case <константное_выражение_n>: [<оператор n>]; <оператор перехода>; [default: <оператор>; ] } |