Статистические и динамические объекты. Динамический захват памяти. Локальный и глобальный heap.

Лист 32 +

Статическими объектами называются объекты, созданные компилятором.

Динамические объекты:

1.вводим некий указатель;

2. привязываем к указателю какой-то блок памяти.

Модель памяти предопределяется соотношением длин указателей, длинами адресов функций с количеством данных и количеством сигментов программы.

Создание динамических объектов:

1.объявить указатель char *ps;

2.выполнить обращение к функции void *malloc(size_t n);

<alloc.h>

size_t – аналог типа int

3.принятие адреса

ps=(char *) malloc(100);

4.использование этого блока

5.освобождение памяти

free(ps);

Захват памяти выполняется параграфами (один параграф 16 байт). Первые 4 параграфа используются ОС под свои нужды, в первые 2 байта заносится длина захваченной памяти, возвращается длина смещенная на 4 байта. Если указатель получен с помощью malloc никогда нельзя его передвигать.

Void *calloc(int nItem, int sItem);

Выделить массив в n элементов, n – вводится с клавиатуры.

Int *a, n, k;

(n);

a=(int *) calloc(n, sizeof(*a))

for (k=0, k<n, k++)

a[k]=2*k;

Этими захватами для младших моделей памяти имеем доступ для near памяти, для старших моделей памяти malloc и calloc захватывают из far типа.

Char far *pfs;

Voidfar farmalloc (int n );

Void far* farcalloc (int nItem, int sItem)

Far free (voidfar)

Потоковый и префиксный доступ к файлам.

Существует два подхода к файлам: префиксный и потоковый.

· потоковый

Осуществляется на всех платформах, работа с областью памяти через буфер.

File *fp=fopen(path; access)- открытие файла

path- путь относительно текущей директории. Если возвращается нулевой указатель, то доступ к файлу невозможен.

c:\\abc

access- уровень доступа

“w”- на запись и чтение в произвольном режиме(текстовом, бинарном). Если файл с таким именем отсутствует, то он будет создан.

“r”- на чтение

“a”- на запись, если нет, то автоматически будет создан, если существует, то автоматически прокручивается на конец для дозаписи.

“wt”- текстовый файл

“wb”- в бинарном виде

char* fgets (char buf, int n, FILE* fp)- считывает информации в текстовом файле, информация заносится в буфер, считывается не более n байт из FILE.

int fputs(const char* buf, FILE* fp)- запись строки в FILE, если возвращается нулевое значение-ошибка.

fclouse(fp)- закрытие, после этого fp- недействителен.

· префиксный

Работа с информацией на уровне ОС.

Не меняется кардинально подход, дается более широкая возможность для маневрирования.

int hf=open (path, <bit flags>);

bit flags- набор мнемонических констант, объединяющихся битовым или.

O_BINARY-доступ в бинарном варианте

{O_TEXT}- текстовый режим

O_RDWR- уровень доступа к чтению и записи

{O_READONLY}

{O_WRITEONLY}

O_CREATE- файл если не существует, будет создан. Если бит не установлен и файла нет, то будет выдана ошибка.

O_TRUNC- открываемый файл будет обнулен.

int hf=open (path, O_BINARY| O_RDWR| O_TRUNC)- если значение -1- открытие файла с данным уровнем доступа невозможно.

close(hf)

int read (hf, void* buf, unsigned n);

2 параметр- адрес буфера

длина при чтении 0-64кбт.(-1)

возвращаемое значение- реальное количество прочитанных байт.

int write (hf, const void* buf, unsigned n)- запись n байт с адреса, на который указывает буфер. При записи n и то, что возвращается должно совпадать.

Также возможны операции по возвращению длины открытого файла, установления размера открытого файла, возможно переставление указателя файла нужную позицию.

Основные понятия текстового и графического режимов.

Рабочий режим экрана определяется, когда ваша программа вы-

зывает одну из функций определения режима (textmode, initgraph

или setgraphmode).

В текстовом режиме разметка экрана – кол. строк*кол. Символов в строке.

Textmode(int):

LASTMODE -1 Предыдущий т. режим

BW40 0 Черно-белый, 40 столбцов

