Адреса и указатели

Динамическая память

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

Существует другой способ выделения памяти под переменные. В языке С++ память под переменные можно выделять в процессе выполнения программы. Данный способ выделения памяти называют динамическим, переменные, под которые ОП выделялась динамически, – динамическими, а выделенная таким способом память – динамической памятью или кучей. Динамически распределяемая память (куча) – это свободная область ОП, которая не используется программой при ее загрузке в ОП, операционной системой и другими приложениями. Использование динамической памяти дает дополнительные, по сравнению со статической памятью, возможности: 1) при подключении динамической памяти можно увеличить объем обрабатываемых данных; 2) размер динамических данных можно изменять (или вообще динамические переменные удалить в случае их ненадобности).

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

Адресом величины называется номер первого байта участка ОП, в котором располагается сама величина. Размер этого участка однозначно определяется типом переменной.

Указателем называется переменная, которая содержит адрес другой переменной или указывает адресом на переменную некоторого типа. Тип указателя – беззнаковое целое. Если указатель не указывает ни на какую переменную, то говорят, что он содержит нулевой адрес, записываемый с помощью константы NULL.

Объявление указателей:

< тип_адресуемой_переменной > *< имя_указателя >;

Для того чтобы вывести значение указателя на экран монитора, в функции printf() нужно использовать формат вывода %u.

Замечания:

1) указатель всегда содержит адрес нулевого байта адресуемой переменной;

2) тип адресуемой переменной, записанной при объявлении указателя, показывает, сколько байт оперативной памяти (далее ОП) будет адресовать указатель, начиная с нулевого байта адресуемой переменной, например: для символьного типа данных – 1 байт, для целого – 4 байта.

Операции над указателями:

1. Унарные операции:

&<переменная> – операция получения адреса некоторой <переменной>;

*<переменная> – операция получения значения <переменной> по адресу в оперативной памяти (косвенная адресация):

int *p, t=4;

p=&t;

printf(“t=%i\n”,*p);

Данный пример можно отобразить в табличной форме.

Операция Переменная Значения переменных
Адрес переменной t = &p p
Значение переменной t = *p t

2. Операции над указателями:

Ø присваивание указателю нулевого адреса или адреса некоторой переменной;

Ø увеличение или уменьшение значения указателя;

Ø вычитание или сложение двух указателей (в этом случае указатели должны адресовать переменные одного и того же типа);

Ø вычитание или прибавление к указателю целого числа.
Значение самого указателя при выполнении операции будет изменяться по правилу: если к значению указателя прибавляется число k, то значение указателя увеличится на величину, равную k, умноженное на количество байт, занимаемые адресуемой переменной;

Ø сравнение значений двух указателей при помощи операции отношения.