Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 1 часть 3 Введение.docx
Скачиваний:
0
Добавлен:
16.11.2019
Размер:
274.19 Кб
Скачать

17

Лекция 1 часть 3 Введение

Оператор выбора switch

Оператор switch выбирает для выполнения список операторов, метка которого соответствует значению switch-выражения.

оператор_switch: switch ( выражение ) блок_switch

блок_switch: { разделы_switchнеобязательно }

разделы_switch: раздел_switch разделы_switch раздел_switch

раздел_switch метки_switch список_операторов

метки_switch: метка_switch метки_switch метка_switch

метка_switch: case константное_выражение : default :

Вычисляется switch-выражение.

Если значение константы, указанной в метке case, совпадает со значением switch-выражения, управление передается списку операторов, следующему за меткой case.

Если ни одна из констант, указанных в метках case оператора switch, не совпадает со значением switch-выражения и при этом имеется метка default, управление передается списку операторов, следующему за меткой default, если метка default отсутствует, управление передается в конечную точку оператора switch.

Если после выполнения одного раздела (раздел заключен в {} скобки) switch должно следовать выполнение другого раздела switch, необходимо явным образом указывать оператор goto case или goto default.

Ошибка времени компиляции возникает, если несколько меток case в одном операторе switch задают одно и то же константное значение.

Пример

using System;

namespace ConsoleApplication5

{

class Program

{

static void Main(string[] args)

{

int caseSwitch = 5;

switch (caseSwitch)

{

case 1:

Console.WriteLine("Case 1");

break;

case 2:

Console.WriteLine("Case 2");

break;

default:

Console.WriteLine("Default case");

break;

}

}

}

}

Список операторов раздела switch обычно заканчивается оператором break, goto case или goto default.

Если за меткой case нет списка операторов, то операторы break, goto case или goto default необязательны

В примере управление передается списку операторов, следующему за меткой case 2

using System;

namespace ConsoleApplication5

{

class Program

{

static void Main()

{

int caseSwitch = 1;

switch (caseSwitch)

{

case 1:

case 2:

Console.WriteLine("Case 2");

break;

default:

Console.WriteLine("Default case");

break;

}

}

}

}

Оператор итераций do

Оператор do выполняет внедренный оператор один или несколько раз в зависимости от соблюдения условия.

оператор_do: do внедренный_оператор while ( логическое_выражение ) ;

Управление передается внедренному оператору.

Если управление достигает конечной точки внедренного оператора, вычисляется логическое выражение.

Если результатом логического выражения является true, управление передается в начало оператора do. В противном случае управление передается в конечную точку оператора do.

Пример.

using System;

namespace ConsoleApplication5

{

class Program

{

static void Main(string[] args)

{

int x = 0;

do

{

Console.WriteLine(x);

x++;

} while (x < 5);

}

}

}

Операторы перехода

Операторы перехода осуществляют безусловную передачу управления. Операторы перехода могут передавать управление за пределы блока, но они никогда не передают управление внутрь блока.

Оператор break осуществляет выход из ближайшего объемлющего оператора switch, while, do, for или foreach.

Оператор continue начинает новую итерацию ближайшего объемлющего оператора while, do, for или foreach goto

Оператор return возвращает управление в программу, вызвавшую функцию-член, в которой используется оператор return. Оператор return с выражением может использоваться только в функции-члене, вычисляющей значение, т. е. в методе с типом возвращаемого значения, отличным от void, в методе доступа get для свойства или индексатора или в операторе, определенном пользователем.

Приведение и преобразование типов.

Преобразования бывают явными и неявными.

int a = 123; long b = a; // implicit conversion from int to long

// неявное перобразование типов, из int к long

int c = (int) b; // explicit conversion from long to int

// явное перобразование типов, из long к int

Неявные преобразования.

При вызове члена функции (метода). Для параметра имеющего тип значения вычисляется выражение аргумента и выполняется неявное преобразование в соответствующий тип параметра. Пример.

using System;

namespace ConsoleApplication5

{

class Program

{

static double f(double a, double b)

{

return a + b;

}

static void Main(string[] args)

{

int r = 2222;

double rez = f(r, 42222);

Console.WriteLine(rez);

}

}

}

Неявное преобразование при использовании оператора присваивания.

