- •Елементи мови с.Основні символи
- •Ключові слова
- •Ідентифікатори
- •Константи
- •Лексеми
- •Коментарі
- •Умовні оператори. Логічні вирази
- •Форми оператора if
- •Оператор вибору switch
- •Перерахування типів
- •Перетворення типів
- •Оператори циклу
- •Оператор while
- •Оператор for
- •Оператор do-while
- •Оператори переходу
- •Cтруктури
- •Об'єднання (суміші)
- •Робота з структурами.
- •Ініціалізація структур
- •Робота з обєднаннями
- •Визначення об'єктів та типів
- •Методи доступу до елементів масивів
- •Покажчики на багатовимірні масиви
- •Операції з вказівниками
- •Робота з покажчиками.
- •Покажчики на структуру
- •Масиви структур
- •Динамічне розміщення масивів
- •Робота з динамічними масивами
- •Робота з непрямою адресацією
- •Робота з покажчиками як параметрами функцій
- •Використання вказівників
- •Операції з вказівниками
- •Використання вказівників в програмі
- •Робота з файлами
- •Відкриття файлу
- •Обробка відкритого файлу
- •Перевірка ознаки кінця файлу
- •Закриття файлу
- •Функції введення-виведення
- •Робота з текстовими файлами
- •Функція форматованого виведення printf ()
- •Основні формати
- •Модифікації форматів
- •Функція форматованого введення scanf ()
- •Робота функції scanf ()
- •Призначеня функцій бібліотеки введення-виведення
- •Макрокоманди
- •Потокові інтерфейси введення-виведення
- •Ближні покажчики (near)
- •Дальні покажчики (far)
- •Покажчики huge
- •Функції для роботи з рядками
- •Динамічні рядки, клас string
- •Визначення поточної робочої директорії
- •Визначення поточного каталогу диска
- •Визначення / встановленн поточного диска
- •Пошук файлу
- •Створення, видалення, зміна директорій
- •Приклад програми для роботи з директоріями
- •Перегляд каталогу диска
- •Параметри структури ffblk
- •Робота з клавіатурою
- •Робота з файлами
- •Послідовний доступ до елементів двійкових файлів
- •Організація довільного доступу до елементів двійкових файлів
- •Робота динамічних структур даних.
- •Функції управління пам'яттю
- •Атрибути файлів.
- •Параметри
- •Динамічні структури даніх
- •Лінійні списки
- •Стек. Загальні поняття.
- •Приклад використання стеку
- •Основні визначення
- •Приклад використання дерев
Ближні покажчики (near)
16-бітовий (near) покажчик для обчислення повної адреси зв'язується з одним із сегментних регістрів; наприклад, покажчик функції складає своє 16-бітове значення із зрушеним вліво вмістом регістра кодового сегмента (CS). Аналогічним чином, ближній покажчик даних містить зсув в сегменті даних, що адресується регістром сегмента даних (DS). З ближніми покажчиками легко маніпулювати, оскільки всі арифметичні операції з ним (наприклад, додавання) можна виконувати безвідносно до сегменту.
Дальні покажчики (far)
Далекий (32-бітовий) покажчик містить не тільки зсув щодо регістра, але також і (в інших 16 бітах) адреса сегмента, який потім повинен бути зрушений вліво і складний із значенням зсуву. Використання дальніх покажчиків дозволяє мати в програмі декілька кодових сегментів; це, в свою чергу, дозволяє програмі перевищувати 64К. Можна також адресувати більше 64К даних.
При використанні дальніх покажчиків для адресації даних вам слід враховувати деякі потенційні проблеми, які можуть виникати при маніпулюванні такими покажчиками. Як пояснювалося в розділі, присвяченому обчисленням адреси, може існувати безліч пар типу сегмент: зсув, що адресують одну і ту ж точку пам'яті. Наприклад, далекі покажчики 0000:0120, 0010:0020 і 0012:0000 дозволяються до одного і того ж 2-бітовому адресою. Однак, якщо у вас були б три змінних типу далекого покажчика - a, b і c, що містять відповідно три зазначених значення, то наступні вирази всі давали б значення "брехня":
if (a == b). . .
if (b == c). . .
if (a == c). . .
Аналогічна проблема виникає, коли вам потрібно порівнювати дальні покажчики за допомогою операцій>,> =, <і <=. У цих випадках у порівнянні бере участь тільки зміщення (як unsigned); при вказаних вище значеннях a, b і c наступні вирази дадуть значення "істина":
if (a> b). . .
if (b> c). . .
if (a> c). . .
Операції рівності (==) та нерівності (! =) Використовують 32-бітові значення як unsigned long (а не у вигляді повної адреси пам'яті). Операції порівняння (<=,> =, <і>) використовують тільки зміщення.
Операції == і! = Вимагають всі 32 біта, що дозволяє комп'ютеру виконувати порівняння з порожнім (NULL) покажчиком (0000:0000). Якщо для перевірки рівності використовувалося тільки значення зсуву, то будь покажчик зі зміщенням 0000 буде дорівнює пустому покажчику, що явно не збігається з тим, що ви хотіли отримати.
При додаванні деякого значення з далеким покажчиком змінюється тільки зміщення. Якщо доданок настільки велике, що сума перевищує FFFF (максимально можлива для зміщення величина), то покажчик перейде знову до початку сегменту. Наприклад, якщо скласти 1 і 5031: FFFF, то результат буде дорівнює 5031:0000 (а не 6031:0000). Подібним же чином, при відніманні 1 з 5031:0000 вийде 5031: FFFF (а не 5030:000 F).
Якщо вам знадобиться виконати порівняння покажчиків, то безпечний спосіб полягає в тому, щоб або використовувати для цього ближні покажчики - все з однією адресою сегмента - або описувані нижче покажчики huge.
Покажчики huge
Покажчики huge також мають розмір 32 біта. як і покажчики far, вони містять одночасно адресу сегмента і зміщення. Однак, на відміну від далеких покажчиків, вони нормалізовані, що дозволяє уникнути проблем, пов'язаних з далекими покажчиками.
Що таке нормалізований покажчик? Це 32-бітовий покажчик, який містить у своєму адресу сегмента максимально можливе там значення. Оскільки сегмент може починатися через кожні 16 байт (10 при підставі 16), це означає, що величина зсуву буде дорівнює числу від 0 до 15 (від 0 до F з підставою 16).
Для нормалізації покажчика він перетвориться до 20-бітовому адресою, після чого праві 4 біти беруться в якості зсуву, а ліві 16 бітів - як адреса сегмента. Наприклад, покажчик 2F84: 0532 можна спочатку перетворити до абсолютного адресою 2FD72, після чого отримати нормалізований покажчик 2FD7: 0002. Наведемо ще ннесколько покажчиків з нормалізованими значеннями:
0000:0123 0012:0003
0040:0056 0045:0006
500D: 9407 594D: 0007
7418: D03F 811B: 000F
Існує три причини, що змушують завжди зберігати покажчик huge в нормалізованому вигляді:
1. Оскільки в такому випадку будь-якому заданому адресою пам'яті відповідає тільки один можливий адресу у вигляді сегмент: зсув типу huge. Це означає, що для покажчиків huge операції == і! = Завжди будуть повертати правильне значення.
2. Крім того, операції>,> =, <і <= працюють з повним 32-бітовим значенням покажчика huge. Нормалізація гарантує в даному випадку коректність результату.
3. І нарешті, внаслідок нормалізації зсув в покажчику huge виконує автоматичний перехід через 16 але на відміну від далеких покажчиків, перехід зачіпає і сегмент. Наприклад, при інкремент 811B: 000F результатбудет дорівнює 811C: 0000; аналогічним чином, при декремент 800C: 0000 вийде 811B: 000F. Ця особливість покажчиків huge дозволяє маніпулювати зі структурами даних з розміром більше 64К. Гарантується, наприклад, що якщо у вас є масив структур типу huge, що перевищує 64К, індексація цього масиву і вибір поля структури завжди будуть виконуватися правильно, незалежно від розміру структури.
Використання покажчиків huge має свою ціну: збільшення часу обробки. Арифметичні операції з вказівниками huge виконуються за допомогою звернень до спеціальних підпрограм. Внаслідок цього арифметичні обчислення займають істотно більше часу в порівнянні з обчисленнями для покажчиків far або near.
Питання для контролю:
1. Що таке показник типу (near)?
2. Що таке показник типу (far)?
3. Де використовується покажчик huge?
Література:
1. Культин Н. С/С++ в задачах и примерах. –СПб.:БХВ-Петербург, 2001. –288 с.- с. 280-283
Урок №51
(згідно робочої навчальної програми)
Тема:Рядкові покажчики, нульові рядки і нульові символи
Питання:
1.Функції для роботи з рядками
2. Динамічні рядки, клас string
