Перечислите основные особенности динамической памяти.
Память, принадлежащая программе, делится на:
Статическую (память, занимаемая глобальными переменными и константами)
Автоматическую (память, занимаемая локальными данными, т.е. стек программы)
Динамическую (память, выделяемая программе по специальному запросу)
В дополнение к статической и автоматической памяти, которые фиксированы после запуска программы, программа может получать нефиксированное количество динамической памяти. Ограничения на объём выделяемой динамической памяти связаны лишь с настройками операционной системы и объемом оперативной памяти компьютера. Основная проблема — явно выделенную динамическую память необходимо возвращать, иначе не хватит памяти другим программам.
Для явного выделения и освобождения динамической памяти используются процедуры:
New
Dispose
var
p: pinteger; //p никуда не указывает
begin
New(p); //в динамической памяти выделяется ячейка
//размером под один integer, и
//p начинает указывать на эту ячейку
p^ := 3;
Dispose(p); //возвращает динамическую память,
//контролируемую указателем p, назад ОС
end.
По окончании работы программы, вся затребованная программой динамическая память возвращается ОС. Но лучше освобождать динамическую память явно! Иначе в процессе работы программы она может занимать большие объёмы (ещё не освобождённой) памяти, что вредит общей производительности системы.
Что возвращает оператор new после выделения участка динамической памяти?
операция new. Это - универсальная операция, которая получает память у операционной системы и возвращает указатель на начало выделенного блока.
Каково назначение оператора delete?
возвращает системе память, на которую указывал указатель p
Какие операции можно производить над указателями.
Над указателями можно выполнять унарные операции: инкремент и декремент. При выполнении операций ++ и -- значение указателя увеличивается или уменьшается на длину типа, на который ссылается используемый указатель.
Пример:
int *ptr, a[10]; ptr=&a[5]; ptr++; /* равно адресу элемента a[6] */ ptr--; /* равно адресу элемента a[5] */
В бинарных операциях сложения и вычитания могут участвовать указатель и величина типа int. При этом результатом операции будет указатель на исходный тип, а его значение будет на указанное число элементов больше или меньше исходного.
Пример:
int *ptr1, *ptr2, a[10]; int i=2; ptr1=a+(i+4); /* равно адресу элемента a[6] */ ptr2=ptr1-i; /* равно адресу элемента a[4] */
В операции вычитания могут участвовать два указателя на один и тот же тип. Результат такой операции имеет тип int и равен числу элементов исходного типа между уменьшаемым и вычитаемым, причем если первый адрес младше, то результат имеет отрицательное значение.
Пример:
int *ptr1, *ptr2, a[10]; int i; ptr1=a+4; ptr2=a+9; i=ptr1-ptr2; /* равно 5 */ i=ptr2-ptr1; /* равно -5 */
Значения двух указателей на одинаковые типы можно сравнивать в операциях ==, !=, <, <=",">, >= при этом значения указателей рассматриваются просто как целые числа, а результат сравнения равен 0 (ложь) или 1 (истина).
Пример:
int *ptr1, *ptr2, a[10]; ptr1=a+5; ptr2=a+7; if (prt1>ptr2) a[3]=4;
В данном примере значение ptr1 меньше значения ptr2 и поэтому оператор a[3]=4 не будет выполнен.
Перечислите основные операции с динамическими структурами данных.
В чем особенности однонаправленных и двунаправленных линейных списков?
Как осуществляется выборка элементов данных в стеке?
Программа может поместить информацию в стек (команда PUSH) или извлечь ее из стека (команда POP). Данные в стеке упорядочиваются специальным образом. Извлекаемый из стека элемент данных - это всегда тот элемент, который был записан туда последним. Такая организация хранения данных сокращенно обозначается LIFO (Last In, First Out - последний поступивший удаляется первым). Если мы поместим в стек два элемента: сначала A, а затем B, то при первом обращении к стеку извлекается элемент B, а при следующем - A. Информация выбирается из стека в обратном по отношению к записи порядке.
Опишите организацию движения данных в очереди.
Очередь – это линейная структура данных, в которую элементы добавляются с одного конца (конец очереди), а удаляются – с другого (начало очереди). Очередь работает по принципу “элемент, помещенный в очередь первым, извлечен будет тоже первым”. Иногда этот принцип обозначается сокращением FIFO (First In – First Out, т.е. первым зашел – первым вышел).
Нарисуйте структуру односвязного кольцевого списка.
Нарисуйте структуру двухсвязного кольцевого списка.
Как описать файловую переменную для ввода данных оператором fscanf
f=fopen(namematrix,"r");
Как описать файловую переменную и открыть файл для записи в данных оператором fprintf
Для записи данных в файл нужно выполнить
1. Описать указатель на файл FILE *filename;
2. Открыть файл (функция fopen)
Описание функции
FILE *fopen(const *filename, const char *mode)
filename – строка, в которой хранится полное имя открываемого файла.
mode – строка, которая определяет режим работы с файлом; возможны
следующие значения:
· «r» – открываем текстовый файл в режиме чтения;
· «w» – создаем текстовый файл;
· «a» – создаем или открываем текстовый файл для дозаписи в конец
файла;
· «r+» – открываем текстовый файл в режиме чтения и записи;
· «w+» – открываем текстовый файл для исправления, старое
содержимое выбрасывается;
· «a+» текстовый файл открывается или создается для исправления
существующей информации и добавления новой в конец файла;
Функция возвращает указатель на файловую переменную или NULL при
неудачном открытии файла.
3. Записать данных в файл (функция fprintf )
Функция fprintf аналогична функции printf, единственным отличием является
первый параметр – указатель на файл. С помощью этой функции вывод
осуществляется не на экран, а в файл.
4. Закрыть файл (функция fclose )
int fclose(FILE *filename);
Как очистить станртный поток ввода stdin
fflush(stdin)
С помощью каких операторов осуществляется ввод данных из файла?
Fscanf()
С помощью каких операторов осуществляется вывод данных в файл?
Fprintf()