KnigaRead.com/
KnigaRead.com » Разная литература » Прочее » Герберт Шилдт - C# 4.0 полное руководство - 2011

Герберт Шилдт - C# 4.0 полное руководство - 2011

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн "Герберт Шилдт - C# 4.0 полное руководство - 2011". Жанр: Прочее издательство неизвестно, год неизвестен.
Перейти на страницу:

Для извлечения элемента из стека вызывается открытый метод Pop (), приведенный ниже.

// Извлечь символ из стека, public char Рор() { if(tos==0)    {

Console.WriteLine (" - Стек пуст."); return (char) 0;

}

tos — ;

return stck[tos];

}

В этом методе сначала проверяется значение переменной tos. Если оно равно нулю, значит, стек пуст. В противном случае значение переменной tos декрементируется, и затем из стека возвращается элемент по указанному индексу.

Несмотря на то что для реализации стека достаточно методов Push () и Pop (), полезными могут оказаться и другие методы. Поэтому в классе Stack определены еще четыре метода: IsFull (), IsEmpty (), Capacity () и GetNum (). Эти методы предоставляют всю необходимую информацию о состоянии стека и приведены ниже.

return tos;

}

Метод IsFull () возвращает логическое значение true, если стек заполнен, а иначе — логическое значение false. Метод IsEmpty () возвращает логическое значение true, если стек пуст, а иначе — логическое значение false. Для получения общей емкости стека (т.е. общего числа элементов, которые могут в нем храниться) достаточно вызвать метод Capacity (), а для получения количества элементов, хранящихся в настоящий момент в стеке, — метод Get Num (). Польза этих методов состоит в том, что для получения информации, которую они предоставляют, требуется доступ к закрытой переменной tos. Кроме того, они служат наглядными примерами организации безопасного доступа к закрытым членам класса с помощью открытых методов.

Конкретное применение класса Stack для реализации стека демонстрируется в приведенной ниже программе.

// Продемонстрировать применение класса Stack, using System;

// Класс для хранения символов в стеке, class Stack {

// Эти члены класса являются закрытыми, char[] stck; // массив, содержащий стек int tos;    // индекс вершины стека

// Построить пустой класс Stack для реализации стека заданного размера, public Stack(int size) {

stck = new char[size]; // распределить память для стека tos = 0;

}

// Поместить символы в стек, 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 IsFullO { return tos==stck.Length;

}

// Возвратить значение true, если- стек пуст, public bool IsEmptyO {

return tos==0;

}

// Возвратить общую емкость стека, public int Capacity()    {

return stck.Length;

}

// Возвратить количество объектов, находящихся в данный момент в стеке, public int GetNum() { return tos;

}

}

