Лекции Булатицкий Дмитрий Иванович (во многом по материалам Прасолова А. Н.)
Скачать 319.62 Kb.
|
Простейшая анимацияДанная лекция проходит в режиме мастер-класса, внимание студентов следует обратить на следующие приёмы: Смена кадров; Формирование и параметризация «спрайтов»; Двойная буферизация; Интерактивная анимация одного объектаДанная лекция проходит в режиме мастер-класса, внимание студентов следует обратить на следующие приёмы: Обработка нажатия клавиш без остановки основного цикла анимации; Обработка событий мыши; Изменение параметров анимации под управлением пользователя. Интерактив при нескольких движущихся объектахДанная лекция проходит в режиме мастер-класса, внимание студентов следует обратить на следующие приёмы: Организация движения нескольких объектов; Управление одним из движущихся объектов; Многопользовательское управление. Работа с динамической памятьюСтандартные функции управления динамической памятьюДанные, которые создаются, инициализируются и уничтожаются по требованию программиста называются динамическими. Для управления такими данными используются специальные стандартные функции, прототипы которых описаны в заголовочном файле Для запроса динамической памяти служит функция malloc(), которая имеет следующий прототип: void * malloc(size_t size); Функция malloc() выделяет область динамической памяти, размером size байт, и возвращает адрес этой области памяти. Параметр size, имеет тип size_t, который описан в файле В том случае, когда функция malloc() не может удовлетворить запрос на память, она возвращает значение NULL, то есть значение не существующего указателя. Константа NULL описана в заголовочном файле Поскольку функция malloc() возвращает значение на произвольный тип данных, то возвращаемое значение должно быть явно преобразовано к нужному типу данных. После того, как выполнена вся работа с выделенной областью памяти, ее следует освободить с помощью функции free(), имеющей следующий прототип: void free(void *block); где block - указатель на область памяти, значение которого ранее было возвращено какой-либо функцией выделения памяти. Если при вызове функции free() значение указателя block не соответствует адресу, возвращенному функцией выделения памяти, то результат выполнения функции free() непредсказуем, а область динамической памяти может быть вообще разрушена. Не допускается также освобождать уже освобожденный блок памяти. Значение параметра block равное NULL не вызывает никаких действий со стороны функции free(); Рассмотрим типичную последовательность действий при работе с динамической памятью: double *A; int n; ... n = 200; ... A = (double *) malloc( n * sizeof(double) ); ... /* Работа с массивом A */ ... free(A); В рассмотренном фрагменте программы выделяется память для хранения n элементов типа double. В целях совместимости никогда не следует явно задавать размер элемента данных. Нужно пользоваться операцией sizeof(). Возвращаемое функцией malloc() значение преобразуется к типу указателя на double. Как видно из примера, функции работы с динамической памятью позволяют использовать массивы с границами, задаваемыми переменными, а не константами. В некоторых случаях бывает полезной функция calloc(), которая не только выделяет память, но и заполняет область выделенной памяти нулевыми значениями. Она имеет следующий прототип: void * calloc(size_t nitems, size_t size); Функция выделяет непрерывный блок памяти для nitems элементов данных размером size байт каждый и заполняет этот блок нулевыми значениями. В остальном работа ее аналогична работе функции malloc(). Функция realloc() служит для изменения размера ранее выделенного блока памяти: void *realloc(void *block, size_t size); Здесь block - адрес ранее выделенного блока памяти, size - новый размер блока в байтах. Функция возвращает значение нового указателя на блок памяти, которое может и не совпадать со старым. Функция гарантирует сохранность данных в блоке, разумеется, сохранность не более size байт. В остальном работа функции совпадает с работой ранее рассмотренных функций выделения памяти. Все рассмотренные функции могут выделять память размером не более одного сегмента, то есть не более 64K в 16-ти разрядных моделях и не более 4G в 32-х разрядных моделях памяти. При работе с динамической памятью следует иметь в виду, что в каждом выделенном блоке несколько байт отводится на служебную информацию. Так в 16-ти разрядной Large модели память выделяется блоками по размеру кратными 16 байтам, и в каждом блоке 4 байта служебные. К сожалению, стандартные средства работы с динамической памятью не предусматривают "сборку мусора", то есть автоматическое перемещение выделенных блоков в динамической памяти так, чтобы между ними не было неиспользуемых промежутков. Поэтому от программиста требуется повышенное внимание к стратегии выделения и освобождения динамической памяти в своих программах. Иначе может получиться так, что требуемый блок памяти невозможно выделить, хотя суммарный объем неиспользуемой памяти допускает это. Функция coreleft() возвращает значение оставшейся в динамической области памяти в байтах. Функция может иметь следующие прототипы в зависимости от моделей памяти: unsigned coreleft(void); /* Маленьких модели */ unsigned long coreleft(void); /* Большие модели */ При использовании этих функций следует иметь в виду, что они возвращают не общее количество свободной динамической памяти и не размер наибольшего свободного блока, а размер блока памяти, который остался между наивысшем по адресу выделенным блоком и концом динамической памяти. |