1629295407-c61bfe4caba98380ea3e7cdae6295416 (846200), страница 40
Текст из файла (страница 40)
Подробнее о методах и классах209}stck[i] = ob.stck[i];// Устанавливаем переменную tos для нового стека.tos = ob.tos;// Помещаем символ в стек.public void push(char ch) {if(tos==stck.Length) {Console.WriteLine(" -- Стек заполнен.");return;}stck[tos] = ch;tos++;}// Извлекаем символ из стека.public char pop() {if(tos==0) {Console.WriteLine(" -- Стек пуст.");return(char) 0;}tos--;return stck[tos];}// Метод возвращает значение true, если стек заполнен.public bool full() {return tos==stck.Length;}}// Метод возвращает значение true, если стек пуст.public bool empty() {return tos==0;}// Возвращает общий объем стека.public int capacity() {return stck.Length;}// Возвращает текущее количество объектов в стеке.public int getNum() {return tos;}// Демонстрация использования класса Stack.class StackDemo {public static void Main() {Stack stk1 = new Stack(10);char ch;int i;// Помещаем символы в стек stk1.Console.WriteLine(210Часть I.
Язык C#"Помещаем символы от А до Z в стек stk1.");for(i=0; !stk1.full(); i++)stk1.push((char) ('A' + i));// Создаем копию стека stck1.Stack stk2 = new Stack(stk1);// Отображаем содержимое стека stk1.Console.Write("Содержимое стека stk1: ");while( !stk1.empty() ) {ch = stk1.pop();Console.Write(ch);}Console.WriteLine();}}Console.Write("Содержимое стека stk2: ");while( !stk2.empty() ) {ch = stk2.pop();Console.Write(ch);}Console.WriteLine("\n");Результаты выполнения этой программы:Помещаем символы от А до Z в стек stk1.Содержимое стека stk1: JIHGFEDCBAСодержимое стека stk2: JIHGFEDCBAВ классе StackDemo создается пустым первый стек stk1, который заполняетсясимволами.
Этот стек затем используется для создания второго стека stk2, и в этом случаевызывается следующий конструктор класса stack.// Создаем Stack-объект из существующего стека.public Stack(Stack ob) {// Выделяем память для стека.stck = new char[ob.stck.Length];// Копируем элементы в новый стек.for(int i=0; i < ob.tos; i++)stck[i] = ob.stck[i];}// Устанавливаем переменную tos для нового стека.tos = ob.tos;При выполнении кода этого конструктора для массива stck выделяется областьпамяти, причем ее размер позволяет поместить в этот массив все элементы, содержащиеся встеке, заданном в качестве аргумента ob. Затем содержимое базового массива, на которомоснован стек ob, копируется в новый массив, и соответствующим образом устанавливаетсяпеременная индекса tos.
По завершении работы этого конструктора новый и исходныйстеки являются отдельными объектами, но идентичны по своему содержимому.Глава 8. Подробнее о методах и классах211Вызов перегруженного конструктора с помощью ссылки thisПри работе с перегруженными конструкторами иногда необходимо обеспечить вызоводного конструктора из другого. В C# это реализуется с помощью еще одной формыключевого слова this. Общий формат записи такого вызова:имя_конструктора(список_параметров1) :this(список_параметров2) {// ...
Тело конструктора,// которое может быть пустым.}При выполнении перегруженного конструктора сначала вызывается та его версия,список параметров которой совпадает с элементом список_параметров2. При этомбудут выполнены любые инструкции, содержащиеся внутри исходного конструктора.Например:// Демонстрация вызова конструктора с помощью ссылки this.using System;class XYCoord {public int x, y;public XYCoord() : this(0, 0) {Console.WriteLine("Внутри конструктора XYCoord()");}public XYCoord(XYCoord obj) : this(obj.x, obj.y) {Console.WriteLine("Внутри конструктора XYCoord(obj)");}public XYCoord(int i, int j) {Console.WriteLine("Внутри конструктора XYCoord(int, int)");x = i;y = j;}}class OverloadConsDemo {public static void Main() {XYCoord t1 = new XYCoord();XYCoord t2 = new XYCoord(8, 9);XYCoord t3 = new XYCoord(t2);Console.WriteLine("t1.x, t1.y: " + t1.x + ", " + t1.y);Console.WriteLine("t2.x, t2.y: " + t2.x + ", " + t2.y);Console.WriteLine("t3.x, t3.y: " + t3.x + ", " + t3.y);}}Эта программа генерирует следующие результаты:Внутри конструктора XYCoord(int, int)Внутри конструктора XYCoord()Внутри конструктора XYCoord(int, int)Внутри конструктора XYCoord(int, int)Внутри конструктора XYCoord(obj)t1.x, t1.y: 0, 0t2.x, t2.y: 8, 9t3.x, t3.y: 8, 9212Часть I.
Язык C#Вот как работает эта программа. В классе XYCoord единственным конструктором,который реально инициализирует члены x и y, является XYCoord(int, int). Остальныедва конструктора просто вызывают конструктор XYCoord(int, int), используяключевое слово this. Например, при создании объекта t1 вызывается конструкторXYCoord(), выполняющий вызов this(0, 0), который преобразуется в вызовконструктора XYCoord(0, 0), Создание объекта t2 происходит аналогично.Преимущество использования ключевого слова this для вызова перегруженныхконструкторов состоит в том, что можно избежать ненужного дублирования кода. Впредыдущем примере применение слова this позволило избежать дублирования всемитремя конструкторами одного и того же кода инициализации членов. Еще одно достоинствоэтого средства — возможность создавать конструкторы с заданием действующих “поумолчанию” аргументов, которые используются в том случае, когда аргументыконструктора не заданы явным образом.
Например, вы могли бы создать еще одинконструктор класса XYCoord следующим образом:public XYCoord(int x) : this(x, x) { }Этот конструктор автоматически устанавливает координату y равной значениюкоординаты x. Конечно, использовать такие действующие “по умолчанию” аргументынужно очень аккуратно, поскольку их неправильное использование может ввестипользователей в заблуждение.Метод Main()До сих пор мы использовали только одну форму метода Main().
Однако существуетнесколько перегруженных форм этого метода. Одни возвращают значение, а другиепринимают аргументы. Рассмотрением этих форм мы и займемся в следующих разделах.Возвращение значений из метода Main()По завершении программы можно возвратить значение вызывающему процессу(часто в его роли выступает операционная система). Для этого используется следующаяформа методаMain(): public static int Main()Обратите внимание на то, что вместо типа void, эта версия метода Main() имеет вкачестве типа возвращаемого значения int.Обычно значение, возвращаемое методом Main(), служит индикатором того, какбыла завершена программа (нормально или аварийно). По соглашению нулевое значение,как правило, подразумевает нормальное завершение.
Все же другие значения соответствуютопределенным типам ошибок.Передача аргументов методу Main()Многие программы принимают аргументы командной строки. Аргумент команднойстроки — это информация, которая указывается при запуске программы сразу после ееимени в командной строке. Эти аргументы затем передаются методу Main(). Для работы саргументами командной строки необходимо использовать одну из следующих форм методаMain():public static void Main(string[] args)public static int Main(string[] args)Глава 8. Подробнее о методах и классах213Первая форма возвращает значение типа void, а вторую можно использовать длявозврата целочисленного значения, как описано в предыдущем разделе.
В обоих случаяхаргументы командной строки хранятся как строки в string-массиве, передаваемом методуMain().Следующая программа отображает все аргументы командной строки, с которыми онабыла вызвана.// Отображение всей информации из командной строки.using System;class CLDemo {public static void Main(string[] args) {Console.WriteLine("Командная строка содержит " +args.Length + " аргументов.");Console.WriteLine("Вот они: ");}}for(int i=0; i<args.Length; i++)Console.WriteLine(args[i]);Предположим, мы запустили на выполнение программу CLDemo следующимобразом:CLDemo один два три четыре пятьВ этом случае мы увидим такие результаты:Командная строка содержит 5 аргументов.
Вот они:одиндватричетырепятьЧтобы “попробовать на вкус” возможности использования аргументов команднойстроки, рассмотрим следующую программу. Она кодирует и декодирует сообщения.Сообщение, предназначенное для кодирования или декодирования, указывается вкомандной строке. Метод шифрования очень прост: чтобы закодировать слово, код каждойего буквы инкрементируется на 1.
В результате буква “А” превращается в букву “Б” и т.д.Чтобы декодировать слово, достаточно код каждой его буквы декрементировать на 1.// Кодирование и декодирование сообщений.using System;class Cipher {public static int Main(string[] args) {// Проверка наличия аргументов.if(args.Length < 2) {Console.WriteLine("ИСПОЛЬЗОВАНИЕ: " +"слово1: <<закодировать>>/<<раскодировать>> " +"[слово2... словоN]");return 1; // Возврат признака неверного выполнения.}// Если аргументы присутствуют, то первым аргументом214Часть I.
Язык C#// должно быть слово "закодировать" или "раскодировать".if(args[0]!= "закодировать" & args[0] != "раскодировать") {Console.WriteLine("Первым аргументом должно быть слово " +"\"закодировать\" или \"раскодировать\".");return 1; // Возврат признака неверного выполнения.}// Кодируем или декодируем сообщение.for(int n=1; n < args.Length; n++) {for(int i=0; i < args[n].Length; i++) {if(args[0]=="закодировать")Console.Write((char) (args[n][i] + 1) );elseConsole.Write((char) (args[n][i] - 1) );}}}}Console.Write(" ");Console.WriteLine();return 0;Чтобы использовать эту программу, укажите после ее имени командное слово“закодировать” или “раскодировать”, а затем фразу, подлежащую соответствующейоперации.
В предположении, что эта программа называется Cipher, приводим два примераее выполнения.D:\Cipher закодировать один два пейо егбD:\Cipher раскодировать пейо егб один дваВ этой программе есть два интересных момента. Во-первых, обратите внимание нато, как проверяется наличие аргументов командной строки. Это очень важный момент,который можно обобщить. Если работа программы опирается на один или несколькоаргументов командной строки, всегда необходимо удостовериться в том, что эти аргументыдействительно переданы программе.