Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MEGAPACK_version_final.doc
Скачиваний:
6
Добавлен:
15.09.2019
Размер:
2.34 Mб
Скачать

57. Вказівники. Розподіл динамічної пам’яті.

Указатель – переменная, значением которой является адреса некоторого обїекта в памяти компьютера.

Переманняа, являющаяся указателем, обьявляется соответствующим образом. Обьявление указателя состоит из имени базового типа, символа * и имени перемнной. Общая форма обїявления указателя: тип *имя

Здесь тип – это бызовый тип указателя, им может быть любой правильный тип. Имя определяет имя переменной-указателя.

Базовый тип указателя определяет тип объекта, на который указатель будет ссылаться.

В программе на языке высокого уровня указатели могут быть типизированными и нетипизированными. При объявлении типизированного указателя определяется и тип объекта в памяти, адресуемого этим указателем. Так например, объявления в языке PASCAL:

Var ipt : ^integer; cpt : ^char;

или в языке C:

int *ipt; char *cpt;

означают, что переменная ipt представляет собой адрес области памяти, в которой хранится целое число, а cpt - адрес области памяти, в которой хранится символ. Хотя физическая структура адреса не зависит от типа и значения данных, хранящихся по этому адресу, компилятор считает указатели ipt и cpt имеющими разный тип, и в Pascal оператор: cpt := ipt;

будет расценен компилятором как ошибочный (компилятор C для аналогичного оператора присваивания ограничится предупреждением). Таким образом, когда речь идет об указателях типизированных, правильнее говорить не о едином типе данных "указатель", а о целом семействе типов: "указатель на целое", "указатель на символ" и т.д. Могут быть указатели и на более сложные, интегрированные структуры данных, и указатели на указатели.

Нетипизированный указатель - тип pointer в Pascal или void * в C - служит для представления адреса, по которому содержатся данные неизвестного типа. Работа с нетипизированными указателями существенно ограничена, они могут использоваться только для сохранения адреса, обращение по адресу, задаваемому нетипизированным указателем, невозможно.

Основными операциями, в которых участвуют указатели являются присваивание, получение адреса, выборка.

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

Операция получения адреса - одноместная, ее операнд может иметь любой тип, результатом является типизированный (в соответствии с типом операнда) указатель, содержащий адрес объекта-операнда.

Операция выборки - одноместная, ее операндом является типизированный (обязательно!) указатель, результат - данные, выбранные из памяти по адресу, заданному операндом. Тип результата определяется типом указателя-операнда.

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

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

Динамическое распределение не обеспечивается C переменными; не имеется никакого класса памяти "dynamic", и не может быть переменной C, чье значение сохранено в динамически размещенном месте. Единственный способ обратиться к динамически размещенному месту - через указатель. Т.к. это менее удобно, и фактический процесс динамического распределения требует большего количества компьютерного времени, программисты использует динамическое распределение только когда ни статическое ни автоматическое распределение применить невозможно.

Например, если Вы хотите зарезервировать динамически некоторое место, чтобы разместить struct foobar, Вы не можете объявлять переменную типа struct foobar, чье содержание - динамически размещенное место. Но Вы можете объявить переменную struct foobar * типа указатель и назначить ей адрес. Тогда Вы можете использовать операторы "*" и "->" для этой переменной- указателя, чтобы обратиться по адресу:

{

struct foobar *ptr= (struct foobar *) malloc (sizeof (struct foobar));

ptr->name = x;

ptr->next = current_foobar;

current_foobar = ptr;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]