Тема 6.2 Структуры, объединения, перечисления
Структуры
-
Объявление и инициализация структур
-
Синтаксис объявления структурного типа :
-
struct имя_структурного_типа
-
{ тип данных имя_поля;
-
тип данных имя_поля;
-
…
-
};
-
Пример:
-
struct Book
-
{ char author[40]; // автор, символьная строка
-
char title[80]; // название, символьная строка
-
int year; // год издания, целое число
-
int pages; // количество страниц, целое число
-
};
Структуры
-
Очень часто при обработке информации приходится работать с блоками данных разных типов. Например, информация о книге в каталоге библиотеки включает в себя автора (символьная строка), название книги (тоже строка), год издания (целое число), количество страниц (целое число) и т.п.
-
Для хранения этой информации в памяти не подходит обычный массив, так как в массиве все элементы должны быть одного типа. Конечно, можно использовать несколько массивов разных типов, но это не совсем удобно (желательно, чтобы все данные о книге находились в памяти в одном месте).
-
В современных языках программирования существует особый тип данных, который может включать в себя несколько элементов более простых (причем разных!) типов.
-
Структура – это тип данных, который может включать в себя несколько полей – элементов разных типов (в том числе и другие структуры).
-
Одно из применений структур – организация различных баз данных, списков и т.п.
-
Поскольку структура - это новый тип данных, его надо предварительно объявить в начала программы.
-
Для объявления структуры используется ключевое слова struct, за которым следуют идентификатор, являющийся именем типа структуры, и список полей ( элементов) структуры, заключенных в фигурные скобки. Каждый элемент объявляемой структуры, как и структура в целом, заканчивается точкой с запятой.
-
При объявлении структурного типа память не выделяется, реальных структур в памяти еще нет. Это объявление сообщает компилятору, что в программе могут быть определены переменные структурного типа.
-
Для выделения памяти необходимо объявить переменные структурного типа.
Структуры
-
Объявление и инициализация структур
-
Способы объявления переменных структурного типа :
-
Пример 1: struct Book
-
{ char author[40];
-
char title[80];
-
int year;
-
int pages;
-
};
-
//объявление и инициализация переменной структурного типа
-
Book b1 {"А. С. Пушкин","Полтава",1998 };
-
Пример 2: struct Book
-
{ char author[40];
-
char title[80];
-
int year;
-
int pages;
-
} b2; // объявление переменной
Структуры
-
Первый способ (Пример 1): Сначала объявляется структурный тип (Book), а потом переменная структурного типа (b1).
-
Второй способ (Пример 2):одновременно объявляется структурный тип (Book) и выделяется память под переменную структурного типа (b2).
Структуры
-
Работа с полями структуры
-
Обращение по имени: имя_переменной_структурного_типа . имя_поля
-
Book b;
-
strcpy ( b.author, " А.С. Пушкин " );
-
b.year = 1998;
-
Обращение по адресу: указатель_на_структурный_тип -> имя_поля
-
Book b;
-
Book *p; // указатель на структуру
-
p = &b; // записать адрес структуры в указатель
-
strcpy ( p->author, "А.С. Пушкин" );
-
p -> year = 1998;
-
// выражение p -> year эквивалентно (*p).year
Структуры
-
Для обращения ко всей структуре используется имя переменной структурного типа, а для обращения к отдельному полю имя этого поля ставится через точку. Элементы структуры вводятся последовательно по одному. Заполнять их можно в любом порядке. С полем структуры можно работать так же, как и с переменной соответствующего типа: числовые переменные могут участвовать в арифметических выражениях, со строками можно выполнять все стандартные операции.
-
Пусть известен адрес структуры в памяти. Как известно, адрес может быть записан в указатель – специальную переменную для хранения адреса. Для обращения к полю структуры по ее адресу используют специальный оператор ->.
Структуры
-
Ввод и вывод структур
-
Консольный ввод и вывод :
-
#include <iostream>
-
using namespace std;
-
struct Book
-
{ char author[40];
-
char title[80];
-
int year;
-
int pages;
-
};
-
int main(void)
-
{ Book b;
-
cout << "Autor: "; cin.getline(b.author,40);
-
cout << "Title: "; cin.getline(b.title,80);
-
cout << "Year: "; cin >> b.year;
-
cout << "Pages: "; cin >> b.pages;
-
cout << "\n";
-
cout << b.author << " "<< b.title << " ";
-
cout << b.year << " " << b.pages << "\n";
-
}
Структуры
-
При вводе с клавиатуры и выводе на экран с каждым полем структуры надо работать отдельно, как с обычной переменной. В приведенном примере данные вводятся в структуру b типа Book с клавиатуры и выводятся на экран.
Структуры
-
Структуры и бинарные файлы
-
#include <iostream>
-
#include <stdio.h>
-
using namespace std;
-
struct Book
-
{ char author[40];
-
char title[80];
-
int year;
-
int pages;
-
};
-
int main(void)
-
{ Book b; FILE *fp;
-
int n;
Структуры
-
// Запись структуры в бинарный файл
-
fp = fopen("books.dat", "wb");
-
cout << "Autor: "; cin.getline(b.author,40);
-
cout << "Title: "; cin.getline(b.title,80);
-
cout << "Year: "; cin >> b.year;
-
cout << "Pages: "; cin >> b.pages;
-
fwrite(&b, sizeof(Book), 1, fp);
-
fclose(fp);
-
cout << "File write!\n";
Структуры
// Чтение структуры из бинарного файла
cout << "File read!\n";
fp = fopen("books.dat", "rb");
n = fread (&b, sizeof(Book), 1, fp);
if (n == 0) cout << "Error read file!";
else
{ cout << b.author << " ";
cout << b.title << " ";
cout << b.year << " " << b.pages << "\n";
}
fclose(fp);
};
Структуры
-
Структуры очень удобно записывать в двоичные файлы, поскольку можно за 1 раз прочитать или записать сразу одну или даже несколько структур. Вспомним, что при чтении из двоичного файла функции fread надо передать адрес нужной области памяти (куда записать прочитанные данные), размер одного блока и количество таких блоков. Для того, чтобы не вычислять размер структуры вручную, применяют оператор sizeof.
-
Можно было также вместо sizeof(Book) написать sizeof(b), поскольку запись b – это как раз один экземпляр структуры Book. Функция fread возвращает число удачно прочитанных элементов (в нашем случае – структур). Поэтому если в примере переменная n равно нулю, чтение закончилось неудачно и надо вывести сообщение об ошибке.
-
Для записи структуры в двоичный файл используют функцию fwrite. Ее параметры – те же, что и у fread. Пример ниже показывает добавление структуры в двоичный файл books