C40 1 16 цветов, 40 столбцов

BW80 2 Черно-белый, 80 столбцов

C80 3 16 цветов, 80 столбцов

MONO 7 Монохромный, 80 столбцов

C4350 64 EGA, 80x43; VGA, 80x50 строк

В графическом режиме X*Y пикселов и цвет.

int driver, mode;

driver = VGA;

mode = VGAHI;

initgraph(&driver, &mode, "c:\\borland\\bgi");

if(graphresult() < 0) //Ошибка

x_size = getmaxx();

y_size = getmaxy();

closegraph();

closegraph - Закрывает графическую систему.

detectgraph - Проверяет аппаратное обеспечение и определяет, какие графические драйверы использовать;

graphdefaults - Сбрасывает все переменные графической системы в значения по умолчанию.

_graphfreemem - Отменяет выделенную графикепамять. Используется для определения собственной подпрограммы.

_graphgetmem - Распределяет память графике; используется для определения собственной подпрограммы.

getgraphmode - Возвращает текущий графический режим.

getmoderange - Возвращает минимальный и максимальный допустимые режимы для заданного драйвера.

initgraph - Инициализирует графическую систему и переводит аппаратное обеспечение в графический режим.

installuserdriver - Устанавливает дополнительный драйвер устройства в таблице драйверов устройста BGI.

installuserfont - Загружает поставляемый файл векторного (штрихового) шрифта в таблицу символьных файлов BGI.

registerbgldriver - Регистрирует внешний или загруженный пользователем файл драйвера для включения во время компоновки.

restorecrtmode - Восстанавливает первоначальный (существовавший до Initgraph) режим экрана. setgraphbufsize - Задает размер внутреннего графического буфера.

setgraphmode - Выбирает заданный графический режим, очищает зкран и восстанавливает все умолчания.

19. Использоване модификаторов near, far, huge. Приведите примеры.(АЯиП)

Ближние указатели (near) 16-битовый (near) указатель для вычисления полного адреса связывается с одним из сегментных регистров; например, указатель функции складывает свое 16-битовое значение со сдвинутым влево содержимым регистра кодового сегмента (CS). Аналогичным образом, ближний указатель данных содержит смещение в сегменте данных, адресуемом регистром сегмента данных (DS). С ближними указателями легко манипулировать, поскольку все арифметические операции с ним (например, сложение) можно выполнять безотносительно к сегменту.

Дальние указатели (far)Дальний (32-битовый) указатель содержит не только смещение относительно регистра, но также и (в остальных 16 битах) адрес сегмента, который затем должен быть сдвинут влево и сложен со значением смещения. Использование дальних указателей позволяет иметь в программе несколько кодовых сегментов; это, в свою очередь, позволяет программе превышать 64К. Можно также адресовать более 64К данных. При использовании дальних указателей для адресации данных следует учитывать некоторые потенциальные проблемы, которые могут возникать при манипулировании такими указателями. Может существовать

множество пар типа сегмент: смещение, адресующих одну и ту же точку памяти. Например, если бы были три переменных типа дальнего указателя - a, b и c, содержащих соответственно три указанных значения, то следующие выражения все давали бы значение "ложь":

if (a == b) . . .

if (b == c) . . .

if (a == c) . . .

Аналогичная проблема возникает, когда требуется сравнивать дальние указатели при помощи операций >, >=, < и <=. В этих случаях в сравнении участвует только смещение; при указанных значениях a, b и c следующие выражения дадут значения "истина":

if (a > b) . . .

if (b > c) . . .

if (a > c) . . .

Операции равенства (==) и неравенства (!=) используют 32-битовые значения как unsigned long (а не в виде полного адреса памяти). Операции сравнения (<=, >=, < и >) используют только смещение. Операции == и != требуют все 32 бита, что позволяет компьютеру выполнять сравнение с пустым (NULL) указателем (0000:0000). Если для проверки равенства использовалось только значение смещения, то любой указатель со смещением 0000 будет равен пустому указателю, что явно не совпадает с тем, что вы хотели получить.

