Попробуйте часть кода до слова main заменить на #include "stdafx.h" //1 #include <iostream> //2 using namespace std; //3 |
Пользовательские типы данных
К пользовательским типам данных относятся нестандартные данные, о структуре которых система не имеет представления, и операции над которыми стандартом языка C не определены. Структура таких данных становится известной компилятору только по описанию, содержащемуся в тексте исходной программы. К пользовательским данным такого типа относятся массивы (о них речь шла в предыдущем разделе), структуры (в других алгоритмических языках они известны под термином записи ), перечисления (в некоторых книгах по языкам C, C++ их относят к целочисленным данным) и объединения.
9.1. Структуры
Первоначальным образом для данных типа структур явились строки таблиц, с которыми знаком любой человек. Характерным для таблиц любого содержания является наличие столбцов, в каждом из которых хранятся однотипные данные. Однако в соседних столбцах типы данных могут отличаться. Если специфической особенностью массивов является использование одного и того же типа для всех элементов массива, то строки таблиц можно представлять как последовательность полей данных разного типа. Для каждого поля строки таблицы известно наименование соответствующего столбца таблицы и тип размещаемого в этом поле значения. Например, поле "Фамилия" заполняется текстовой информацией, поле "Год рождения" хранит целочисленные данные, на поле "Пол" достаточно записывать единственный символ 'М' или 'Ж' и т.д.
9.1.1. Объявление и инициализация структур
То, что принято называть "шапкой" таблицы в языках программирования носит название шаблона структуры. Например, шаблон структуры, описывающей данные о книге, может быть устроен следующим образом:
struct book { char title[40]; //наименование char authors[30]; //авторы char publishing_house[15]; //издательство int year; //год издания int pages; //количество страниц float price; //цена }
Идентификатор book выполняет функцию имени шаблона или типа структуры. В дальнейшем им можно пользоваться для объявления конкретных переменных – структур типа book:
struct book b1,b2,b3; //три переменных типа book
В языке C++ служебное слово struct можно опускать:
book b1,b2,b3;
Обратите внимание на то, что строковые поля в структурах имеют фиксированные размеры. Это существенно упрощает обработку данных, т.к. работа с полями переменной длины могла бы привести к очень медленно работающим программам.
Вообще говоря, объявление шаблона структуры и переменных, связанных с этой структурой, можно совместить:
struct book { char title[40]; char authors[30]; char publishing_house[15]; int year; int pages; float price; } b1,b2,b3;
Более того, в объявлении шаблона структуры можно опустить имя шаблона:
struct { char title[40]; char authors[30]; char publishing_house[15]; int year; int pages; float price; } b1,b2,b3;
Однако если данная структура должна выступить в качестве параметра какой-либо функции, то и в заголовке этой функции и в ее прототипе без имени шаблона не обойтись.
Для доступа к соответствующим полям структур используются составные имена, образованные из имени структуры и имени поля:
strcpy(b1.title,"C++:Экспресс курс"); strcpy(b1.authors,"В.Лаптев"); cout << b1.title; b1.year=2004;
Если мы имеем дело с указателем, который настроен на адрес структуры, то составные имена записываются с использованием двух символов "->":
struct book *p=&b1; //указатель на структуру strcpy(p->title,"C++:Экспресс курс"); strcpy(p->authors,"В.Лаптев"); cout << p->title; p->year=2004;
Структуры могут объединяться в массивы:
struct book c[20]; //массив структур
И тогда для доступа к полям соответствующего элемента используются индексированные составные имена:
strcpy(с[2].title,"Язык C++ ") strcpy(c[2].authors,"В.В.Подбельский"); cout << c[2].title; c[2].year=1996; struct book *pс=с; strcpy(pс[2]->title,"C++:Экспресс курс"); strcpy(pс[2]->authors,"В.Лаптев"); cout << pс[2]->title; pс[2]->year=2004;
При объявлении переменных типа структура их поля могут быть проинициализированы довольно естественным способом:
struct book a={"Programming Languages", "Jean E.Sammet", "Prentice-Hall", 1969,785,49.99};
Для структур, объявленных с использованием одного и того же шаблона, допустима операция присваивания:
b1=a; //все поля структуры a копируются в структуру b1
К сожалению, одноименные поля строкового типа у структур так копировать нельзя – необходимо прибегать к услугам функций типа strcpy:
strcpy(b1.authors,a.authors); //копируем поле "авторы"
Над содержимым числовых полей структур можно выполнять все операции, доступные для соответствующего типа данных.
Некоторые числовые поля структур могут быть объявлены как битовые шкалы с указанным количеством двоичных разрядов. С одной стороны, это предоставляет возможность компоновать в рамках машинных слов некоторые группы данных и располагать их более компактно в оперативной памяти. С другой стороны, такая возможность избавляет программиста от забот по выделению и вклеиванию соответствующих групп двоичных разрядов. Однако на расположение битовых полей в структурах оказывает дополнительное влияние установка компилятора – признак выравнивания данных на границу байта, слова, двойного слова. Длины битовых шкал при объявлении структур задаются следующим образом:
struct qq{ int a:10; int b:14; } xx, *px; xx.a=127; px=&xx; px->b=9;
В зависимости от признака выравнивания границ данных эти значения могут быть расположены в оперативной памяти по-разному:
С целью принудительного расположения битовых полей в таких структурах допускается вставка безымянных полей:
struct { int a:10; int :6; int b:14; } yy;