Struct+List ++
.pdfСтруктуры объединяют данные разного типа в единое целое
Параметры книги:
•автор (строка)
•название (строка)
•год издания (целое число)
•количество страниц (целое число)
Структура – это тип данных, который может включать в себя несколько полей – элементов разных типов включая указатели и другие структуры, кроме себя.
// Память не выделяется! struct BOOK
{ char author[40]; // автор, символьная строка
char title[80]; |
// название, символьная строка |
int year; |
// год издания, целое число |
int pages; |
// количество страниц, целое число |
}; |
1 |
Как работать со структурами?
Объявление:
// здесь выделяется память!
BOOK ac = {"А.С. Пушкин", "Полтава", 1998, 223 };
Заполнение полей: |
|
|
|
|
|
! |
|
|
strcpy ( ac.author, "А.С. Пушкин" ); |
Для обращения |
|
|
strcpy ( ac.title, "Полтава" ); |
|
к полю структуры |
|
ac.year = 1998; |
|
используется |
|
ac.pages = 223; |
|
точка! |
|
|
|
|
Ввод полей с клавиатуры:
printf ( "Автор " ); gets ( ac.author );
printf ( "Название книги " ); gets ( ac.title );
printf ( "Год издания, кол-во страниц " );
scanf ( "%d %d", &ac.year, &ac.pages );
2
Копирование структур
Задача: скопировать структуру a в b.
просто: b = a;
Копирование «бит в бит»:
#include <mem.h>
memcpy ( &b, &a, sizeof(BOOK) );
По элементам:
BOOK a, b;
// здесь вводим a
strcpy ( b.author, a.author ); strcpy ( b.title, a.title ); b.year = a.year;
b.pages = a.pages; |
3 |
Массивы структур
Объявление: |
B[0] |
... |
B[9] |
|
BOOK B[10];
Обращение к полям:
for ( i = 0; i < 10; i ++ ) B[i].year = 2008;
Запись в двоичный файл:
author |
title |
year |
pages |
|
|
|
|
BOOK
write binary
FILE *f;
f = fopen("input.dat", "wb" );
сколько
блоков
адрес массива |
размер блока |
fwrite ( B, sizeof(BOOK), 10, f );
Чтение из двоичного файла:
f = fopen("input.dat", "rb" );
n = fread ( B, sizeof(BOOK), 10, f ); printf ( "Прочитано %d структур", n );
указатель на файл
fread возвращает число удачно прочитанных
блоков! 4
Пример программы
Задача: в файле books.dat записаны данные о книгах в виде массива структур типа BOOK (<= 1000). Вычислить количество книг 2010 года издания и исправить на 2012 год.
struct BOOK { … }; int main()
{ BOOK B[100]; int i, n, m; |
|
FILE *f; m=sizeof(BOOK); |
|
f = fopen ( "books.dat", “ab" ); |
// открытие файла |
n = fread ( B, m, 100, f ); |
// чтение из файла |
for ( i = 0; i < n; i ++ ) |
|
if(B[i].year == 2010) {count++; B[i].year = 2012; }
fwrite ( B, m, n, f ); fclose ( f );
return 0;
}
5
Выделение памяти под структуру
BOOK *b;
b = (BOOK *)malloc( sizeof(BOOK));
printf ( “Введи: Автор " );
gets ( b->author ); // (*b). author == b-> author
printf ( " Введи: Название книги " ); gets ( b->title );
printf ( " Введи: Количество страниц " ); scanf ( "%i", &b->pages );
printf ( “ Введи: год издания “); scanf ( "%d", &b->year );
6
Динамические массивы структур
Задача: выделить память под структуру во время выполнения программы. Неизвестно, сколько книг будет вводиться
BOOK *p[1000]; // массив указателей на структуры
BOOK B[1000]; // массив структур int n, m;
char s[128];
for ( i = 0; i < 1000; i++ ) { gets(s);
m=strlen(s); if(!m) break;
p[i] = (BOOK *)malloc(sizeof(BOOK)); B[i]=*p[i];
……………………………………………
7
}
Сортировка массива структур
Ключ (ключевое поле) – это поле, по которому сортируются структуры.
Проблема: как избежать копирования структур при сортировке?
Решение: использовать массив указателей, при сортировке переставлять указатели.
До |
p[0] |
p[1] |
p[2] |
p[3] |
p[4] |
|
|
|
|
|
|
|
|
сортировки: |
5 |
1 |
3 |
2 |
4 |
|
|
|
|
|
|
|
|
После |
p[4] |
p[0] |
p[2] |
p[1] |
p[3] |
|
|
|
|
|
|
|
|
сортировки: |
5 |
1 |
3 |
2 |
4 |
|
|
|
|
|
|
|
|
Вывод результата:
for ( i = 0; i < n; i ++ )
printf("%i %s", p[i]->year, p[i]->title);
8
Реализация в программе
//сортировка пузырьком по году издания const int n = 1000;
BOOK B[n], *p[n], *t; int i, j;
…// здесь заполняем структуры for ( i = 0; i < N; i++ )
p[i] = &B[i];
for ( i = 0; i < n-1; i++ ) for ( j = n-2; j >= i; j-- )
if ( p[j+1]->year < p[j]->year )
{ t = p[j]; p[j] = p[j+1]; p[j+1] = t; }
for ( i = 0; i < n; i ++ ) |
|
printf("%i %s", p[i]->year, p[i]->title); |
9 |
Структуры данных Связанные (связные) cписки
Linked List
Списки могут быть следующих видов:
линейные (linear list) и кольцевые (circular list)
однократно связанными (singly linked list) и дважды (doubly linked list) связанными линейные и нелинейные (ортогональные)
10