Решение задач с использованием индексаторов и свойств
Особенности использования индексаторов. Основные сведения о методах доступа к индексаторам. Свойства и массивы. Пример объявления одномерного индексатора, возвращающего значение типа int. Пример объявления двумерного индексатора. Перегрузка индексаторов.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 04.12.2021 |
Размер файла | 186,3 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Размещено на http://www.allbest.ru/
МИНИСТЕРСТВО ВЫСШЕГО И СРЕДНЕГО ОБРАЗОВАНИЯ
ФЕРГАНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ФАКУЛЬТЕТ ФИЗИКА-МАТЕМАТИКА
КУРСОВАЯ РАБОТА
Направление: “Прикладная математика и информатика”
Студент группы 19.09(р)
Ибрагимова Зубайда
Дисциплина: “Основы программирования”
По тема: “Решение задач с использованием индексаторов и свойств.”
г.Фергана 2021
ВВЕДЕНИЕ
Индексатор позволяет работать с классом или структурой таким образом, как если бы это были массивы. Индексация класса выполняется по индексу, указываемому как параметр. Иногда классы, используемые как индексаторы, называют классами-индексаторами.
Объявление индексатора может иметь следующее формальное описание:
[атрибуты] [модификаторы] тип this [[атрибуты]
тип_параметра идентификатор_параметра .,...]
{объявление аксессоров}
Индексатор должен иметь как минимум один параметр. Тип и идентификатор параметра указываются в квадратных скобках после ключевого слова this.
Среда проектирования Visual Studio.NET позволяет использовать мастер создания индексатора: для этого в окне Class View следует выделить имя класса и выполнить команду контекстного меню Add|Add Indexer.
Диалог C# Indexer Wizard (рис. 17.1) позволяет определить параметры создаваемого индексатора.
Цель работы:
Познакомиться с основой объектного подхода в языке C#, созданием объектов и классов.
1. ИСПОЛЬЗОВАНИЕ ИНДЕКСАТОРОВ
Прочитав эту главу, вы научитесь:
* инкапсулировать с помощью индексаторов логический доступ к объекту, работающий наподобие доступа к элементам массива;
* управлять доступом к индексаторам для чтения из них данных, объявляя методы доступа get;
* управлять доступом к индексаторам для записи в них данных, объявляя методы доступа set;
* создавать интерфейсы, объявляющие индексаторы;
* осуществлять реализацию в структурах и классах индексаторов, наследуемых из интерфейсов.
В г «Реализация свойств для доступа к полям» рассматривались способы реализации и использования свойств как средств предоставления управляемого доступа к полям класса. Свойства могут использоваться для зеркального отображения полей, содержащих единственное значение. Но индексаторы незаменимы при обеспечении доступа к элементам, содержащим несколько значений, и при реализации этого доступа с использованием понятного и знакомого синтаксиса.
Что такое индексатор?
Индексатор можно представить себе в качестве более разумно организованного массива, что во многом похоже на представление свойства в качестве более разумно организованного поля. Свойство инкапсулирует в классе одно значение, а индексатор делает то же самое для набора значений. Для индексатора используется точно такой же синтаксис, как и для массива.
Разобраться с тем, что такое индексатор, лучше всего на примере. Сначала будет рассмотрена задача, в которой не используются индексаторы. Затем та же задача будет решена более эффективно за счет применения индексаторов. В задаче используются целые числа, или, если точнее, значения int-типа.
Пример без использования индексаторов.
Обычно int-тип используется для хранения целочисленного значения. Внутри машины значения int-типа сохраняются в виде последовательности из 32 битов, где каждый бит может содержать либо 0, либо 1. Чаще всего это внутреннее двоичное представление вас абсолютно не касается, вы просто используете int-тип в качестве контейнера, содержащего целочисленное значение. Но иногда программисты применяют int-тип для других целей -- некоторые из них используют int в качестве набора двоичных флагов и работают внутри значения int-типа с отдельными битами. Если вы такой же приверженец языка C старой закалки, как и я, то все, что вы прочтете дальше, навеет весьма живые воспоминания.
ПРИМЕЧАНИЕ В некоторых устаревших программах int-типы используются с целью экономии памяти. Эти программы создавались во времена, когда объемы компьютерной памяти измерялись в килобайтах, а не гигабайтах, как сегодня, и память была дефицитной. Тип int с одинарной точностью хранил 32 бита, каждый из которых мог быть либо единицей, либо нулем. В некоторых случаях программисты присваивали единицу, чтобы показать истинное значение (true), и нуль, чтобы показать ложное значение (false), а затем использовали int-тип как набор булевых значений.
В C# предоставляется набор операторов, которыми можно воспользоваться для доступа к отдельным битам в int-значении и работы с ними. К таким операторам относятся:
* оператор НЕ (~). Это унарный оператор, выполняющий поразрядное дополнение. Например, если взять 8-битное значение 11001100 (это десятичное число 204) и применить к нему оператор ~, то в результате получится значение 00110011 (это десятичное число 51) -- все единицы в исходном значении стали нулями, а нули превратились в единицы;
ПРИМЕЧАНИЕ Показанные здесь примеры имеют чисто иллюстративное назначение и верны только для 8 бит. В C# int-тип имеет размерность 32 бита, поэтому при попытке применения любого из этих примеров в приложении C# будет получаться 32-битный результат, который может отличаться от результата, показанного в данной подборке примеров. Например, при 32 битах число 204 имеет вид 00000000000000000000000011001100, поэтому в C# ~204 будет иметь вид 11111111111111111111111100110011 (что фактически является представлением в C# десятичного числа -205).
* оператор сдвига влево (<<). Это бинарный оператор, выполняющий сдвиг влево. Выражение 204 <<2 возвращает значение 48. (В двоичном виде десятичное число 204 отображается как 11001100, и его сдвиг влево на две позиции дает результат 00110000, или десятичное число 48.) Самые левые биты удаляются, а справа появляются нули. Существует также аналогичный оператор, осуществляющий сдвиг вправо (>>);
* оператор ИЛИ (|). Это бинарный оператор, выполняющий поразрядную операцию ИЛИ, возвращающую значение, содержащую единицу в каждом разряде, в котором в любом из операндов имеется единица. Например, выражение 204 | 24 дает значение 220 (204 -- это 11001100, 24 -- это 00011000, а 220 -- это 11011100);
* оператор И (&). Этот оператор выполняет поразрядную операцию И. Оператор И похож на оператор ИЛИ, но он возвращает значение, содержащее единицу в каждом разряде, в котором у обоих операндов имеется единица. Поэтому выражение 204 & 24 дает результат 8 (204 -- это 11001100, 24 -- это 00011000, а 8 -- это 00001000);
* оператор исключающего ИЛИ (^). Этот оператор выполняет поразрядную операцию исключающего ИЛИ, возвращая единицу в каждом разряде, в котором имеется единица в каком-либо из операндов, но не в обоих вместе. (Две единицы дают нуль, в этом и выражается «исключающая» часть оператора.) Следовательно, выражение 204 ^ 24 дает результат 212 (11001100 ^ 00011000 является 11010100).
Для определения значений отдельных битов в int-типе эти операторы могут использоваться вместе. Например, в следующем выражении используются операторы сдвига влево (<<) и поразрядного И (&), в результате чего определяется, какое значение имеет шестой разряд справа байтовой переменной по имени bits -- нуль или единицу:
(bits & (1 << 5)) != 0
ПРИМЕЧАНИЕ Поразрядные операторы вычисляют позиции разрядов справа налево, а разряды отсчитываются, начиная с нуля. Соответственно, самым правым является нулевой разряд, а разряд в позиции с номером 5 -- шестым справа.
Предположим, что переменная bits содержит десятичное число 42. В двоичном выражении оно имеет вид 00101010. Десятичное значение 1 соответствует двоичному значению 00000001, а выражение 1 << 5 имеет значение 00100000, где шестой разряд установлен в единицу. В двоичном виде выражение bits & (1 << 5) выглядит как 00101010 & 00100000, и значение этого выражения в том же двоичном виде выглядит как 00100000, то есть не является нулем. Если переменная bits содержит значение 65, или в двоичном виде 01000001, значение выражения выглядит как 01000001 & 00100000, что дает двоичный результат 00000000, или нуль.
Это довольно сложный пример, но по сравнению со следующим выражением, в котором для установки бита в позиции 6 в нуль используется оператор составного присваивания &=, он представляется простым:
bits &= ~(1 << 5)
Аналогично этому, если требуется установить бит в позиции 6 в единицу, можно воспользоваться поразрядным оператором ИЛИ (|). Следующее сложное выражение основано на применении составного оператора |=:
bits |= (1 << 5)
Применение таких примеров затруднено тем, что, несмотря на их полную состоятельность, в них неимоверно сложно разобраться. К тому же решение с их применением находится на одном из самых низких уровней программирования: на его основе невозможно создать абстракцию выполняемой задачи, что существенно усложняет сопровождение кода, выполняющего подобные операции.
Тот же пример с использованием индексаторов.
Давайте немного отвлечемся от предыдущего низкоуровневого решения и вспомним, что представляет собой эта задача. Вам нужно воспользоваться int-типом не по прямому его назначению, а в качестве массива битов. Поэтому наилучшим способом решения этой задачи станет использование int-типа таким образом, будто он является массивом битов, или, иными словами, обеспечение возможности получения доступа к шестому биту справа в переменной bits путем использования следующего выражения (не забываем, что индексирование массивов начинается с нуля):
bits[5]
А для установки для четвертого бита справа значения true хотелось бы иметь возможность написать следующее:
bits[3] = true
ПРИМЕЧАНИЕ Для опытных разработчиков приложений на языке C булево значение true является синонимом двоичного значения 1, а булево значение false -- двоичного значения 0. Соответственно, выражение bits[3] = true означает: «Установить в переменной bits для четвертого бита справа значение 1».
К сожалению, воспользоваться системой записи с квадратными скобками в отношении int-значения невозможно, она работает только в отношении массива или типа данных с поведением массива. Поэтому решение задачи заключается в создании нового типа, работающего как массив, воспринимаемого как массив и используемого качестве массива булевых переменных, но реализуемого с использованием int-значения. Достичь желаемого результата можно с помощью индексатора. Давайте назовем этот новый тип IntBits. Он будет содержать int-значение (инициализированное в своем конструкторе), но суть замысла в том, что значение типа IntBits будет использоваться в качестве массива булевых переменных.
СОВЕТ Тип IntBits представляется весьма простым, поэтому имеет смысл создать его в виде структуры, а не в виде класса.
struct IntBits
{
private int bits;
public IntBits(int initialBitValue)
{
bits = initialBitValue;
}
7
}
Для определения индексатора используется система записи, являющаяся гибридом записи свойства и массива. Индексатор вводится с помощью ключевого слова this, при этом указывается тип возвращаемого индексатором значения, а в квадратных скобках указывается тип значения, используемого в индексаторе в качестве индекса. В индексаторе для структуры IntBits в качестве типа его индекса используется целое число, а возвращает он булево значение:
struct IntBits
{
...
public bool this [ int index ]
{
get
{
return (bits & (1 << index)) != 0;
}
set
{
if (value) // если value равно true, установка, аиначе - сбросбита
bits |= (1 << index);
else
bits &= ~(1 << index);
}
}
}
Обратите внимание на следующие особенности.
* Индексатор не является методом: параметры в круглых скобках отсутствуют, а в квадратных скобках указывается индекс, который используется для указания того, к какому элементу происходит обращение.
* Индексаторы используют ключевое слово this. В классе или структуре может быть определено не более одного индексатора (хотя его можно переопределить и иметь несколько реализаций), и он всегда называется this.
* В индексаторах, как и в свойствах, содержатся методы доступа get и set. В данном примере методы доступа get и set содержат ранее рассмотренные сложные поразрядные выражения.
* Индекс, указанный в объявлении индексатора, заполняется индексным значением, указанным при вызове индексатора. Методы доступа get и set могут считать этот аргумент для определения элемента, к которому осуществляется доступ.
ПРИМЕЧАНИЕ Во избежание любых неожиданных исключений, выдаваемых в коде индексатора, в индексаторе нужно проверять значение индекса на его принадлежность к допустимому диапазону значений.
После объявления индексатора вы можете вместо int-переменной воспользоваться переменной типа IntBits и, как показано в следующем примере, применить к ней систему записи с использованием квадратных скобок:
int adapted = 126; // Двоичный вид числа 126 -- 01111110
IntBits bits = new IntBits(adapted);
bool peek = bits[6]; // извлечение булева значения по индексу 6;
// оно должно быть true (1)
bits[0] = true; // установка бита по индексу 0 в true (1)
bits[3] = false; // установка бита по индексу 3 в false (0)
// теперь в bits содержится значение 01110111,
или 119 в десятичном исчислении
Вполне очевидно, что разобраться в этом синтаксисе будет гораздо проще. В нем довольно лаконично и непосредственно отражается суть задачи.
Основные сведения о методах доступа к индексаторам.
При чтении с использованием индексатора компилятор автоматически преобразует ваш код, имеющий признаки массива, в вызов метода доступа get данного индексатора. Рассмотрим следующий пример:
bool peek = bits[6];
Эта инструкция преобразуется в вызов метода доступа get для индексатора bits, а для аргумента index устанавливается значение 6.
Аналогично этому при записи с использованием индексатора компилятор автоматически преобразует ваш код, имеющий признаки массива, в вызов метода доступа set данного индексатора, устанавливая для аргумента index значение, заключенное в квадратные скобки:
bits[3] = true;
Эта инструкция преобразуется в вызов метода доступа set для индексатора bits, а для аргумента index устанавливается значение 3. Как и в обычных свойствах, данные, записываемые в индексатор (в данном случае true), становятся доступными внутри метода доступа set при использовании ключевого слова value. Тип у переменной value такой же, как тип у самого индексатора (в данном случае bool).
Индексатор также можно применять в сложном контексте чтения/записи. В таком случае используются оба метода доступа, и get, и set. Посмотрите на следующую инструкцию, в которой используется оператор ИЛИ (^), чтобы инвертировать значение бита с индексом 6 в переменной bits:
bits[6] ^= true;
Это выражение будет автоматически преобразовано в следующий код:
bits[6] = bits[6] ^ true;
Работоспособность этого кода обеспечивается наличием обоих методов доступа, get и set.
ПРИМЕЧАНИЕ Можно объявить индексатор, содержащий только метод доступа get (индексатор только для чтения) или только метод доступа set (индексатор только для записи).
Сравнение индексаторов и массивов
При использовании индексатора намеренно применяется синтаксис, очень похожий на тот, что применяется в массивах. Но между индексаторами и массивами имеется ряд весьма важных различий.
* В индексаторах могут использоваться нечисловые индексы, например строки (как показано в следующем примере), а в массивах могут использоваться только целочисленные индексы:
public int this [ string name ] { ... } // Допустимо
* Индексаторы могут перегружаться (точно так же, как методы), а массивы не могут:
public Name this [ PhoneNumber number ] { ... }
public PhoneNumber this [ Name name ] { ... }
* Индексаторы не могут использоваться в качестве ref- или out-параметров, а массивы могут:
IntBits bits; // bits содержит индексатор
Method(ref bits[1]); // ошибка в ходе компиляции.
2. СВОЙСТВА, МАССИВЫ И ИНДЕКСАТОРЫ
Свойство может возвращать массив, но следует помнить, что массивы относятся к ссылочным типам, поэтому предоставление массива в качестве свойства позволяет случайно перезаписать большой массив данных. Посмотрите на следующую структуру, предоставляющую свойство по имени Data, содержащее массив:
struct Wrapper
{
private int[] data;
...
public int[] Data
{
get { return this.data; }
set { this.data = value; }
}
}
Теперь посмотрите на следующий код, использующий это свойство:
Wrapperwrap = newWrapper();
...
int[] myData = wrap.Data;
myData[0]++;
myData[1]++;
Его внешний вид вроде бы ничем не настораживает. Но поскольку массивы относятся к ссылочным типам, переменная myData ссылается на тот же самый объект, что и закрытая переменная data в структуре Wrapper. Любые изменения, вносимые в элементы в myData, делаются в массиве data, а выражение myData[0]++ производит точно такой же эффект, что и выражение data[0]++. Если это противоречит вашим замыслам, нужно в методах доступа get и set свойства Data воспользоваться методом Clone, чтобы возвращалась копия массива data, или сделать копию устанавливаемого значения, как показано в следующем примере кода. (Метод Clone для копирования массивов рассматривался в главе 8 «Основные сведения о значениях и ссылках».) Учтите, что метод Clone возвращает объект, который следует привести к типу целочисленного массива:
struct Wrapper
{
private int[] data;
...
public int[] Data
{
get { return this.data.Clone() as int[]; }
set { this.data = value.Clone() as int[]; }
}
}
Но с точки зрения использования памяти этот подход может оказаться слишком грубым и неэкономичным. А индексаторы позволяют решить эту задачу намного проще и естественнее -- не нужно предоставлять в качестве свойства весь массив, вместо этого лучше через индексатор сделать доступными его отдельные элементы:
struct Wrapper
{
private int[] data;
...
public int this [int i]
{
get { return this.data[i]; }
set { this.data[i] = value; }
}
}
В следующем коде индексатор используется примерно так же, как и в показанном ранее свойстве:
Wrapper wrap = new Wrapper();
...
int[] myData = new int[2];
myData[0] = wrap[0];
myData[1] = wrap[1];
myData[0]++;
myData[1]++;
Теперь увеличение значений в массиве myData на единицу не влияет на исходный массив Wrapper-объекта. Если же действительно понадобится изменить данные во Wrapper-объекте, придется написать следующую инструкцию:
wrap[0]++;
Так будет намного понятнее и безопаснее!
Индексаторы в интерфейсах.
Индексаторы можно объявлять в интерфейсе. Для этого указываются ключевое слово get, ключевое слово set или же оба этих слова, но вместо тела метода доступа get или set ставится точка с запятой. Любые реализующие интерфейс класс или структура должны включать и реализацию методов доступа к индексатору, объявленному в интерфейсе:
interface IRawInt
{
bool this [ int index ] { get; set; }
}
struct RawInt : IRawInt
{
...
public bool this [ int index ]
{
get { ... }
set { ... }
}
...
}
Если индексатор интерфейса реализуется в классе, объявление индексатора можно сделать виртуальным. Это позволит последующим производным классам перегружать методы доступа get и set:
class RawInt : IRawInt
{
...
public virtual bool this [ int index ]
{
get { ... }
set { ... }
}
...
}
Можно также выбрать реализацию индексатора с использованием синтаксиса явной реализации, рассмотренного в главе 13 «Создание интерфейсов и определение абстрактных классов». Явная реализация индексатора не может иметь модификатор доступа public и объявляться виртуальной (и, соответственно, не может быть перегружена):
struct RawInt : IRawInt
{
...
bool IRawInt.this [ int index ]
{
get { ... }
set { ... }
}
...
}
3. ИСПОЛЬЗОВАНИЕ ИНДЕКСАТОРОВ В ПРИЛОЖЕНИИ WINDOWS
В следующем упражнении будет исследовано и завершено приложение простой телефонной книги. В классе PhoneBook будут созданы два индексатора: один, принимающий параметр типа Name (имя) и возвращающий значение типа PhoneNumber (номер телефона), и второй, действующий наоборот, то есть принимающий параметр PhoneNumber и возвращающий Name. (Структуры Name и PhoneNumber будут содержаться в упражнении в готовом виде.) Вам также нужно будет вызвать эти индексаторы из подходящих для этого мест в программе.
Ознакомьтесь с приложением.
Откройте в среде Microsoft Visual Studio проект Indexers, который находится в папке \Microsoft Press\VCSBS\Chapter 16\Indexers вашей папки документов.
С помощью этого графического приложения пользователь может искать номер телефона делового партнера, а также искать имя делового партнера по заданному номеру телефона.
Щелкните в меню Отладка на пункте Начать отладку. Произойдут сборка и запуск приложения и появится форма с пустыми текстовыми полями Name (Имя) и Phone Number (Номер телефона). Изначально в форме имеются две кнопки: одна для поиска телефона при заданном имени, другая для поиска имени при заданном номере телефона. Если раскрыть панель управления в нижней части формы, появится кнопка Add (Добавить), которая добавит к списку имен и номеров телефона, хранящемуся в приложении, еще одну пару «имя -- номер телефона». Все кнопки, включая Add на панели управления, в данный момент ничего не делают. Приложение имеет вид, показанный на рис. 16.1.
Вам предстоит завершить приложение и заставить кнопки работать.
Вернитесь в среду Visual Studio 2015 и остановите отладку.
Выведите в окно редактора файл Name.cs проекта Indexers. Изучите структуру Name. Она предназначена для работы в качестве хранилища имен. Имя предоставляется конструктору в виде строки. Это имя может быть извлечено путем использования строкового свойства Text, предназначенного только для чтения. (Методы Equals и GetHashCode используются для сравнения имен при сквозном поиске в массиве из Name-значений, и пока их можно проигнорировать.)
Выведите в окно редактора файл PhoneNumber.cs и изучите структуру PhoneNumber. Она похожа на структуру Name.
Выведите в окно редактора файл PhoneBook.cs и изучите класс PhoneBook.
Рис. 1 - Класс PhoneBook
В этом классе содержатся два закрытых массива: массив Name-значений по имени names и массив PhoneNumber-значений по имени phoneNumbers. Класс PhoneBook содержит также метод Add, добавляющий номер телефона и имя в телефонную книгу. Этот метод вызывается, когда пользователь щелкает на имеющейся в форме кнопке Add. Метод enlargeIfFull вызывается методом Add для проверки заполненности массивов, когда пользователь добавляет еще одну запись. Этот метод создает два новых, более крупных массива, копируя в них содержимое существующих массивов, после чего уничтожает старые массивы.
Метод Add намеренно упрощен и не проверяет, добавлялись ли уже в телефонную книгу данные имя или телефон.
Класс PhoneBook пока не предоставляет функциональных возможностей, с помощью которых пользователь смог бы найти имя или номер телефона. В следующем упражнении для реализации такой возможности вами будут добавлены два индексатора.
Создание индексаторов.
Удалите из файла PhoneBook.cs комментарий // TODO: write 1st indexer here, заменив его открытым, предназначенным только для чтения индексатором для класса PhoneBook, выделенным в следующем примере кода жирным шрифтом. Индексатор будет возвращать Name-значение, получив в качестве своего индекса PhoneNumber-значение. Оставьте тело метода доступа get пустым.
Индексатор должен иметь следующий вид:
sealed class PhoneBook
{
...
public Name this[PhoneNumber number]
{
get
{
}
}
...
}
Реализуйте метод доступа get, выделенный в следующем примере кода жирным шрифтом.
Метод доступа предназначен для поиска имени, соответствующего указанному номеру телефона. Для этого вам нужно вызвать статический метод IndexOf, принадлежащий классу Array. Метод IndexOf осуществляет сквозной поиск в массиве, возвращая индекс первого же элемента массива, соответствующего указанному значению. Первым аргументом IndexOf является массив для выполнения сквозного поиска (phoneNumbers). Вторым аргументом IndexOf является искомый элемент. IndexOf возвращает целочисленный индекс элемента, если таковой будет найден, в противном случае возвращает -1. Если индексатор находит номер телефона, он должен возвращать соответствующее имя, а в противном случае -- пустое Name-значение. (Учтите, что Name является структурой, следовательно, пассивный конструктор установит для его закрытого поля name значение null.)
sealed class PhoneBook
{
...
public Name this [PhoneNumber number]
{
get
{
int i = Array.IndexOf(this.phoneNumbers, number);
if (i != -1)
{
return this.names[i];
}
else
{
return new Name();
}
}
}
...
}
Заменитекомментарий // TODO: write 2ndindexerhere вторымоткрытым, предназначеннымтолькодлячтенияиндексаторомдлякласса PhoneBook, возвращающим PhoneNumber-значениеипринимающимодин Name-параметр. Реализуйте этот индексатор точно так же, как и первый индексатор. (Тут снова следует учесть, что PhoneNumber является структурой, всегда имеющей пассивный конструктор.)
Второй индексатор должен иметь следующий вид:
sealed class PhoneBook
{
...
public PhoneNumber this [Name name]
{
get
{
int i = Array.IndexOf(this.names, name);
if (i != -1)
{
return this.phoneNumbers[i];
}
else
{
return new PhoneNumber();
}
}
}
...
}
Обратите внимание на возможность сосуществования этих перегружаемых индексаторов, обусловленную тем, что их индексы имеют разные типы, а значит, и разные сигнатуры. Если бы структуры Name и PhoneNumber были заменены простыми строками (которые в них заключены), перегрузка имела бы одинаковую сигнатуру и класс не прошел бы компиляцию.
Щелкните в меню Сборка на пункте Собрать решение, исправьте все синтаксические ошибки, если таковые обнаружатся, а затем, если это необходимо, выполните повторную сборку решения.
4. ВЫЗОВ ИНДЕКСАТОРОВ
Выведите в окно редактора файл MainPage.xaml.cs и найдите метод findByNameClick. Этот метод вызывается при щелчке на кнопке Find By Name (Найти по имени). На данный момент код в нем отсутствует. Замените комментарий // TODO: кодом, выделенным в следующем примере жирным шрифтом. Этот код выполняет следующие задачи:
* считывает значение свойства Tex, имеющегося в форме текстового поля name. В этой строке содержится имя делового партнера, набранное пользователем;
* если строка не является пустым значением, с помощью индексатора ищет номер телефона, соответствующий этому имени в телефонной книге PhoneBook. (Заметьте, что в классе MainPage содержится закрытое PhoneBook-поле по имени phoneBook.) Код создает из строки Name-объект и передает его в качестве параметра индексатору PhoneBook;
* если возвращенное индексатором свойство Text, принадлежащее структуре PhoneNumber, не содержит значение null или не является пустым, записывает значение этого свойства в имеющееся в форме текстовое поле phoneNumber. В противном случае в это поле выводится текст «Not Found», свидетельствующий о том, что поиск не удался.
В окончательном виде метод findByNameClick должен выглядеть следующим образом:
private void findByNameClick(object sender, RoutedEventArgs e)
{
string text = name.Text;
if (!String.IsNullOrEmpty(text))
{
Name personsName = new Name(text);
PhoneNumber personsPhoneNumber = this.phoneBook[personsName];
phoneNumber.Text = String.IsNullOrEmpty(personsPhoneNumber.Text) ?
"Not Found" : personsPhoneNumber.Text;
}
}
Кроме инструкции, которая обращается к индексатору, у этого кода есть еще две интересные особенности.
* Статический String-метод по имени IsNullOrEmpty используется для определения того, не является ли строка пустой и не содержит ли она null-значение. Это метод лучше всего подходит для тестирования строки на наличие в ней значения. Он возвращает true, если строка содержит значение null или является пустой, а в противном случае возвращает значение false.
* Инструкция, заполняющая свойство Text текстового поля phoneNumber, использует оператор ? :, который действует как встроенная в выражение инструкция if…else. Этот оператор работает с тремя операндами: булевым выражением, выражением для вычисления и возвращения в случае вычисления булева выражения в true и еще одним выражением для вычисления и возвращения в случае вычисления булева выражения в false. Есливпредыдущемкодевыражение String.IsNullOrEmpty(personsPhoneNumber.Text) вычисляется в true, что означает, что совпадений в записях телефонной книги найдено не было, то в форме выводится текст «Not Found»; в противном случае выводится значение, хранящееся в свойстве Text переменной personsPhoneNumber.
В общем виде оператор ? : имеет следующий синтаксис:
Результат = <булево выражение> ? <Вычисляется, если true> : <Вычисляется,
если false>
Найдите в файле MainPage.xaml.cs метод findByPhoneNumberClick, который находится ниже метода findByNameClick. Метод findByPhoneNumberClick вызывается при щелчке на кнопке Find By Phone Number (Найти по номеру телефона). Пока в этом методе нет ничего, кроме комментария // TODO:. Вам нужно реализовать этот метод, вставив в него код. (Полный код метода показан в следующем примере жирным шрифтом.)
Прочитайте значение свойства Text из имеющегося в форме текстового поля phoneNumber. Это строка, содержащая номер телефона, набранный пользователем.
Если в строке есть содержимое, воспользуйтесь индексатором для поиска имени, соответствующего этому номеру телефона в PhoneBook.
Запишите в принадлежащее форме поле name значение возвращенного индексатором свойства Text, принадлежащего структуре Name.
В окончательном варианте метод должен приобрести следующий вид:
private void findByPhoneNumberClick(object sender, RoutedEventArgs e)
{
string text = phoneNumber.Text;
if (!String.IsNullOrEmpty(text))
{
PhoneNumber personsPhoneNumber = new PhoneNumber(text);
Name personsName = this.phoneBook[personsPhoneNumber];
name.Text = String.IsNullOrEmpty(personsName.Text) ?
"NotFound" : personsName.Text;
}
}
Щелкнитевменю Сборка на пункте Собрать решение и исправьте любые выявленные ошибки.
Тестирование приложения.
Щелкните в меню Отладка на пункте Начать отладку. Наберите в соответствующих полях свое имя и номер телефона, затем раскройте панель управления и щелкните на кнопке Add (Добавить) (панель управления раскрывается по щелчку на символе многоточия). При щелчке на кнопке Add (Добавить) метод Add сохраняет информацию в телефонной книге и очищает текстовые поля, подготавливая их к поиску.
Наберите несколько разных имен и номеров, чтобы в телефонной книге появилась подборка записей. Учтите, что приложение не проверяет вводимые имена и номера телефонов и одно и то же имя и один и тот же номер телефона можно ввести более одного раза. Чтобы не мешать демонстрации работы программы и исключить путаницу, постарайтесь задавать разные имена и номера телефонов.
Наберите одно из ранее введенных имен в поле Name и щелкните на кнопке Find By Name (Найти по имени). Из телефонной книги будет извлечен и выведен в текстовое поле Phone Number номер телефона, ранее присвоенный вами этому деловому партнеру.
Наберите в поле Phone Number номер телефона другого делового партнера, а затем щелкните на кнопке Find By Phone Number (Найти по номеру телефона). Из телефонной книги будет извлечено и показано в поле Name имя делового партнера.
Наберите в поле Name имя, которое не вводилось в телефонную книгу, а затем щелкните на кнопке с надписью Find By Name (Найти по имени). На этот раз в поле с надписью Phone Number будет выведено сообщение о том, что номер не найден, -- «Not Found».
Закройте форму и вернитесь в среду Visual Studio 2015.
В этой главе вы узнали, как использовать индексаторы, предоставляющие к данным класса такой же доступ, как и к элементам массива. Вы научились создавать индексаторы, которые могут принимать индекс и возвращать соответствующее значение с использованием логики, определяемой в методе доступа get, и увидели, как используется с индексом метод доступа set, предназначенный для того, чтобы заполнить значение в индексаторе.
Если хотите продолжить работу и изучить следующую главу, оставьте открытой среду Visual Studio 2015 и переходите к главе 17 «Введение в обобщения».
Если сейчас вы хотите выйти из среды Visual Studio 2015, то в меню Файл щелкните на пункте Выход. Увидев диалоговое окно с предложением сохранить изменения, щелкните на кнопке Да и сохраните проект.
Краткий справочник
Чтобы Сделайте следующее Создать индексатор для класса или структуры Объявите тип индексатора, затем наберите ключевое слово this, а после него укажите в квадратных скобках аргументы индексатора. В теле индексатора может содержаться метод доступа get и/или set, например: struct RawInt { ... public bool this [ int index ] { get { ... } set { ... } } ... } Определить индексатор в интерфейсе Определите индексатор с ключевым словом get и/или set, например: interface IRawInt { bool this [ int index ] { get; set; } } Реализовать интерфейсный индексатор в классе или структуре Определите в классе или структуре, реализующей интерфейс, индексатор и реализуйте методы доступа к нему, например: struct RawInt : IRawInt { ... public bool this [ int index ] { get { ... } set { ... } } ... } Реализовать индексатор, определенный в интерфейсе, путем явной реализации интерфейса в классе или структуре Укажите индексатор в классе или в структуре, реализующей интерфейс, но не указывайте степень его доступности, например: struct RawInt : IRawInt { ... bool IRawInt.this [ int index ] { get { ... } set { ... } } ... |
Пример объявления одномерного индексатора, который возвращает значение типа char.
Одномерный индексатор соответствует одномерному массиву. В примере объявляется класс CharArray, содержащий индексатор.
// класс, который содержит индексатор
class CharArray
{
char[] A;
// конструкторкласса
public CharArray(int size)
{
if (size > 26) size = 26;
A = new char[size];
for (int i = 0; i < size; i++)
A[i] = (char)((int)'A' + i);
}
// объявлениеиндексатора
public char this[int index]
{
get // чтение из позиции index
{
if ((index >= 0) && (index < A.Length))
return A[index];
else
return 'A';
}
set // запись в позицию index
{
if ((index>=0) && (index<A.Length))
A[index] = value;
}
}
}
В вышеприведенном коде объявляется индексатор, возвращающий значение элементов типа char. Значения индексов имеют тип int.
В индексаторе реализуются два аксесора: get, set. В теле реализации аксессоров осуществляется проверка на выход индекса за пределы допустимого диапазона [0 .. Size-1].
Демонстрация использования класса в другом программном коде
...
// использование класса CharArray
CharArray cA = new CharArray(15); // массивиз 15 символов
char c;
c = cA[0]; // c = 'A'
c = cA[3]; // c = 'D'
c = cA[10]; // c = 'K'
c = cA[14]; // c = 'O'
c = cA[15]; // c = 'A' - попытка доступа за допустимые пределы
c = cA[30]; // c = 'A' - попытка доступа за допустимые пределы
cA[3] = 'Z';
c = cA[3]; // c = 'Z'
cA[30] = 'X'; // допускается, но блокируется в в аксессоре set { ... }
c = cA[30]; // c = 'A'
...
Пример объявления одномерного индексатора, возвращающего значение типа int.
В примере реализуется класс, который содержит одномерный индексатор, который возвращает значение типа int. Тип индексов в индексаторе также int.
// класс, содержащий индексатор
class IntArray
{
int[] Array; // массив
public IntArray(int size)
{
// выделить память для массива
Array = new int[size];
// обнулитьмассив
for (int i = 0; i < size; i++)
Array[i] = 0;
}
// индексатор
public int this[int index]
{
// аксессоры
get { return Array[index]; }
set { Array[index] = value; }
}
}
Использование класса IntArray в другом программном коде
// использованиекласса IntArray
IntArray iA = new IntArray(100);
inti;
int d;
// заполнение значениями массива через индексатор
for (i = 0; i< 100; i++)
iA[i] = i * i + 1;
d = iA[3]; // d = 10
d = iA[25]; // d = 626
iA[25] = 15;
d = iA[25]; // d = 15
Пример объявления одномерного индексатора в котором реализован индекс типа char.
Тип индекса в индексаторе не обязательно должен быть целочисленным. Можно объявлять и другой тип индекса, например double, char. Но в этом случае при использовании внутреннего массива нужно привести тип индекса из другого типа (double, char, …) к типу int.
Следующий пример демонстрирует применение индексатора в классе, в котором значение индекса есть числом типа char. Данный пример реализует подсчет количества символов латинского алфавита `A' … `Z' в заданной строке.
// класс, в котором индекс в индексаторе есть типа char
class CharIndex
{
int[] Array;
int Size;
public CharIndex()
{
Size = 26;
Array = new int[Size];
for (int i = 0; i < Size; i++)
Array[i] = 0;
}
// индексатор
public int this[char symbol]
{
get
{
if ((symbol>='A') && (symbol<='Z'))
return Array[(int)((int)symbol - (int)'A')];
return 0;
}
set
{
if ((symbol>='A') && (symbol<='Z'))
Array[(int)symbol-(int)'A'] = value;
}
}
}
Как видно из вышеприведенного кода, в аксессорах get и set, индекс массива Array приводится к типу int. Однако, из программного кода, к объекту класса CharIndex можно доступиться по индексу типа char.
Использование класса в другом программном коде
// использованиекласса CharIndex
CharIndex cI = new CharIndex();
string s = "USING AN INDEXERS IN PROGRAMS";
int d;
int i;
char c;
// подсчет количества символов 'A'..'Z'
for (i = 0; i<s.Length; i++)
cI[s[i]]++;
d = cI['U']; // d = 1
d = cI['A']; // d = 2
d = cI['N']; // d = 4
d = cI['I']; // d = 3
Пример объявления двумерного индексатора.
В примере объявляется двумерный индексатор, который реализует двумерный массив чисел типа double.
// класс, который реализует двумерный индексатор
class TwoDimIndexes
{
double[,] A; // внутренний массив элементов
int m, n; // размерность массива
// конструктор
public TwoDimIndexes(int _m, int _n)
{
m = _m;
n = _n;
A = new double[m, n];
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
A[i, j] = 0;
}
// двумерныйиндексатор
public double this[int i, int j]
{
get { return A[i, j]; }
set { A[i, j] = value; }
}
}
Использование класса TwoDimIndexes в некотором программном коде
// использованиекласса TwoDimIndexes
TwoDimIndexes dI = new TwoDimIndexes(3, 5);
doublex;
// формирование массива с помощью индексатора
for (inti = 0; i< 3; i++)
for (int j = 0; j < 5; j++)
dI[i, j] = i * 2 + j;
x = dI[1, 3]; // x = 1*2 + 3 = 5
x = dI[2, 0]; // x = 4
Пример объявления трехмерного индексатора.
Объявляется класс, который содержит трехмерный индексатор
// класс, в котором объявляется трехмерный индексатор
classThreeDimIndexes
{
double[, ,] M; // трехмерныймассив
int x, y, z; // размерность массива
// конструктор
public ThreeDimIndexes(int _x, int _y, int _z)
{
x = _x;
y = _y;
z = _z;
// Выделить память для массива M
M = new double[3, 4, 5];
}
// трехмерныйиндексатор
public double this[int i, int j, int k]
{
get
{
bool fi, fj, fk;
// проверка на допустимые границы индексов массива
fi = (i >= 0) && (i < x);
fj = (j >= 0) && (j < y);
fk = (k >= 0) && (k < z);
if (fi && fj && fk)
return M[i, j, k];
else
return 0.0;
}
set
{
bool fi, fj, fk;
// проверка на допустимые границы индексов массива
fi = (i >= 0) && (i < x);
fj = (j >= 0) && (j < y);
fk = (k >= 0) && (k < z);
if (fi && fj && fk)
M[i, j, k] = value;
else
M[i, j, k] = 0.0;
}
}
}
Использование класса в другом программном коде
// использованиекласса ThreeDimIndexes
ThreeDimIndexes dI = new ThreeDimIndexes(3, 4, 5);
doublex;
// формирование значений элементов массива с помощью индексатора
int i, j, k;
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
for (k = 0; k < 5; k++)
dI[i, j, k] = i * 2.5 + j * 2 + k;
x = dI[0, 1, 3]; // x = 0*2.5 + 1*2 + 3 = 5.0
x = dI[1, 3, 2]; // x = 1*2.5 + 3*2 + 2 = 10.5
Какие особенности использования индексаторов без базового массива.
В классе не обязательно объявлять внутреннюю переменную-массив для того, чтобы использовать индексатор. Конечно, данные можно сохранять и во внутренней переменной (массиве). Однако, бывают случаи, когда значение элементов массива формируются программно, то есть поддаются некоторой закономерности или формуле. В этих случаях не обязательно объявлять внутренний массив, для сохранения которого нужна дополнительная память.
Пример объявления класса, который содержит индексатор, но не содержит базового массива. Вычисление значения n-го числа Фибоначчи.
В классе CFibonacci объявляется индексатор, который формирует число Фибоначчи на основе его позиции в ряде. Для определения числа, в классе реализован скрытый (private) дополнительный метод GetNumber(). Класс не содержит конструктора. Индексатор в классе содержит только один аксессор get.
Реализация класса имеет следующий вид
// класс, который содержит индексатор без использования внутреннего массива
class CFibonacci
{
// внутренний метод
// вычисляет значение числа Фибоначчи по его позиции index
private int GetNumber(int index)
{
if (index < 0) return -1;
int t = 0;
if (index == 1) t = 1;
if (index == 2) t = 1;
if (index > 2)
{
int t1, t2;
int i;
t1 = t2 = 1;
i = 2;
while (i<index) // циклвычислениячислаФибоначчи
{
t = t1 + t2;
t1 = t2;
t2 = t;
i++;
}
}
return t;
}
// индексатор
public int this[int index]
{
get { return GetNumber(index); }
}
}
ИспользованиеклоассаCFibonacciвдругомпрограммномкоде
// использование индексатора без внутреннего базового массива
CFibonacci cF = new CFibonacci();
int d;
// прочитать число Фибоначчи
d = cF[5]; // d = 5
d = cF[7]; // d = 13
d = cF[10]; // d = 55
Что называется перегрузкой индексаторов?
Перегрузка индексатора - это реализация в классе нескольких индексаторов, которые имеют разные типы индекса (например int, char, double).
В общем виде реализация такого класса выглядит следующим чином:
class ClassName
{
...
public return_type this[type1 index]
{
// ...
}
public return_type this[type2 index]
{
// ...
}
...
public return_type this[typeN index]
{
// ...
}
...
}
где
ClassName - имя класса, в котором объявляется перегруженный индексатор;
return_type - тип элемента индексатора. Этот тип есть общим для всех перегруженных индексаторов;
type1, type2, …, typeN - типы индексов с именем index.
Пример объявления класса, в котором используются перегруженные индексаторы.
В классе CDoubleArray демонстрируется использование перегруженного индексатора
// класс, который содержит перегруженный индексатор
class CDoubleArray
{
double[] A;
int length;
public CDoubleArray(int _length)
{
length = _length;
A = new double[length];
for (int i = 0; i < length; i++) // занести произвольные значения в массив
A[i] = i * 2;
}
// перегруженныйиндексатор
public double this[int index]
{
get { return A[index]; }
set { A[index] = value; }
}
public double this[double index]
{
get { return A[(int)(index+0.5)]; }
set { A[(int)(index+0.5)] = value; }
}
}
Использование класса CDoubleArray в другом программном коде
// использование перегруженного индексатора
CDoubleArray dA = new CDoubleArray(10);
doubled;
d = dA[3]; // d = 6
d = dA[3.3]; // d = 6
d = dA[3.5]; // d = 8
dA[4.7] = 1100;
d = dA[5]; // d = 1100
ЗАКЛЮЧЕНИЕ
индексатор массив перегрузка доступ
Индексаторы следует создавать при наличии в вашем классе элемента, подобного свойству, если такое свойство представляет не одно значение, а коллекцию значений, где каждый отдельный элемент определяется набором аргументов. Эти аргументы могут однозначно определять, на какой элемент в коллекции необходимо ссылаться. Индексаторы расширяют концепцию свойств, где член обрабатывается как элемент данных за пределами класса и как метод -- в его пределах. Индексаторы позволяют аргументам находить в свойстве один элемент, который представляет набор элементов.
СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ
1. Бишоп, Дж. C# в кратком изложении / Дж. Бишоп, Н. Хорспул. - М.: Бином. Лаборатория знаний, 2013. - 472 c.
2. Вагнер, Билл С# Эффективное программирование / Билл Вагнер. - М.: ЛОРИ, 2013. - 320 c.
3. Зиборов, В.В. Visual C# 2012 на примерах / В.В. Зиборов. - М.: БХВ-Петербург, 2013. - 480 c.
4. Мак-Дональд, Мэтью Silverlight 5 с примерами на C# для профессионалов / Мэтью Мак-Дональд. - М.: Вильямс, 2013. - 848 c.
5. Марченко, А. Л. Основы программирования на С# 2.0 / А.Л. Марченко. - М.: Интернет-университет информационных технологий, Бином. Лаборатория знаний, 2011. - 552 c.
6. Подбельский, В. В. Язык С#. Базовый курс / В.В. Подбельский. - М.: Финансы и статистика, Инфра-М, 2011. - 384 c.
7. Смоленцев, Н. К. MATLAB. Программирование на Visual С#, Borland JBuilder, VBA (+ CD-ROM) / Н.К. Смоленцев. - М.: ДМК Пресс, 2011. - 456 c.
8. Троелсен, Эндрю Язык программирования C# 5.0 и платформа .NET 4.5 / Эндрю Троелсен. - М.: Вильямс, 2015. - 486 c.
9. Троелсен, Эндрю Язык программирования С# 2008 и платформа .NET 3.5 / Эндрю Троелсен. - М.: Вильямс, 2010. - 370 c.
10. http://diplom.avorut.ru
11. http://vladdelphisite.narod.ru
12. http://diplom.avorut.ru
13. https://studbooks.net
Размещено на Allbest.ru
...Подобные документы
Объявление, выделение, освобождение памяти под динамические массивы. Обращение к элементам. Решение задач с использованием динамических массивов на языке C++. Разработка и реализация программы для формирования и обработки динамического двумерного массива.
курсовая работа [813,4 K], добавлен 13.06.2014Широкое использование компьютерных и информационных технологий. Концепции типов данных. Алгоритмы сортировки одномерных массивов. Описание двумерного массива Паскаля. Методы доступа к элементам массивов. Индексные, динамические и гетерогенные массивы.
курсовая работа [66,3 K], добавлен 07.12.2010Ознакомление с понятием, особенностями объявления, инициализацией и принципами работы с одномерными и двумерными массивами. Изучение смысла тернарной операции вывода элементов матрицы. Рассмотрение сущности и способов использования указателей переменных.
лабораторная работа [22,1 K], добавлен 15.07.2010Пример дерева решений. Анализ древовидной структуры данных. Предикторные (зависимые) переменные как признаки, описывающие свойства анализируемых объектов. Решение задач классификации и численного прогнозирования с помощью деревьев классификации.
презентация [391,1 K], добавлен 09.10.2013Пример решения задач и построения диаграмм с использованием функции "Подбор параметра". Анализ суммы выплат по вкладу и расчет размера пенсионных накоплений с помощью MS Excel. Вычисление радиуса описанной окружности по трем сторонам треугольника.
реферат [958,2 K], добавлен 19.08.2010Разработка приложения по обмену услугами для владельцев собак. Создание личного кабинета с персональными данными. Редактирование: личных данных, объявления, питомца. Алгоритм редактирования и удаления объявления. Тестирование данного программного средства
дипломная работа [2,8 M], добавлен 14.10.2016Основные приемы работы с классами и объектами. Перегрузка функций и операторов. Массивы объектов. Реализация одиночного наследования. Множественное наследование. Виртуальные функции. Шаблоны: понятие и функциональные особенности, свойства и применение.
методичка [1,1 M], добавлен 16.04.2012Изучение понятия и основных видов массивов. Ввод массива с клавиатуры и вывод на экран. Сортировка массивов. Метод простых обменов (пузырьковая сортировка). Сортировка простым выбором и простым включением. Решение задач с использованием массивов Паскаля.
курсовая работа [82,1 K], добавлен 18.03.2013Понятие перегрузки (доопределения) операций и её разновидности. Пример соответствующей программы перегрузки, понятие полиморфизма и правила isA. Использование классов операторов в программах языка С++, конструкций операторов и производных классов.
реферат [19,9 K], добавлен 30.10.2011Именованная совокупность переменных. Традиционный пример и сведения о структурах. Пример программы создающий список и выводящий его содержимое на консоль. Программа подсчета ключевых слов. Доступ к элементам объединения. Записи в линейном списке.
методичка [35,9 K], добавлен 06.07.2009История появления и распространения Turbo Pascal - среды разработки для языка программирования Паскаль. Общий вид объявления файлового типа. Входная, выходная и промежуточная информация. Алгоритм решения задачи: словесный алгоритм, блок-схема, программа.
курсовая работа [359,4 K], добавлен 05.01.2010Форматы шрифтовых файлов. Сущность понятия "текст", его стиль. Пример нескольких атрибутов шрифта. Гарнитура, начертание, индекс. Инструменты для работы с текстом в Photoshop. Панель свойств инструмента "текст", пример деформации. Палитра "символ, абзац".
лекция [1,8 M], добавлен 28.11.2013Принципы программирования файловой структуры в операционной системе Windows. Свойства и методы класса Tstream. Пример создания, чтения и записи потока. Чтение, запись и внутренняя структура файла. Пример чтения из файла, начиная с заданной позиции.
курсовая работа [251,6 K], добавлен 18.05.2011Определение понятий "процедура" и "функция", порядок их объявления для нескольких модулей. Перечень возможных вариантов расположения подпрограмм и особенности их использования. Осуществление передачи параметров в подпрограммы по значению и наименованию.
лабораторная работа [116,0 K], добавлен 30.09.2012Рассмотрение особенностей объявления функций на языке СИ. Определение понятий аргументов функции и их переменных (локальных, регистровых, внешних, статических). Решение задачи программным методом: составление блок-схемы, описание функций main и sqr.
презентация [125,5 K], добавлен 26.07.2013Графики вещественнозначных функций вещественного переменного. Построение двумерных графиков. Пример построения графика синусоиды. Пример использования функции subplot. Оформление двумерных графиков в системе MatLab. Основные функции оформления графиков.
курсовая работа [826,3 K], добавлен 30.04.2019Краткие теоретические сведения о методах защиты информации и ограничения доступа к персональному компьютеру. Способы ограничения доступа к информации в файле в офисных программах MS Word, MS Excel. Зашифровка данных с помощью архиваторов и системы EFS.
методичка [753,5 K], добавлен 15.07.2014Общие сведения о функциях, их структура. Области видимости и классы памяти переменных в функциях. Классификация видов памяти, выделяемой под переменные и константы. Примеры объявления глобальных и локальных переменных. Обращение к функции и ее прототип.
презентация [64,6 K], добавлен 09.12.2013Разработка программного средства для поиска альтернативных решений многокритериальных задач. Проектирование программного средства с помощью объектно-ориентированного подхода. Пример листинга программного кода. Особенности работы программы на примере.
контрольная работа [346,5 K], добавлен 11.06.2011Типизация данных в JavaScript. Правила объявления локальных и глобальных переменных. Объявление и использование функций. Открытие и закрытие файла, запись в него и чтение из него. Создание теста с использованием средств языка программирования PHP скрипт.
контрольная работа [73,8 K], добавлен 25.01.2016