
- •Лабораторная работа №1
- •1.1 Краткие теоретические сведения
- •1.1.1 Инициализации указателя:
- •1.1.2 Описание массива:
- •1.1.3 Правила работы с массивами:
- •1.2 Варианты заданий
- •1.3 Контрольные вопросы:
- •Лабораторная работа №2
- •2.1 Краткие теоретические сведения
- •2.2 Задание
- •2.3 Варианты заданий
- •2.4 Контрольные вопросы:
1.3 Контрольные вопросы:
По каким признакам классифицируются структуры данных?
Что означает понятие «тип данных»?
Какую информацию можно извлечь из типа данных?
К какой группе структур данных относятся статические массивы?
К какой группе структур данных относятся динамические массивы?
Что такое указатели?
Какие операции можно выполнять над указателями?
В чем заключается связь между указателями и массивами?
Какие операции обязательны при работе с динамическими массивами?
Свойства динамических массивов.
Можно ли изменить размер динамического массива при исполнении программы? Если да, то как это сделать?
Какое требование нужно соблюдать при присваивании адреса массива указателю?
Лабораторная работа №2
Тема: Массивы и структурированные типы данных
Цель: получение практических навыков объявления, инициализации, сортировки, поиска элемента в массивах структурированных типов данных
2.1 Краткие теоретические сведения
Правила работы со структурами:
Структуры применяются для логического объединения связанных между собой данных различных типов.
После описания структурного типа ставится точка с запятой.
Элементы структуры называются полями. Поля могут быть любого основного типа, массивом, указателем, объединением или структурой.
Для обращения к полю используется операция выбора: «точка» при обращении через имя структуры и «->» при обращении через указатель.
Структуры одного типа можно присваивать друг другу.
Ввод/вывод структур выполняется поэлементно.
Структуры, память под которые выделяет компилятор, можно инициализировать перечислением значений их элементов.
Пример 1: Написать программу, которая считывает массив структур типа Man из бинарного файла и упорядочивает его элементы по именам.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const int l_name=30;
struct Man {
char name[l_name+1];
int birth_year;
float pay;
};
int compare (const void *man1, const void *man2); // 1
int main(){
FILE *fbin;
if ((fbin=fopen(“dbase.bin”,”rb”))==NULL){
puts(“Ошибка открытия файла\n”);return 1;}
fseek(fbin,0,SEEK_END);
int n_record=ftell(fbin)/sizeof(Man);
Man *man=new Man[n_record]; //2
fseek(fbin,o,SEEK_SET); //3
fread(man,sizeof(Man),n_record,fbin); //4
fclose(fbin);
qsort(man,n_record,sizeof(Man),compare); //5
for(int i=0;i<n_record;i++)
printf(“%s %5i %10.2f\n”,man[i].name,man[i].birth_year, man[i].pay);
return 0;
}
int compare (const void *man1, const void *man2){
return strcmp(((Man *)man1)->name,((Man *)man2)->name);
}
Для сортировки мы в образовательных целях и для разнообразия использовали стандартную функцию qsort (оператор 5). Ее прототип находится в заголовочном файле <stdlib.h>. Функция может выполнять сортировку массивов любых размеров и типов. У неё четыре параметра:
указатель на начало области, в которой размещается упорядочиваемая информация;
количество сортируемых элементов;
размер каждого элемента в байтах:
имя функции, которая выполняет сравнение двух элементов.
Необходимо уяснить следующее: раз функция qsort универсальна, мы должны дать ей информацию, как сравнивать сортируемые элементы и какие выводы делать из сравнения. Значит, мы должны написать функцию, которая сравнивает два любых элемента, и передать ее в qsort. Имя функции может быть любым. Мы назвали её compare. Оператор 1 представляет собой заголовок (прототип) функции, он необходим компилятору для проверки правильности ее вызова.
Для правильной работы qsort требуется, чтобы наша функция имела два параметра - указатели на сравниваемые элементы. Они должны иметь тип void. Функция должна возвращать значение, меньшее нуля, если первый элемент меньше второго, равное нулю, если они равны, и большее нуля, если первый элемент больше. При этом массив будет упорядочен по возрастанию. Если мы хотим упорядочить массив по убыванию, нужно изменить возвращаемые значения так: если первый элемент меньше второго, возвращать значение, большее нуля, а если больше - меньшее.
Внутри функции надо привести указатели на void к типу указателя на структуру Man. Для этого мы использовали операцию приведения типа в стиле С. Чтобы описание структуры было известно в функции compare, мы перенесли описание структуры, а вместе с ней и описание необходимой ей константы l_name в глобальную область.
Для упорядочивания массива по другому полю надо изменить функцию сравнения. Вот, например, как она выглядит при сортировке по зарплате:
int compare(const void *man1,const void *man2){
return ((Man *)man1)->pay>((Man *)man2)->pay? -1:
((Man *)man1)->pay==((Man *)man2)->pay? 0: 1;
}