Указатели huge также имеют размер 32 бита. как и указатели far, они содержат одновременно адрес сегмента и смещение. Однако, в отличие от дальних указателей, они нормализованы, что позволяет избежать проблем, связанных с дальними указателями. Нормализованный указатель - 32-битовый указатель, который содержит в своем адресе сегмента максимально возможное значение. Поскольку сегмент может начинаться через каждые 16 байт (10 при основании 16), это означает, что величина смещения будет равна числу от 0 до 15 (от 0 до F с основанием 16). Для нормализации указателя он преобразуется к 20-битовому адресу, после чего правые 4 бита берутся в качестве смещения, а левые 16 битов - как адрес сегмента. Существует три причины, заставляющие всегда хранить указатель huge в нормализованном виде:

1. Поскольку в таком случае любому заданному адресу памяти соответствует только один возможный адрес в виде сегмент: смещение типа huge. Это означает, что для указателей huge операции == и != всегда будут возвращать правильное значение.

2. Кроме того, операции >, >=, < и <= работают с полным 32-битовым значением указателя huge. Нормализация гарантирует в данном случае корректность результата.

3. И наконец, вследствие нормализации смещение в указателе huge выполняет автоматический переход через 16 но в отличие от дальних указателей, переход затрагивает и сегмент. Эта особенность указателей huge позволяет манипулировать со структурами данных с размером более 64К.

Гарантируется, например, что если имеется массив структур типа huge, превышающий 64К, индексация этого массива и выбор поля структуры всегда будут выполняться правильно, независимо от размера структуры. Использование указателей huge имеет свою цену: увеличение времени обработки. Арифметические операции с указателями huge выполняются при помощи обращений к специальным подпрограммам. Вследствие этого арифметические вычисления занимают существенно больше времени по сравнению с вычислениями для указателей far или near.

20. Сравнительная характеристика языков С и С++(без классов): ссылки, модификатор const, параметры по умолчанию. (АЯиП)

Язык Си++ вводит новые объекты:

1.Типированные константы - переменные только для чтения, которые обязательно должны получить значение в месте объявления: const unsigned u=3456;

и могут быть только статическими, доступными только в пределах своего файла. Чтобы сделать их доступными из других единиц компиляции, придется объявлять их с ключевым словом extern extern const unsigned u=3456;

Чтобы использовать в другом файле, нужно тоже использовать extern - модификатор и не присваивать значение: extern const unsigned u;

2.Ссылка <тип> & <имя переменной>=<перемен>; Ссылка второе имя переменной для ссылки обязательна инициализация. Они тоже содержат адрес объекта, но при обращении по ссылке не надо применять операцию разадресации, как это необходимо при доступе по указателям. Ссылаться можно только на ранее "прописанный" в памяти объект. Ссылки вводят третий механизм передачи формальных параметров. Так же как и по адресу копирует адрес объекта. int y=16; int& x=y; Нельзя указатель создать на ссылку. Можно использовать независимую ссылку на константу.

3.Управление памятьюК таким функциям, как malloc() и free(), в С++ добавлены 3 встроенных в язык оператора new, delete, delete[]. Оператор new используется для создания объекта в куче: int nf=18; float * fp= new float[nf];

Оператор new позволяет попутно заполнить выделяемую память заданным значением: float * fp= new float[nf] (0); (массив заполняется нулями). new - в отличие от malloc, вернет ненулевой указатель, если по ошибке запросили 0 байтов памяти и запись в эту память имеет непредсказуемые последствия. Освобождение памяти осуществ. операторы delete или delete[] (для массивов).

4.Перегрузка функций - возможность использовать в программе функции с одинаковыми именами, если они имеют отличающиеся списки аргументов. С этой возможностью связано также требование предварительного объявления прототипа функции до ее вызова на выполнение - это объявление используется компилятором для определения правильности передачи аргументов при вызове, особенно для функций с одинаковыми именами.

Появление параметров по умолчанию в функциях которые автоматически будут использованы в том случае, если при вызове функции соответствующий аргумент не будет задан. Перегруженные функции, т.е. функции с одним именем но разными фармальными параметрами

1. Строгий контроль соответствия типов

2. Все функции должны иметь прототипы и все функции должны быть известны компилятору

Наши рекомендации