Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Структура как тип и совокупность данных

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

struct имя_нового_типа {

определение компонентного данного_1;

определение компонентного данного _N;

определение или описание компонентной функции_1;

определение или описание компонентной функции_K;

};

где имя_нового_типа – это идентификатор (имя), которое программист даёт новому типу данных; компонентные данные – это фундаментальные или определённые пользователем типы данных; компонентные функции – это функции реализующие поведение объёкта (его создание, уничтожение, множество операций над ним и т.д.).

В этом параграфе мы остановимся на способе определения нового типа данных с помощью struct и опустим пока рассмотрение возможностей, связанных с компонентными функциями. В качестве примера приведём определение нового тип address:

struct address { char* name; // имя long number; // номер дома char* street; // улица char* town; // город char state[2]; // штат int zip; // индекс };

Итак, в этом примере мы определили новый тип данных - address. Этот тип данных содержит шесть полей компонентных данных (name, number, street, town, state, zip), каждый из которых является переменной фундаментального типа данных. Возникает вопрос: Существуют ли какие-либо ограничения на типы данных, включаемых в структурированный объект? Да, одно ограничение существует. Нельзя в определении типа включить поле данных того же самого типа, т.е. определение struct adr { adr z;}; запрещено правилами языка Си++, но включать указатель на тот же самый тип struct adr { adr* z;}; уже можно.

Поскольку address – это новый тип данных то по аналогии с фундаментальными типами данных мы можем определить объект типа address, указатель на объект типа address, массив объектов типа address, ссылку на объект типа address, и т.п. Приведём пример:

int i=2; //определена и инициализирована переменная i типа int.

int *pi = &i, ari[3] = {1,3,7}, &rfi = i; /* определение и инициализация указателя pi на объект типа int; определение и инициализация массива ari объектов типа int; определение ссылки rfi на объект типа int.*/

address Nik={"Jim Dandy", 61, "South Street", "New Providence", {‘N’,‘J’}, 1974};. /*Определение и инициализация структурированного объекта Nik типа address. Его поля данных name, street, town инициализируются адресами начиная с которых строки "Jim Dandy", "South Street", "New Providence" размещаются в памяти соответственно. Его поля number, zip инициализируются числами 61 и 1974 соответственно. Элементы массива state объекта Nik инициализируется символами ‘N’, ‘J’ */

address *pNik = &Nik, ArAddr[3], &rfNik= Nik; /* определение и инициализация указателя pNik на объект типа address; определение массива ArAddr объектов типа address; определение ссылки rfNik на объект типа address.*/

Как видно из примера структурированный объект, в данном случае Nik, можно не только определить, но и сразу инициализировать. Поле данных name объекта Nik будет равно адресу, начиная с которого в памяти расположена строковая константа "Jim Dandy"; поле number объекта Nik получает значение 61 и т.д.

Иногда нет необходимости вводить новый тип данных, но есть необходимость определить несколько объектов структурированного типа. В этом случае после ключевого слова struct опускают имя типа, пример:

struct { char N[12]; int value;} XX, Y[7], *pXX; / * определение структурированного объекта XX, массива структурированных объектов Y, и указателя на структурированный объект рХХ. Каждый из объектов содержит массив N и поле value.*/

Поскольку в этом примере не было дано имя новому типу, то соответственно нет возможности за пределами определения создать объекты этого типа, другими словами XX и массив Y будут единственными объектами этого безымянного структурированного типа.

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

Полная форма (квалифицированное имя) Краткая форма (уточненное имя)
имя_объекта.имя_типа::имя_поля_данных имя_объекта. имя_поля_данных
указатель_на_объект-> имя_типа::имя_поля_данных указатель_на_объект-> имя_поля_данных
(*указатель_на_объект). имя_типа::имя_поля_данных (*указатель_на_объект).имя_поля_данных

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

В таблице мы впервые виде как используются операции (точка), (стрелочка) и (двойное двоеточие) для структурированного объекта. Если посмотреть в таблицу приоритетов операций, то видно, что они имеют самый высокий ранг. Кроме того если выражение имя_объекта имеет тип структурированного данного, то выражение имя_объекта.имя_поля_данных, или указатель_на_объект->имя_поля_данных, или (*указатель_на_объект).имя_поля данных совпадает с типом поля данных, пример:

Nik.name // выражение имеет тип char* и с ним можно делать всё, что раньше делалось с переменной char*

Nik.name = “Иванов”; /*Указатель name типа char* структурированного объекта Nik настраивается на начало фрагмент памяти, в котором расположена литерная константа “Иванов “*/

Nik.number = 34; /*C помощью операции точка получили доступ к полю number структурированного объекта Nik и присвоили ему значение 34. Выражение Nik.number имеет тип long */

ArAddr[0].number =75; /*C помощью операции точка получили доступ к полю number структурированного объекта ArAddr[0] и присвоили ему значение 75. Выражение ArAddr[0].number имеет тип long */

pNik->street = “Фрунзе”; /* C помощью операции стрелочка и указателя на объект Nik получили доступ к полю street объекта Nik. Поскольку поле street в определении структурированного объекта имеет тип char*, то выражение pNik->street тоже имеет тип char*. В данном случае в поле street структурированного объекта Nik запоминается адрес, начиная с которого в памяти размещена строковая константа “Фрунзе”.*/

(*pNik).zip = 3456; /* Такой способ записи в принципе эквивалентен первому, так как операция звёздочка – это операция разыменования указателя, следовательно вместо скобок появится объект, и с помощью операции точка мы получим доступ к полю zip и присвоим ему значение 3456. Выражение (*pNik).zip естественно имеет тип int. */

Таким образом в нашем примере мы переопределили значение некоторых полей структурированного объекта Nik. Если их значения вывести на печать с помощью строк программы

cout << “\n Фамилия: “<< Nik.name << “\t Номер дома: “<<Nik.number<<”\t Улица: “<<Nik.street;

cout<<”\t Город: <<Nik.state<<”\t Штат: “<<Nik.state[0]<< Nik.state[1]<<”\t Индекс: “<<Nik.zip;

то мы получим на экране

Фамилия: Иванов Номер дома: 34 Улица: Фрунзе Город: New Providence Штат: NJ Индекс: 3456

Строка программы cout<< Nik будет выдавать ошибку, так как объект cout «знает» как выводить на печать все объекты основных типов данных, но не объекты типа address. Для того чтобы эта строка заработала необходимо написать компонентную функцию и переопределить поведение объекта cout для объекта типа address. Но этим мы займёмся позже.

Необходимо также отметить, что при определении любого структурированного объекта для каждого из них выделяется свой собственный фрагмент памяти под все поля данных, записанных в определении структурированного типа, т.е. структурированный объект имеет свою собственную независимую от других объектов копию всех полей компонентных данных. Другими словами записав Nik.number, мы обращаемся к полю number структурированного объекта Nik, а записав ArAddr[0].number, мы обращаемся к полю number структурированного объекта ArAddr[0] – это поля никак не связаны между собой, потому что относятся к разным объектам (в первом хранится значение 34, во втором 75).

Структурированный объект может быть передан в функцию по значению в качестве параметра и возвращён функцией по значению с помощью оператора return. Пример:

address current = {"Сидоров ", 31, "Петровская ", "Таганрог", {‘R’,‘U’}, 3900};

<== предыдущая лекция | следующая лекция ==>
Концепція сталого розвитку продуктивних сил України | Операции, определенные по умолчанию над структурированными объектами
Поделиться с друзьями:


Дата добавления: 2014-01-11; Просмотров: 425; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.009 сек.