Пример. Неявное преобразование числового типа: из int к long. Компилятор неявно преобразует значение справа в тип long перед присвоением его переменной bigNum. Преобразование от меньшего к большему целому типу.

using System;

namespace ConsoleApplication5

{

class Program

{

static void Main(string[] args)

{

int num = 2147483647;

long bigNum = num;

}

}

}

Неявные преобразования числовых типов.

Существуют следующие неявные преобразования числовых типов:

  • из sbyte к short, int, long, float, double или decimal;

  • из byte к short, ushort, int, uint, long, ulong, float, double или decimal;

  • из short к int, long, float, double или decimal;

  • из ushort к int, uint, long, ulong, float, double или decimal;

  • из int к long, float, double или decimal;

  • из uint к long, ulong, float, double или decimal;

  • из long к float, double или decimal;

  • из ulong к float, double или decimal;

  • из char к ushort, int, uint, long, ulong, float, double или decimal;

  • из float к double.

Преобразования из типов int, uint, long или ulong к float, а также из long или ulong к double могут привести к потере точности, но не величины. Другие неявные преобразования числовых типов никогда не приводят к потере данных.

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

Неявные преобразования ссылочных типов

Существуют следующие неявные преобразования ссылочных типов:

Из любого ссылочного типа к object.

Из производного класса к базовому классу.

Из типа класса S к типу интерфейса T (где S реализует T).

Из типа интерфейса S к типу интерфейса T (где S является производным от T).

Из любого типа массива к System.Array и реализуемым им интерфейсам.

Из типа_массива S, который имеет тип элементов SE, к типу_ массива T, который имеет тип элементов TE, если выполняются следующие условия:

S и T различаются только по типу элементов. Другими словами, типы S и T имеют одинаковое число измерений.

SE и TE являются ссылочными_типами.

Существует неявное преобразование ссылочного типа из SE к TE.

Пример

using System;

namespace ConsoleApplication5

{

class Program

{

static void Main()

{

string[] t = new string[2] { "vv", "kkk" };

object[] tt = new object[2];

tt = t;

}

}

}

Пример

Если элемент массива ссылочного типа передается в качестве параметра ссылки или вывода, во время выполнения необходимо убедиться, что фактический тип элементов массива идентичен типу параметра.

using System;

namespace ConsoleApplication5

{

class Program

{

static void F(ref object x) { }

static void Main()

{

object[] a = new object[10];

object[] b = new string[10];

F(ref a[0]); // Ok

F(ref b[1]); // ArrayTypeMismatchException

}

}

}

Понятие упаковки и распаковки является ключевым в системе типов C#. С помощью данных операций осуществляется связь между типами значений и ссылочными типами за счет возможности преобразования любого значения типа значений к типу object и обратно.

Преобразования упаковки

Преобразование упаковки обеспечивает неявное преобразование типа значений в ссылочный тип.

из любого типа значений к типу object. Пример.

int i = 123;

object box = i;

Явные преобразования

Выражение приведения типа используется для явного преобразования выражения в данный тип.

выражение_приведения_к_типу: ( тип ) унарное_выражение

Выражение_приведения_типа вида (T)E, где T является типом, а E —унарным_выражением, выполняет явное преобразование значения E в тип T.

Явные преобразования числовых типов.

Явные преобразования числовых типов предназначены для преобразования из одного числового_типа к другому числовому_типу, для которого не существует неявного преобразования:

  • из sbyte к byte, ushort, uint, ulong или char;

  • из byte к sbyte и char;

  • из short к sbyte, byte, ushort, uint, ulong или char;

  • из ushort к sbyte, byte, short или char;

  • из int к sbyte, byte, short, ushort, uint, ulong или char;

  • из uint к sbyte, byte, short, ushort, int или char;

  • из long к sbyte, byte, short, ushort, int, uint, ulong или char;

  • из ulong к sbyte, byte, short, ushort, int, uint, long или char;

  • из char к sbyte, byte или short;

  • из float к sbyte, byte, short, ushort, int, uint, long, ulong, char или decimal;

  • из double к sbyte, byte, short, ushort, int, uint, long, ulong, char, float или decimal;

  • из decimal к sbyte, byte, short, ushort, int, uint, long, ulong, char, float или double.

Пример. Для выполнения явного преобразования числового типа необходимо

