Basic Pascal Tutorial/Chapter 5/Pointers/bg

From Free Pascal wiki
Revision as of 15:57, 3 January 2023 by Alpinistbg (talk | contribs) (Created page with "{{Basic Pascal Tutorial/Chapter 5/Pointers}} {{TYNavigator|Chapter 5/Records|Chapter 6/Final words}} == 5F - Указатели == ''(author: Tao Yue, state: unchanged)'' [...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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);

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

Trivial usage example: singly linked lists

What is a pointer good for? Why can't you just use an integer in the examples above instead of a pointer to an integer? Well, the above is clearly a contrived example. The real power of pointers is that, in conjunction with records, it makes dynamically-sized data structures possible. If you need to store many items of one data type in order, you can use an array. However, your array has a predefined size. If you don't have a large enough size, you may not be able to accomodate all the data. If you have a huge array, you take up a lot of memory when sometimes that memory is not being used.

A dynamic data structure, on the other hand, takes up only as much memory as is being used. What you do is to create a data type that points to a record. Then, the record has that pointer type as one of its fields. E. g. stacks and queues can all be implemented using this data structure:

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

Each element points to the next. The last record in the chain indicates that there is no next record by setting its next field to a value of nil.

 ◄   ▲   ►