Basic Pascal Tutorial/Chapter 5/Pointers/bg

From Free Pascal wiki
Jump to navigationJump to search

български (bg) English (en) français (fr) 日本語 (ja) 中文(中国大陆)‎ (zh_CN)

 ◄   ▲   ► 

5F - Указатели

(author: Tao Yue, state: unchanged)

Указателят е тип данни, който съдържа адрес в паметта. Указателят може да се разглежда като препратка към този адрес, докато променливата е просто друго име за този адрес. Ако променливата съдържа нечий телефонен номер, то тогава указателят е страницата и номерът на реда, където е изписан номера в телефонния указател. За да получите достъп до данните, съхранени на този адрес в паметта, трябва да 'последвате' стойността на указателя.

Резервиране на памет

За да декларирате указател, трябва да укажете към какво ще сочи той. Типът данни към който ще сочи се предхожда от стрелка (^). Например, ако декларирате указател към цяло число, ще трябва да използвате следния код:

type
  PointerType = ^integer;

След това можете да декларирате променливи от типа PointerType.

Преди да използвате указател, трябва да запазите място в паметта за променливата към която той ще сочи. Това се прави с:

New(PointerVariable);

За да достъпите данните към които сочи указателя, трябва да добавите стрелка след името му. Например, ако PointerVariable е декларирана като PointerType (по-горе), можете да присвоите стойност на мястото в паметта, като използвате:

PointerVariable^ := 5;

След като приключите с указателя, трябва да освободите пространството в паметта. В противен случай, всеки път, когато програмата се стартира, тя ще запазва все повече и повече памет, докато накрая компютърът ви няма повече такава. За да освободите заетата памет, трябва да използвате командата Dispose:

Dispose(PointerVariable);

На един указател може да се присвои стойността на друг указател. Имайте предвид обаче, че тъй като се копира само адресът, а не стойността, след като промените данните, намиращи се в един указател, другият указател също сочи към променените данни. Освен това, ако освободите заетата памет за указател, копираният указател вече сочи към безсмислени данни.

Пример за употреба: единично свързани списъци

За какво е добре да се използват указателите? Не може ли просто в примерите по-горе да се използват целочислени променливи вместо указателите към тях? Очевидно горните примери са измислени само с демонстрационна цел. Истинската сила на указателите е, че когато се комбинират със записи, тогава е възможно да се създават динамични структури от данни. Когато има нужда да се помнят много данни от един тип в някакъв порядък, тогава може да се използва масив. Вашият масив обаче има предварително зададен размер. Ако той не е достатъчно голям, може да не успеете да поберете всички данни или обратно - ако имате огромен масив заемате много памет която не се използва.

Динамичната структура на данни, от друга страна, заема само толкова памет, колкото е необходимо. Това, което трябва да направите, е да създадете тип данни, който сочи към запис. След това записът има този тип указател като едно от своите полета. напр. всички стекове и опашки могат да бъдат реализирани с помощта на следната структура от данни:

type
	PointerType = ^RecordType;
	RecordType = record
		data : integer;
		next : PointerType;
	end;

Всеки запис сочи към следващия с полето си next. Последният запис във веригата има в полето next специалната стойност nil.

 ◄   ▲   ►