заключить тип, в который производится преобразование (приведение), в скобки перед преобразуемым значением или переменной. Следующая программа выполнят приведение типа double в тип int.

using System;

namespace ConsoleApplication5

{

class Program

{

static void Main()

{

double x = 1234.7;

int a;

// Cast double to int.

a = (int)x;

System.Console.WriteLine(a);

}

}

}

Если x и y являются идентификаторами, то (x)y, (x)(y) и (x)(-y) являются выражениями приведения типа, а (x)-y не является, даже если x обозначает тип. Однако если x является ключевым словом, которое обозначает стандартный тип (например, int), то все четыре вида выражения являются выражениями приведения типа (потому что такое ключевое слово не может само быть выражением). Пример.

using System;

namespace ConsoleApplication5

{

class Program

{

static void Main()

{

double x = 1234.7;

int a;

// Cast double to int.

a = (int)-x;

System.Console.WriteLine(a);

}

}

}

Результат

Операторы checked и unchecked

Операторы checked и unchecked используются для управления контекстом проверки переполнения для арифметических операций и преобразований целого типа.

выражение_checked: checked ( выражение )

выражение_unchecked: unchecked ( выражение )

Оператор checked вычисляет содержащееся в нем выражение в проверяемом контексте.

Оператор unchecked — в непроверяемом. Используется для подавления проверки переполнения при выполнении арифметических операций и преобразований с данными целого типа. В непроверяемом контексте арифметическое переполнение будет проигнорировано, а результат усечен.

В контексте checked для неконстантных выражений (выражений, которые вычисляются во время выполнения), возникает исключение System.OverflowException.

Пример использования оператора unchecked.

Явное преобразование из int к short, где

short

От -32 768 до 32 767

16-разрядное целое число со знаком

System.Int16

int

От -2 147 483 648 до 2 147 483 647

32-разрядное целое число со знаком

System.Int32

int i = 2147483647;

short ixx = unchecked((short)i);

Пример использования оператора checked.

Для неконстантных выражений (выражений, которые вычисляются во время выполнения), не заключенных в операторы или инструкции checked или unchecked, контекстом проверки переполнения по умолчанию является unchecked, если внешние факторы (например, переключатели компилятора и конфигурация среды исполнения) не заставляют установить контекст checked.

Пример.

int i = 2147483647;

short ixx = (short)i;

Если размер исходного типа превышает размер конечного, дополнительные самые старшие разряды исходного значения отбрасываются.

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

Для преобразований из типа decimal к целому типу исходное значение округляется в сторону нуля до ближайшего целого значения. Результатом преобразования является полученное целое значение.

Пример.

decimal d = 10000.5m;

int i =(int)d;

Console.WriteLine(i);

Для типов с плавающей запятой и типа decimal отсутствует неявное преобразование, поэтому для преобразования между этими двумя типами следует использовать приведение. Пример.

Пример.

decimal myMoney = 99.9m;

double x = (double)myMoney;

Console.WriteLine(x);

Если убрать оператор явного преобразования, то программа завершится с ошибкой

Ошибка 1 Не удается неявно преобразовать тип "decimal" в "double". Существует явное преобразование (возможно, пропущено приведение типов)

Преобразования из double к float.

Значение типа double округляется до ближайшего значения типа float. При переполнении арифметической операции или делении на ноль исключение никогда не вызывается, потому что типы чисел с плавающей запятой основаны на стандарте IEEE 754 и включают правила для представления бесконечности и нечисловых значений (NaN).

Явные преобразования ссылочных типов.

Поддерживаются следующие явные преобразования ссылочных типов:

  • Из object любому другому ссылочному_типу.

  • Из любого типа_класса S к любому типу_класса T, если S является базовым классом для T.

Пользовательские явные преобразования

Преобразования с помощью вспомогательных классов.

Пример

int numVal = Convert.ToInt32("29");

Преобразования распаковки.

Преобразование распаковки обеспечивает явное преобразование ссылочного_типа к типу_значений.

Пример.

int i = 123;

object box = i;

i = 666;

i = (int)box;

Лекция 1 часть 4. Введение. Массивы.

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

Типы массива

Тип массива записывается как тип_не_массива, за которым следуют спецификации_ранга:

тип_массива: тип_не_массива спецификации_ранга

тип_не_массива: тип

