Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Управление программой с помощью исключений






В качестве примера применения механизма исключений не для исправления ошибок ввода, а для управления программой, рассмотрим обработку исключения System. IndexOutRangeException. Это исключение посылается при попытке обратиться к элементу массива с помощью индексного выражения, когда индекс выходит за пределы его граничной пары. В обработке исключений будем увеличивать размер массива, то есть выполним моделирование " растущего" массива. Напишем метод, реализующий ввод с клавиатуры целых чисел в массив. Окончанием ввода будет служить ввод нулевого числа. Так как количество вводимых чисел заранее неизвестно, то нужен массив, изменяющий свои размеры в процессе выполнения программы.

Предварительно определим статический метод varyArray(), позволяющий изменять размер одномерного массива по следующим правилам. Параметры метода: аг - ссылка на исходный массив и размер int newSize нового массива, который будет сформирован методом. Если значение параметра newSize меньше длины исходного массива, то в получаемый массив копируются только newSize первых элементов исходного массива. Если newSize больше длины исходного массива, то значения всех элементов исходного массива присваиваются первым newSize элементам формируемого массива. Остальные элементы (как мы знаем) по умолчанию инициализируются нулевыми значениями. Код метода:

static int[] varyArray(int[] ar, int newSize)

{

int[] temp = new int[newSize];

Array.Copy(ar, temp, newSize < ar.Length? newSize: ar.Length);

return temp;

}

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

У приведённого в следующей программе метода с заголовком public static int[] arrayRead() параметров нет. Для него исходными данными служат значения (целые числа), которые пользователь вводит с клавиатуры. Конец ввода - ввод нулевого числа. Текст программы с указанными методами:

// 16_04.cs – растущий массив и исключения

class Method

{

// Изменить размер массива до значения newSize:

static int[] varyArray(int[] ar, int newSize)

{

int[] temp = new int[newSize];

Array.Copy(ar, temp, newSize < ar.Length? newSize: ar.Length);

return temp;

}

// Читать числа в растущий массив:

public static int[] arrayRead()

{

int k = 0, // Количество прочитанных чисел

dimAr = 2, // Текущий размер массива

x; // Вводимое число

int[] row = new int[dimAr];

while (true)

{

do

Console.Write(" x = ");

while (! int.TryParse(Console.ReadLine(), out x));

if (x == 0) break;

try

{

row[k] = x;

k++;

}

catch (IndexOutOfRangeException)

{

dimAr *= 2;

row = Method.varyArray(row, dimAr);

row[k++] = x;

}

} //end while

row = Method.varyArray(row, k);

return row;

}

}

public static void Main()

{

int[] res = Method.arrayRead();

foreach (int memb in res)

Console.Write(memb + " ");

}

Результат выполнения программы:

x = 1< ENTER>

x = 2< ENTER>

x = 3< ENTER>

x = 4< ENTER>

x = 5< ENTER>

x = 0< ENTER>

12 3 4 5

В методе arrayRead() объявлены несколько переменных: k - счётчик прочитанных и сохранённых в создаваемом массиве ненулевых чисел; dimAr -текущий размер массива, который вначале равен 2; х - переменная, которой присваивается введённые пользователем числовое значение; row - ссылка на одномерный целочисленный массив, элементам которого присваиваются вводимые числовые значения.

Ввод чисел и сохранение их в массиве, адресованном ссылкой row, выполняется в " бесконечном" цикле с заголовком while(true). В его теле вспомогательный цикл с постусловием (такой цикл мы уже неоднократно применяли в программах) обеспечивает корректный ввод значения х. Если х после ввода оказывается равным нулю, то оператор break; прекращает выполнение " бесконечного" цикла. Для ненулевого значения х делается попытка присваивания row[k]=x. Если k< dimAr, то присваивание выполняется благополучно, значение k увеличивается на 1 и следует переход к новой итерации цикла – читается новое значение х. Как только k достигает значение dimAr (а вначале эта величина равна 2), выполнение row[k]=x становится невозможным и возникает исключение типа IndexOutRangeException. Управление передаётся за пределы контролируемого блока – оператор k++; не выполняется. Посланное исключение перехватывает соответствующий ему catch-обработчик. В его теле удваивается значение переменной dimAr и переменной row присваивается ссылка на новый увеличенный вдвое массив, первые элементы которого получают значение уже введённые с клавиатуры. Далее в этот массив заносится значение х, и увеличивается на 1 счётчик обработанных чисел, что обеспечивает оператор row[k++]=x;. Блок try и соответствующий ему обработчик catch целиком размещены в конце цикла, поэтому следует переход к его очередной итерации.

При выходе из цикла (когда х получит нулевое значение) следует обращение к методу varyArray(row, k). При этом к равно реальному количеству значений, присвоенных первым к элементам массива, адресованного ссылкой row. Формируемый этим методом массив- будет содержать только реально введённые пользователем ненулевые числа. " Лишних" элементов в хвосте созданного методом arrayRead() массива не будет. Сказанное подтверждают результаты выполнения метода Main(), где оператор foreach выводит значения всех элементов созданного массива.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.