- •Часть 1
- •Общие сведения Сведения об эумк
- •Методические рекомендации по изучению дисциплины
- •Рабочая учебная программа
- •Часть 2 184
- •Пояснительная записка
- •Содержание дисциплины
- •Индивидуальные практические работы, их характеристика
- •Контрольные работы, их характеристика
- •Литература
- •Основная
- •Дополнительная
- •Перечень компьютерных программ, наглядных и других пособий, методических указаний и материалов и технических средств обучения
- •Учебно-методические пособия
- •Алфавит языка
- •Лексемы
- •Идентификаторы
- •Ключевые слова
- •Знаки операций
- •Константы
- •Комментарии
- •Тема 2. Типы данных Концепция типа данных.
- •Простые типы данных
- •Целый тип int
- •Символьный тип char
- •Типы с плавающей точкой: float, double, long double
- •Тема 3. Выражения
- •Переменные
- •Именованные константы
- •Операции
- •Операции присваивания
- •Инкремент и декремент
- •Унарный плюс и унарный минус (строка 2)
- •Явное преобразование типа
- •Операция определения размера sizeof
- •Деление и остаток от деления
- •Логические операции не, и, или (!, &&, ||)
- •Условная операция (?:)
- •Операция запятая (,)
- •Операции взятия адреса и разадресации
- •Тема 4. Операторы
- •Структура программы
- •Тема 5. Базовые конструкции структурного программирования
- •Операторы ветвления
- •1. Условный оператор if
- •2. Оператор switch
- •Операторы цикла
- •1. Цикл с предусловием while
- •2. Цикл с постусловием do-while
- •3. Цикл с параметром for
- •Тема 6. Массивы
- •Тема 7. Указатели и массивы
- •Тема 8. Строки символов
- •Тема 9. Структуры
- •Массивы структур
- •Битовые поля
- •Объединения
- •Перечисления
- •Тема 10. Функции
- •Глобальные, локальные и статические переменные
- •Параметры функции
- •Передача массивов в качестве параметров функции
- •Функция main, ее параметры
- •Функции стандартной библиотеки
- •Функции форматного вывода и ввода printf и scanf
- •Тема 11. Файлы
- •Тема 12. Работа с динамической памятью
- •Тема 13. Динамические структуры данных
- •Очереди
- •Линейные списки
- •Бинарные деревья
- •Практический раздел Общие указания Указания по выбору варианта
- •Порядок оформление итогового отчета
- •Индивидуальные практические работы Индивидуальная практическая работа 1 Методические указания
- •Варианты заданий.
- •Индивидуальная практическая работа 2 Методические указания
- •Варианты заданий
- •Контрольные работы Контрольная работа 1 Методические указания
- •Варианты заданий
- •Контрольная работа 2 Методические указания
- •Варианты заданий
Тема 12. Работа с динамической памятью
Свободная память, которой может распоряжаться программа а процессе своей работы, называется динамической памятью. В ней программа может выделять участки и получать к ним доступ через посредство указателей, а также освобождать те участки, которые становятся не нужны. Далее можно снова получать доступ к имеющейся свободной памяти, но уже для других целей, затем освобождать ненужные участки и так далее. Например, если мы обычным способом определим переменную и массив:
int k, mas[10];
то под переменную k и массив mas компилятор выделит память, которую уже нельзя будет освободить до самого конца работы программы. Здесь мы имеем дело со статической памятью.
k = 100; //заносим в k значение 100
for(int i=0; i<10; i++) //вводим в массив mas данные
mas[i] = i*k;
puts("Static memory:");
for(i=0; i<10; i++) //выводим данные из массива mas на экран
printf("%5d", mas[i]);
Однако память под переменную или массив можно выделить динамически, для чего нужно с помощью оператора new выделить участок свободной памяти и получить к нему доступ с помощью указателя. В дальнейшем этот участок можно освободить с помощью оператора delete, присоединяя его к области свободной памяти с целью возможного будущего использования для других целей. Тот же пример можно решить и так:
int *pk; //определяем указатель pk на целое число
pk = new int; //выделяем динамическую память под целое число и заносим в рk
//адрес ее начала
int *pmas; //определяем указатель pmas на целое число
pmas = new int[10]; //выделяем динамическую память под 10 целых чисел
//и заносим в рmas адрес ее начала
*pk = 100; //вводим в динамическую переменную значение 100
for(i=0; i<10; i++) //вводим в динамический массив данные
*(pmas+i) = i*(*pk);
puts("\n\nDynamic memory:");
for(i=0; i<10; i++) //выводим данные из динамического массива на экран
printf("%5d", *(pmas+i));
delete pk; //освобождаем динамическую память, занятую под переменную
delete []pmas; //освобождаем динамическую память, занятую под массив
Замечание 1. Инструкции определения указателя и выделения для него динамической памяти можно совместить. Тогда первые четыре строки, связанные с определением указателей и выделением динамической памяти, можно записать так:
int *pk = new int;
int *pmas = new int[10];
Замечание 2. В языке С имеется другая пара функций, связанных с распределением и освобождением динамической памяти: это функции malloc и free, которые описаны в заголовочном файле stdlib.h. Тот же пример с их использованием можно записать так:
int *pk;
pk = (int *) malloc(sizeof(int)); //выделяем динамическую память под //переменную целого типа
int *pmas;
pmas = (int *) malloc(10 * sizeof(int)); //выделяем динамическую память под массив
. . . //целого типа
. . .
. . .
free(pk); //освобождаем динамическую память, занятую под переменную
free(pmas); //освобождаем динамическую память, занятую под массив
Здесь (int *) - операция приведения к типу "указатель на целое", поскольку функция malloc возвращает указатель на void, который далее нужно преобразовать к нужному типу. Так как в качестве параметра в функцию malloc нужно передать число байт, которые будут выделены из свободной памяти под переменную или массив, то мы использовали функцию sizeof, которая возвращает длину в байтах, занимаемую переменной типа int. Как было сказано выше, первые четыре строки можно попарно совместить и записать так:
int *pk = (int *) malloc(sizeof(int));
int *pmas = (int *) malloc(10 * sizeof(int));