class StackDemo {

static void Main()    {

Stack    stkl    =    new    Stack (10);

Stack    stk2    =    new    Stack(lO);

Stack    stk3    =    new    Stack(10);

char ch; int i;

// Поместить ряд символов в стек stkl.

Console.WriteLine("Поместить символы А-J в стек stkl."); for(i=0; !stkl.IsFull(); i++) stkl.Push((char)    ('A1    +    i));

if(stkl.IsFull()) Console.WriteLine("Стек stkl заполнен.");

// Вывести содержимое стека stkl.

Console.Write("Содержимое стека stkl: "); while( !stkl.IsEmpty()    )    {

ch = stkl.Pop();

Console.Write(ch);

}

Console.WriteLine();

if(stkl.IsEmpty()) Console.WriteLine("Стек stkl пуст.п");

// Поместить дополнительные символы в стек stkl.

Console.WriteLine("Вновь поместить символы А-J в стек stkl."); for(i=0; !stkl.IsFull(); i++) stkl.Push((char)    ('A'    + i));

// А теперь извлечь элементы из стека stkl и поместить их в стек stk2. // В итоге элементы сохраняются в стеке stk2 в обратном порядке. Console.WriteLine("А теперь извлечь символы из стека stkln" +

"и поместить их в стек stk2."); while( !stkl.IsEmpty()    )    {

ch = stkl.Pop(); stk2.Push(ch);

Console.Write("Содержимое стека stk2: "); while( !stk2.IsEmpty() )    {

ch = stk2.Pop();

Console.Write(ch);

}

Console.WriteLine("n");

// Поместить 5 символов в стек.

Console.WriteLine("Поместить 5 символов в стек stk3."); for(i=0; i < 5; i++)

stk3.Push((char) ('A1 + i)) ;

Console.WriteLine("Емкость стека stk3: " + stk3.Capacity()); Console.WriteLine("Количество объектов в стеке stk3: " + stk3.GetNum());

}

}

При выполнении этой программы получается следующий результат.

Поместить символы А-J в стек stkl.

Стек stkl заполнен.

Содержимое стека stkl: JIHGFEDCBA Стек stkl пуст.

Вновь поместить символы А-J в стек stkl.

А теперь извлечь символы из стека stkl и поместить их в стек stk2.

Содержимое стека stk2: ABCDEFGHIJ

Поместить 5 символов в стек stk3.

Емкость стека stk3: 10 Количество объектов в стеке stk3: 5

Передача объектов методам по ссылке

В приведенных до сих пор примерах программ при указании параметров, передаваемых методам, использовались типы значений, например int или double. Но в методах можно также использовать параметры ссылочного типа, что не только правильно, но и весьма распространено в ООП. Подобным образом объекты могут передаваться методам по ссылке. В качестве примера рассмотрим следующую программу.

// Пример передачи объектов методам по ссылке.

using System;

class MyClass { int alpha, beta;

public MyClass(int i, int j) { alpha = i; beta = j;

// Возвратить значение true, если параметр ob // имеет те же значения, что и вызывающий объект, public bool SameAs(MyClass ob) {

if ((ob.alpha == alpha) & (ob.beta == beta)) return true; else return false;

}

// Сделать копию объекта ob. public void Copy(MyClass ob) { alpha = ob.alpha; beta = ob.beta;

}

public void Show() {

Console.WriteLine("alpha: {0}, beta: {1}", alpha, beta);

}

}

class PassOb {

static void Main() {

MyClass obi = new MyClass(4, 5);

MyClass ob2 = new MyClass (6, 7);

Console.Write("obi: "); obi.Show ();

Console.Write("ob2: "); ob2.Show();

if(obi.SameAs(ob2))

Console.WriteLine("obi и ob2 имеют одинаковые значения."); else

Console.WriteLine("obi и ob2 имеют разные значения."); Console.WriteLine() ;

// А теперь сделать объект obi копией объекта ob2. obi.Copy(ob2);

Console.Write("obi после копирования: "); obi.Show();

if(obi.SameAs(ob2) )

Console.WriteLine("obi и ob2 имеют одинаковые значения."); else

Console.WriteLine("obi и ob2 имеют разные значения.");

}

}

Выполнение этой программы дает следующий результат.

obi: alpha: 4, beta: 5 ob2: alpha: 6, beta: 7

оЫ и ob2 имеют разные значения.

оЫ после копирования: alpha: 6, beta: 7 obi и оЬ2 имеют одинаковые значения.

Каждый из методов Same As () и Сору () в приведенной выше программе получает ссылку на объект типа MyClass в качестве аргумента. Метод Same As () сравнивает значения переменных экземпляра alpha и beta в вызывающем объекте со значениями аналогичных переменных в объекте, передаваемом посредством параметра ob. Данный метод возвращает логическое значение true только в том случае, если оба объекта имеют одинаковые значения этих переменных экземпляра. А метод Сору () присваивает значения переменных alpha и beta из объекта, передаваемого по ссылке посредством параметра ob, переменным alpha и beta из вызывающего объекта. Как показывает данный пример, с точки зрения синтаксиса объекты передаются методам по ссылке таким же образом, как и значения обычных типов.

Способы передачи аргументов методу

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

Первым способом является вызов по значению. В этом случае значение аргумента копируется в формальный параметр метода. Следовательно, изменения, вносимые в параметр метода, не оказывают никакого влияния на аргумент, используемый для вызова. А вторым способом передачи аргумента является вызов по ссылке. В данном случае параметру метода передается ссылка на аргумент, а не значение аргумента. В методе эта ссылка используется для доступа к конкретному аргументу, указываемому при вызове. Это означает, что изменения, вносимые в параметр, будут оказывать влияние на аргумент, используемый для вызова метода.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*