Оператор присвоєння
Як змінна може бути проста змінна, розіменований покажчик, змінна з індексами або компонент змінної типу запис. Символ: = називається піктограмою присвоєння. Вираз має бути сумісним з присвоєння зі змінною.
Оператор присвоєння замінює поточне значення змінної значенням виразу.
i := i + 1; // збільшує значення змінної i на 1
У PascalABC.NET визначено також оператори присвоювання зі значками +=, -=, *=, /=. Для числових типів дія даних операторів описана тут. Крім того, використання операторів += та *= для рядків описано тут і операторів += , -= та *= для множин - тут. Їхня дія для процедурних змінних описана тут.
Оператори += , -= , *= , /= мають такий зміст: a #= b означає a := a # b , де # - знак операції + , - , * , / .
a + = 3; // збільшити a на 3
b * = 2; // збільшити b у 2 рази
Опертор /= не застосовується, якщо вираз ліворуч - ціле.
Оператори +=, -=, *=, /= можуть також використовуватися з властивостями класів відповідних типів у лівій частині.
Ipsum sed dolor
Interdum aenean
Aenean ornare velit lacus, ac varius enim lorem ullamcorper dolore. Proin aliquam facilisis ante interdum. Sed nulla amet lorem feugiat tempus aliquam.
Nulla amet dolore
Aenean ornare velit lacus, ac varius enim lorem ullamcorper dolore. Proin aliquam facilisis ante interdum. Sed nulla amet lorem feugiat tempus aliquam.
Tempus ullamcorper
Aenean ornare velit lacus, ac varius enim lorem ullamcorper dolore. Proin aliquam facilisis ante interdum. Sed nulla amet lorem feugiat tempus aliquam.
Sed etiam facilis
Aenean ornare velit lacus, ac varius enim lorem ullamcorper dolore.Proin aliquam facilisis ante interdum.
Feugiat lorem aenean
Aenean ornare velit lacus, ac varius enim lorem ullamcorper dolore.
Amet varius aliquam
Aenean ornare velit lacus, ac varius enim lorem ullamcorper dolore.
Ante interdum
Aenean ornare velit lacus, ac varius enim lorem ullamcorper dolore aliquam.
Aenean ornare velit lacus, ac varius enim lorem ullamcorper dolore aliquam.
Aenean ornare velit lacus, ac varius enim lorem ullamcorper dolore aliquam.
Get in touch
Submit feedback about this site to:
Знайомство з вказівниками у Паскалі
Всім читачам habr.com, привіт! Ми студенти Технічного ВНЗ-Марія та Катерина, і хочемо розповісти про свій досвід роботи з вказівниками мовою програмування Паскаль.
Знайомство з покажчиками відбулося ще на першому курсі, коли нам читали предмет з мови програмування Паскаль. Ця тема нас зацікавила, тому ми вивчили безліч статей та навчальної літератури. для людей будь-якого рівня знань було б розказано про використання покажчиків у Паскалі. Безумовно, інформація з цієї теми є у Інтернеті, але вона розрізнена і більшість авторів складно доносять інформацію для непідготовленого читача, який тільки починає шлях програміста.
Як показує практика, тема покажчиків складна для розуміння, саме тому в нас народилася ідея - написати публікацію про роботу з динамічною пам'яттю та покажчиками, щоб будь-кому, хто побачив цю статтю, подібна тема стала зрозумілою.
Види пам'яті у мові програмування Паскаль
Оперативна пам'ять ПК є сукупність елементарних осередків для зберігання інформації - байтів, кожен з яких має власний номер. Ці номери називаються адресами, що дозволяють звертатися до будь-якого байта пам'яті.
Існує багато різних видів оперативної пам'яті. Всі ці види можна розділити на дві підгрупи. статична пам'ять (Static RAM) та динамічна пам'ять (Dynamic RAM). Коли йдеться про види пам'яті, маються на увазі способи організації роботи з нею, включаючи виділення, звільнення пам'яті та методи доступу.
Статична пам'ять
Статична пам'ять - це пам'ять, яка виділяється на початок роботи програми, на стадії компіляції та складання.
Компіляція - це перетворення програми, складеною вихідною мовою високого рівня (Однією з яких є Паскаль - процедурно-орієнтована мова програмування високого рівня), в еквівалентну програму
на низькорівневою мовою або машинному коді
(Машинний код – це двійкові числа, що виражають команди процесора та дані, які потрібно обробити. Його важко зрозуміти та проводити в ньому якісь коригування).
Складання - Процес отримання інформаційного продукту з вихідного коду. Найчастіше збірка - виконуваний файл - двійковий файл, що містить код (машинні інструкції) програми або бібліотеки.
- статичні змінні мають фіксовану адресу, відомий до запуску програми та не змінюється у процесі її роботи.
- доступ до статичних змінних здійснюється через їхні імена.
- статичні програмні об'єкти народжуються автоматично перед виконанням програми або підпрограми, в якій вони описані, і існують, поки виконання цієї програми чи підпрограми не завершиться. Розмір статичних об'єктівне змінюється протягом усього часу їхнього існування.
прикладом статичного об'єкта у мові Паскаль є змінна, описана у блоці програми чи підпрограми (процедури, функції).
Наведемо приклад статичного об'єкта:
var n: integer; begin n:=32; end.
Таке оголошення породжує статичну змінну цілого типу.
Динамічна пам'ять
Динамічна пам'ять - це оперативна пам'ять, що виділяється у процесі компіляції програми. При динамічному розміщенні
заздалегідь не відомі ні тип, ні кількість даних, що розміщуються, до них не можна звертатися за іменами, як до статичних змінних. Програма може захоплювати ділянки динамічної пам'яті необхідного розміру. Після використання раніше захоплену ділянку динамічної пам'яті слід звільнити.
Під динамічну пам'ять відводиться простір між статичною пам'яттю та стеком. Зазвичай стек розташовується у старших адресах віртуальної пам'яті та зростає у бік зменшення адрес. Програма та константні дані розміщуються у молодших адресах, вище розташовуються статичні змінні. Простір вище статичних змінних та нижче стека займає динамічна пам'ять:
Динамічну пам'ять зазвичай використовують при:
- обробці великих масивів даних
- розробці САПР (Система Автоматизації Проектних Робот)
- тимчасове збереження даних при роботі з графічними та звуковими засобами ЕОМ
До таких об'єктів відносять:
- файли (текстові, типізовані, нетипізовані)
- лінійні структури
- однозв'язні (черга, стек, список тощо)
- багатозв'язкові (багатозв'язний список)
Управління динамічною пам'яттю пов'язано з використанням типу посилань. Величини, які мають тип посилання, називають вказівниками.
Вказівники найпростіші дії з ними
Покажчик
- це змінна, яка містить адресу іншої змінної (байта пам'яті).
Оголошення покажчиків
Де "^" означає, що задається вказівний тип, а потім йде ім'я будь-якого стандартного або раніше описаного типу.
Операції над покажчиками
До роботи з покажчиком оголосимо ще одну змінну, але не вказівного типу (рядок 3).
var p:^integer; n:integer; k:^integer; k1:integer; y1:^integer; y2:^integer; y3:^integer; begin n:=5; p:=@n; writeln('адреса n:',@n); writeln('значення n:',n); writeln('адреса p:',@p); writeln('значення p:',p); writeln('Розйменування або отримання значення за адресою, що містить p як значення:',p^); k: = @ k1; k^:=9; writeln('Розйменування або отримання значення за адресою, яка містить k як значення:',k^); writeln(); If k^=p^ then begin writeln('значення змінних, розташованих за різними адресами, однакове'); writeln('значення p:',p); writeln('значення k:',k); end; If k^<>p^ then begin writeln('значення змінних, розташованих за різними адресами, різні'); writeln('Розйменування k:',k^); writeln('Розйменування p:',p^); end; writeln(); y2:=@n; y1:=y2; writeln('Розйменування y1:',y1^); writeln('Розйменування y2:',y2^); writeln(); y3:=nil; writeln('Значення y3:',y3); end.
- У рядках 11, 12, 14, 17, 36: ми отримуємо адресу змінної, використовуючи символ «@».
- У рядках 16, 19, 21, 28 і т.д.: ми отримуємо значення змінної на її адресу, використовуючи символ «^». Ця операція називається «розіменування». (Розйменування це операція отримання значення об'єкта, адреса якого зберігається в покажчику). Додамо до нашої програми дві змінні: типу покажчик - k і ціле k1 (рядки 4,5).
- У рядках 10, 11, 17 тощо: ми використовуємо операцію «присвоєння».Присвоїти можна:
- значення того ж типу, що і покажчик (рядок 36, 37)
Результат роботи програми
- адреса іншої змінної (рядок 11, 17)
- спеціальне значення, яке називається порожнім покажчиком і позначається службовим словом nil (Воно пов'язані з жодним об'єктом, тобто. ні на що фактично не вказує, рядок 41) Результат роботи програми
- значення типу, який вказує покажчик (рядок 18)
- У рядку 21: ми порівнюємо вказівники на «рівність».
- У рядку 28: ми порівнюємо вказівники на «нерівність».
Процедури роботи з покажчиками
Першим кроком після оголошення змінної типу покажчик (рядок 2) є процедура виділення пам'яті,
яка позначається new (покажчик). Ця процедура має один параметр (рядок 4).
var p:^integer; begin new(p); end.
Після застосування процедури new під змінну p
виділилася пам'ять.
*Для кращого засвоєння матеріалу графічно зображуватимемо покажчики. На схемі точка буде ставитися в покажчика і малюватись стрілка для зв'язування його з відповідним об'єктом.
Об'єкт, створений за допомогою new У процесі виконання програми або підпрограми існує аж до завершення основної програми, або до тих пір, поки він не буде знищений явно.При створенні об'єкта вказівник на нього поміщається в змінну, яка є фактичним параметром оператора виклику процедури new.
У початковий момент виконання програми змінна p не має жодного значення:
Після створення динамічного об'єкта покажчик на нього автоматично надається змінною p. Схематично результат зображується так:
Змінна
p
тепер "вказує" на об'єкт цілого типу, Тому саму вказівну змінну теж називають покажчиком. Зауважимо, що параметр процедури new однозначно визначає, якого типу об'єкт породжується. У разі з опису типу змінної p випливає, що породжується об'єкт типу integer. Зазначимо, що об'єкти, що породжуються, не мають жодного початкового значення.
Для звільнення динамічної пам'яті, яку вказує покажчик застосовується процедура видалення
dispose (покажчик) (рядок 8). Параметр у цій процедурі має бути вказівником на вже існуючий динамічний об'єкт, інакше виникне помилка.
var p:^integer; begin new(p); writeln('Адреса вказівника: ', @ p); writeln('Значення вказівника: ', p); writeln('Розйменування покажчика:', p^); dispose(p); writeln(); writeln('Адреса вказівника після видалення: ', @ p); writeln('Значення вказівника після видалення:', p); end.
Після застосування об'єкт, зазначений як фактичний параметр перестає існувати, a покажчик на нього видаляється з безлічі значень вказівного типу, в результаті чого всі змінні, що містять покажчик на знищений об'єкт, стають невизначеними.
Слід пам'ятати, що повторне застосування процедури dispose до вільного покажчика може призвести до помилки.
Переваги та недоліки покажчиків
- Переваги покажчиків
- зменшують обсяг пам'яті та скорочує час виконання програми
- дозволяють повертати кілька значень з функції та можуть використовуватись для передачі інформації між функціями
- дають можливість змінити розмір динамічно виділеного блоку пам'яті
- дозволяють отримати доступ до будь-якої комірки пам'яті комп'ютера
- допомагають створювати складні структури даних, такі як список, стек, черги, дерева, графіки і т.д.
- Недоліки покажчиків
- виділений динамічно блок пам'яті необхідно звільняти явно, інакше може статися витік пам'яті
- підвищують ймовірність виникнення помилок та проблем із пам'яттю. При цьому знайти та виправити ці помилки завдання не з легких, особливо в об'ємних програмах
- складні для розуміння та вимагають певного обсягу знань. Програміст несе відповідальність за ефективне та правильне використання покажчиків
Навіщо потрібні покажчики?
Якщо немає особливої необхідності використовувати покажчики, краще вибирати альтернативний варіант, який завжди присутній. Наприклад, використання посилань.
- Для того щоб безпосередньо працювати з пам'яттю Вказівники потрібні для того, щоб можна було працювати з оперативною пам'яттю. Наприклад, під час передачі покажчика на функцію комп'ютер не створює її локальну копію, а звертається безпосередньо до неї.
- Для динамічного керування пам'яттю Якщо нам потрібно виділити в пам'яті деяку область для зберігання даних, але стандартні змінні нам не підходять, ми можемо використовувати покажчик. В цьому випадку ми поміщаємо в нього стартову адресу осередку і говоримо, скільки байтів після нього потрібно використовувати і що в них покласти.
Завдання із застосуванням покажчиків
- Через покажчики на покажчики порахувати суму двох чисел та записати до третього.
var num_1, num_2:integer; //два числа, значення яких використовуватимуться у додаванні sum:integer; //змінна задля збереження рез-та додавання x, y:^integer; //Змінні для зберігання адрес двох чисел x1:^^integer; //перше доданок y1:^^integer; //друге доданок begin //занесення змінні числових значень num_1:=1; num_2: = 2; //Привласнення змінним типу покажчик у кач-ві значення адрес змінних цільового типу x: = @ num_1; y:=@num_2; //Привласнення змінним типу покажчик на покажчик в кач-ві значення адрес змінних типу покажчик x1: = @ x; y1: = @ y; //Підсумування двох чисел, це виходить за рахунок подвійного розіменування змінної типу покажчик на покажчик на тип integer sum: = x1 ^ ^ + y1 ^ ^; writeln('сума:',sum); end.
- Напишіть функцію swap, яка змінює значення переданих аргументів. У Pascal існують два типи підпрограм: процедури та функції (службові слова: procedure, function). Процедури після виконання не повертають жодного значення підпрограми, а функція повертає результат. При написанні підпрограм важливим етапом є передача параметрів. Виділяють параметри-значення і параметри-змінні.
- Параметри-значення При цьому формальні параметри підпрограми передаються копії фактичних. Перед формальними параметрами немає слова Var. З такими параметрами зручно працювати, оскільки під час виклику підпрограми з їхньої місце можна підставити як змінну, а й константу чи вираз. Навіть якщо всередині підпрограми значення такого параметра змінюється, при виході з неї воно відновлюється (оскільки змінюється значення не самого параметра, а його копії).
- Параметри-змінні При цьому формальні параметри підпрограми передаються адреси фактичних. Фактичні значення за вказаною адресою змінюються. Перед формальними параметрами вказується слово Var. Приклад передача значень у підпрограму зі словом var є завдання 2.
//Створюємо два покажчики на ціле число та дві змінні типу ціле число var p1: ^integer; p2:^integer; x:integer; y:integer; procedure Swap(var a,b:integer); //Створюємо тимчасову змінну типу ціле var temp: integer; begin //Надаємо temp значення першої змінної temp:=a; //Привласнюємо першої змінної значення другий a:=b; //Привласнюємо другий змінної значення temp b: = temp; end; begin //Привласнюємо ціле значення змінним x:=5; y:=8; //Ініціалізуємо покажчики p1: = @ x; p2: = @ y; //Викликаємо процедуру, яка змінює місцями значення двох змінних, використовуючи операцію розіменування Swap(p1^, p2^); writeln (p1^); writeln(p2^); end.
Висновок
У цій статті ми спробували на власному досвіді вивчення вказівників у Паскалі поділитися отриманими знаннями та простою мовою пояснити базові поняття, підкріпивши їх прикладами та схемами. Якщо ви розібралися в темі покажчиків: отримали нові знання або освіжили в пам'яті раніше вивчене, то мета статті досягнута
Звичайно, ми розповіли не все про покажчики та їх можливості. Сподіваємося, що ця стаття допомогла Вам знайти відповіді на запитання, що цікавлять, за розглянутою темою і спонукала до подальшого, більш глибокого вивчення покажчиків не тільки мовою Паскаль, але й застосування їх у будь-яких своїх програмах. До зустрічі у майбутніх статтях :)