спецификации_ранга: спецификация_ранга спецификации_ранга спецификация_ранга

спецификация_ранга: [ разделители_размерностейнеобязательно ]

разделители_размерностей: , разделители_размерностей ,

Тип_не_массива является одним из типов, которые сами по себе не являются типом_массива.

Пример. Нельзя использовать int[] в качестве типа массива

int[][] sp = new int[3];

Ошибка Неявное преобразование типа "int[]" в "int[][]" невозможно

int[][] sp = new int[3][3];

Ошибка 1 Недопустимый спецификатор ранга: требуется "," или "]"

int[,] arr = new int[,];

Ошибка 2 При создании массива следует указать размер массива или инициализатор массива

Код, который не приведет к ошибке

Одномерный массив

int[] sp = new int[3];

Двумерный массив

int[,] sp = new int[3,3];

Массив массивов — это массив, элементы которого сами являются массивами.

int[][] arr = new int[2][];

arr[0] = new int[5] { 1, 3, 5, 7, 9 };

arr[1] = new int[4] { 2, 4, 6, 8 };

Console.Write("{0}", arr[0][3]);

Ранг типа массива задается левой спецификацией_ранга в типе_массива: спецификация_ранга указывает, что массив имеет ранг, равный единице плюс число меток «,» в этой спецификации.

Тип элемента массива представляет собой тип, полученный в результате удаления крайней левой спецификации_ранга:

  • Тип массива в форме T[R] указывает массив с рангом R и типом элемента (типом_не_массива) T.

  • Тип массива в форме T[R][R1]...[RN] указывает массив с рангом R и типом элемента T[R1]...[RN].

В результате данные спецификации_ранга считываются слева направо перед последним типом элемента (типом_не_массива). Тип int[][,,][,] указывает одномерный массив трехмерных массивов из двумерных массивов значений с типом int.

Создание массива

Типы массивов являются ссылочными типами.

Во время выполнения значение типа массива может быть равно null или может содержать ссылку на экземпляр массива этого типа.

Первичные выражения разделяются на выражения создания массива и первичные выражения создания не массива.

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

Пример.

int[] arr = { 1, 2, 3 };

int[] arr1 = new int[3];

int[] arr2 = new int[] { 1, 2, 3 };

int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } };

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

Доступ к элементам массива.

Доступ к элементам массива осуществляется при помощи выражений доступа к элементам в форме A[I1, I2, ..., IN], где A является выражением с типом массива, а каждый элемент IX — выражением с типом int, uint, long, ulong либо может быть неявно преобразован в один или несколько из этих типов. Результатом осуществления доступа к элементу массива является переменная, а именно элемент массива, выбранный по индексу.

Элементы массива могут перечисляться с использованием оператора foreach.

В следующем примере создается и инициализируется массив элементов типа int, содержимое созданного массива выводится на консоль.

using System;

namespace ConsoleApplication5

{

class Program

{

static void Main()

{

int[] a = new int[10];

for (int i = 0; i < a.Length; i++)

{

a[i] = i * i;

}

for (int i = 0; i < a.Length; i++)

{

Console.WriteLine("a[{0}] = {1}", i, a[i]);

}

}

}

}

В следующем примере выделяется память для одно-, двух- и трехмерного массивов.

int[] a1 = new int[2];

int[,] a2 = new int[2, 2];

int[, ,] a3 = new int[2, 2, 2];

В примере оператор foreach используется для отображения содержимого массива целых чисел

int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };

foreach (int i in fibarray)

{

System.Console.WriteLine(i);

}

Пример. Просуммировать элементы строк матрицы a. Результат получить в виде вектора (одномерного массива) b:

int[,] a = new int[3, 3] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

int[] b = new int[3];

for (int i = 0; i < 3; i++)

{

int s = 0;

for (int j = 0; j < 3; j++)

s += a[i, j];

b[i] = s;

}

for (int i = 0; i < 3; i++)

Console.Write("{0:d} ", b[i]);

Console.WriteLine();

Console.ReadKey();

Тип System.Array является абстрактным базовым типом для всех типов массива. Выполняется неявное преобразование ссылок из любого типа в тип System.Array, а также явное преобразование ссылок из типа System.Array в любой тип массива. Тип System.Array сам по себе не является типом_массива. Это тип_класса, на основе которого создаются все типы_массива.