Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Auto, extern, register, static, mutable 5 страница




Крім додавання покажчика з цілочисельним значенням і віднімання його від покажчика, а також обчислення різниці двох покажчиків, над покажчиками жодні інші арифметичні операції не виконуються. Наприклад, до покажчиків не можна додавати float - або double -значення.

Щоб зрозуміти, як формується результат виконання арифметичних операцій над покажчиками, виконаємо таку коротку програму. Вона виводить реальні фізичні адреси, які містять покажчик на int -значення (izm) і покажчик на float -значення (f). Звернемо Вашу увагу на кожну зміну адреси (залежну від базового типу покажчика), яка відбувається під час повторення циклу[21]. Зверніть увагу також на те, що під час використання покажчика в cout -настанові його адреса автоматично відображається у форматі адресації, що вживається для поточного процесора і середовища виконання.

Код програми 6.4. Демонстрація виконання арифметичних операцій над покажчиками

#include <vcl>

#include <iostream> // Для потокового введення-виведення

#include <conio> // Для консольного режиму роботи

using namespace std; // Використання стандартного простору імен

 

int main ()

{

int *izm, jzm[10];

double *f, g[10];

int x;

 

izm = jzm;

f = g;

 

for (x=0; x<10; x++)

cout << izm + x << " " << f + x << "\n";

 

getch (); return 0;

}

Ось як виглядають можливі варіанти виконання цієї програми[22]:

0012FE5C 0012FE84 0012FE60 0012FE8C 0012FE64 0012FE94 0012FE68 0012FE9C 0012FE6C 0012FEA4 0012FE70 0012FEAC 0012FE74 0012FEB4 0012FE78 0012FEBC 0012FE7C 0012FEC4 0012FE80 0012FECC 1245016 1244936 1245020 1244944 1245024 1244952 1245028 1244960 1245032 1244968 1245036 1244976 1245040 1244984 1245044 1244992 1245048 1245000 1245052 1245008

Необхідно пам'ятати! Всі арифметичні операції над покажчиками виконуються щодо базового типу покажчика.

6.3.2. Порівняння покажчиків

Покажчики можна порівнювати, використовуючи оператори відношення ==, < і >. Проте для того, щоб результат порівняння покажчиків піддавався інтерпретації, порівнювані покажчики мають бути якимсь чином пов'язані між собою. Наприклад, якщо р1 і р2 – покажчики, які посилаються на дві окремі та ніяк не пов'язані між собою змінні, то будь-яке порівняння р1 і р2 в загальному випадку немає сенсу. Але, якщо покажчики р1 і р2 вказують на змінні, між якими існує деякий зв'язок (як, наприклад, між елементами одного і того ж масиву), то результат порівняння покажчиків р1 і р2 може мати певний сенс. Нижче у цьому підрозділі розглянемо приклад програми, у якій використовується порівняння покажчиків.

6.4. Покажчики і масиви

У мові програмування C++ покажчики і масиви тісно пов'язані між собою, причому настільки, що часто поняття "покажчик" і "масив" взаємозамінні. У цьому підрозділі ми спробуємо простежити цей зв'язок. Для початку розглянемо такий фрагмент програми:

char strMas[80];

char *p1;

p1 = strMas;

У цьому записі strMas є іменем масиву, що містить 80 символів, а р1 – покажчик на тип char. Особливий інтерес представляє третій рядок, у процесі виконання якого змінній р1 присвоюється адреса першого елемента масиву strMas. Іншими словами, після цього присвоєння р1 вказуватиме на елемент strMas[0]. Йдеться про те, що у мові програмування C++ використання імені масиву без індексу генерує покажчик на перший елемент цього масиву. Таким чином, у процесі виконання операції присвоєння p1 = strMas адреса strMas[0] присвоюється покажчику p1. Це і є ключовим моментом, який необхідно чітко розуміти: неіндексоване ім'я масиву, використане у виразі, означає покажчик на початок цього масиву.

Ім'я масиву без індексу утворює покажчик на початок цього масиву.

Оскільки після розглянутого вище присвоєння покажчик р1 вказуватиме на початок масиву strMas, то р1 можна використовувати для доступу до елементів цього масиву. Наприклад, якщо потрібно отримати доступ до п'ятого елемента масиву strMas, використовується один з таких виразів: strMas[4] або *(p1+4).

У обох випадках буде виконане звернення до п'ятого елемента. Необхідно пам'ятати, що індексування елементів масиву починається з нуля, тому при індексі, що дорівнює чотирьом, забезпечується доступ до п'ятого елемента. Таке саме враження справляє підсумовування значення початкового покажчика (р1) з числом 4, оскільки р1 вказує на перший елемент масиву strMas.

Необхідність використання круглих дужок, у які поміщено вираз p1+4, пов'язана з тим, що оператор "*" має вищий пріоритет, ніж оператор додавання "+". Без цих круглих дужок вираз звівся би до отримання значення, яке адресується покажчиком p1, тобто значення першого елемента масиву, яке потім було б збільшено на 4.

Варто знати! Переконайтеся зайвий раз в правильності використання круглих дужок у виразах з покажчиками. Інакше помилку буде важко відшукати, оскільки зовні програма може виглядати цілком коректною. Якщо у Вас є сумніви в потребі їх використання, то прийміть рішення на їх користь – шкоди від цього не буде.

6.4.1. Основні відмінності між індексуванням елементів масивів і арифметичними операціями над покажчиками

У мові програмування C++ передбачено два способи доступу до елементів масивів: за допомогою індексування елементів масивів і арифметики покажчиків. Йдеться про те, що арифметичні операції над покажчиками іноді виконуються швидше, ніж індексування елементів масивів, особливо під час доступу до елементів, розташування яких відрізняється строгою впорядкованістю. Оскільки швидкодія часто є визначальним чинником при виборі тих або інших рішень під час програмування, то використання покажчиків для доступу до елементів масиву – характерна особливість багатьох С++-програм. Окрім того, іноді покажчики дають змогу написати дещо компактніший код програми порівняно з використанням індексування елементів масивів.

Щоб краще зрозуміти відмінність між індексуванням елементів масивів і арифметичними операціями над покажчиками, розглянемо дві версії однієї і тієї ж самої програми. У наведеному нижче коді програми з рядка тексту виділяють слова, розділені між собою пропусками. Наприклад, з рядка "Привіт, друг" програма повинна виділити слова "Привіт" і "друг". Програмісти зазвичай називають такі розмежовані символьні послідовності лексемами (token). У процесі виконання програми вхідний рядок посимвольно копіюється в інший масив (з іменем token) доти, доки не трапиться пропуск. Після цього виділена лексема виводиться на екран, і процес триває доти, доки не буде досягнуто кінця рядка. Наприклад, якщо як вхідний рядок використовувати рядок "Це тільки простий тест.", то програма відобразить таке:

Це

тільки

простий

тест.

Ось як виглядає версія програми поділу рядка на слова з використанням арифметичних покажчиків.

Код програми 6.5. Демонстрація поділу рядка на слова з використанням арифметичних покажчиків

#include <vcl>

#include <iostream> // Для потокового введення-виведення

#include <conio> // Для консольного режиму роботи

#include <cstdio> // Для підтримки системи введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

char strMas[80];

char token[80];

char *p, *q;

 

cout << "Введіть речення: ";

gets (strMas);

 

p = strMas;

 

// Зчитуємо лексему з рядка.

while (*p) {

q = token; // Встановлюємо q для вказівки

// на початок масиву token.

 

/* Зчитуємо символи доти, доки не трапиться або пропуск,

або нульовий символ (ознака завершення рядка). */

while (*p!=' ' && *p) {

*q = *p;

q++;

p++;

}

if (*p) p++; // Переміщаємося за пропуск.

*q = '\0'; // Завершуємо лексему нульовим символом.

cout << token << "\n";

}

 

getch (); return 0;

}

А ось як виглядає версія тієї ж самої програми з використанням індексування елементів масивів.

Код програми 6.6. Демонстрація поділу рядка на слова з використанням
індексування елементів масивів

#include <vcl>

#include <iostream> // Для потокового введення-виведення

#include <conio> // Для консольного режиму роботи

#include <cstdio> // Для підтримки системи введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

char strMas[80];

char token[80];

int i, j;

 

cout << "Введіть речення: ";

gets (strMas);

 

// Зчитуємо лексему з рядка.

for (i=0;; i++) {

// Зчитуємо символи доти, доки не трапиться пропуск,

// або нульовий символ (ознака завершення рядка).

for (j=0; strMas[i]!=' ' && strMas[i]; j++, i++)

token[j] = strMas[i];

token[j] = '\0'; // Завершуємо лексему нульовим символом.

cout << token << "\n";

if (!strMas[i]) break;

}

 

getch (); return 0;

}

У цих програм може бути різна швидкодія, що зумовлено особливостями генерування коду програми С++-компіляторами. Як правило, під час використання індексування елементів масивів генерується довший код (з великою кількістю машинних команд), ніж це робиться у процесі виконання арифметичних дій над покажчиками. Тому не дивно, що професійно в написаному С++-коді програми частіше трапляються версії, які орієнтуються на оброблення покажчиків. Але, якщо Ви – програміст-початківець, то сміливо використовуйте індексування елементів масивів, доки не навчитеся вільно володіти покажчиками.

6.4.2. Індексування покажчика

Як було показано вище, можна отримати доступ до масиву, використовуючи арифметичні дії над покажчиками. Цікаво, що у мові програмування C++ покажчик, який посилається на масив, можна індексувати так, як би це було ім'я масиву (це свідчить про тісний зв'язок між покажчиками і масивами). Відповідний такому підходу синтаксис забезпечує альтернативу арифметичним операціям над покажчиками, оскільки він є дещо зручнішим у деяких ситуаціях. Розглянемо конкретний приклад.

Код програми 6.7. Демонстрація індексування покажчика подібно до індексування масиву

#include <iostream> // Для потокового введення-виведення

#include <cctype> // Для роботи з символьними аргументами

using namespace std; // Використання стандартного простору імен

 

int main ()

{

char strMas[20] = "Я тебе люблю";

char *p;

int i;

 

p = strMas;

 

// Індексуємо покажчик.

for (i=0; p[i]; i++) p[i] = toupper (p[i]);

cout << p; // Відображаємо рядок.

 

getch (); return 0;

}

У процесі виконання програма відобразить на екрані таке:

Я тебе люблю

Ось як працює ця програма. Спочатку в масив strMas вводиться рядок " Я тебе люблю". Потім адреса початку цього рядка присвоюється покажчику р. Після цього кожен символ рядка strMas за допомогою функції toupper () перетвориться в його прописний еквівалент за допомогою індексування покажчика р. Пам'ятайте, що вираз р[i] за своєю дією однаковий виразу *(p+i).

6.4.3. Взаємозамінність покажчиків і масивів

Вище було показано, що покажчики і масиви дуже тісно пов'язані. І дійсно, у багатьох випадках вони взаємозамінні. Наприклад, за допомогою покажчика, який містить адресу початку масиву, можна отримати доступ до елементів цього масиву або за допомогою арифметичних дій над покажчиком, або за допомогою індексування елементів масиву. Проте в загальному випадку покажчики і масиви не є взаємозамінними. Розглянемо, наприклад, такий фрагмент коду програми:

int num[10];

int i;

for (i=0; i<10; i++) {

*num = i; // Тут все гаразд.

num++; // Помилка – змінну num модифікувати не можна.

}

Тут використовується масив цілочисельних значень з іменем num. Як зазначено в коментарі, незважаючи на те, що абсолютно прийнятно застосувати до імені num оператор "*" (який зазвичай застосовується до покажчиків), проте абсолютно неприпустимо модифікувати значення num. Йдеться про те, що num – це константа, яка вказує на початок масиву. І її, як наслідок, інкрементувати ніяк не можна. Іншими словами, хоча ім'я масиву (без індексу) дійсно генерує покажчик на початок масиву, однак його значення зміні не підлягає.

Хоча ім'я масиву генерує константу-покажчик, його, проте, (подібно до покажчиків) можна помістити у вирази, якщо, звичайно, воно при цьому не модифікується. Наприклад, наступна настанова, у процесі виконання якої елементу num[3] присвоюється значення 100, є цілком допустимою:

*(num+3) = 100; // Тут все гаразд оскільки num не змінюється.

6.4.4. Масиви покажчиків

Покажчики, подібно до інших типів даних, можуть зберігатися в масивах. Ось, наприклад, як виглядає оголошення 10-елементного масиву покажчиків на int -значення.

int *ipa[10];

У цьому записі кожен елемент масиву ipa містить покажчик на цілочисельне значення.

Щоб присвоїти адресу int -змінній з ім'ям var третьому елементу цього масиву покажчиків, записується таке:

ipa[2] = &var;

Необхідно пам'ятати, що тут ipa – масив покажчиків на цілочисельні значення. Елементи цього масиву можуть містити тільки значення, які є адресами змінних цілочисельного типу. Ось тому змінна var передує оператору "&".

Щоб присвоїти значення змінної var цілочисельній змінній х за допомогою масиву ipa, використовують такий синтаксис:

х = *ipa[2];

Оскільки адреса змінної var зберігається в елементі ipa[2], то застосування оператора "*" до цієї індексованої змінної дасть змогу набути значення змінній var.

Подібно до інших масивів, масиви покажчиків можна ініціалізувати. Як правило, масиви ініціалізованих покажчиків використовують для зберігання покажчиків на рядки. Наприклад, щоб створити функцію, яка виводить щасливі передбачення, можна таким чином визначити масив fortunes:

char * fortunes []= {

"Незабаром гроші потечуть до Вас рікою.\n"

"Ваше життя осяє нове кохання.\n"

"Ви житимете довго і щасливо.\n"

"Гроші, вкладені зараз в справу, незабаром принесуть дохід.\n"

"Близький друг шукатиме Вашої підтримки.\n"

};

Не забувайте, що мова програмування C++ забезпечує зберігання всіх рядкових літералів у таблиці рядків, пов'язаній з конкретною програмою, тому масив потрібен тільки для зберігання покажчиків на ці рядки. Таким чином, для виведення другого повідомлення достатньо використовувати настанову, подібну до такої:

cout << fortunes [1];

Наведений нижче код програми передбачень є цілком коректною. Для отримання випадкових чисел у ній використовується функція rand (), а для отримання випадкових чисел в діапазоні від 0 до 4 – оператор ділення за модулем, оскільки саме такі числа можуть слугувати для доступу до елементів масиву за індексом.

Код програми 6.8. Демонстрація механізму використання масиву покажчиків

#include <vcl>

#include <iostream> // Для потокового введення-виведення

#include <cstdlib> // Для використання бібліотечних функцій

#include <conio.h> // Для консольного режиму роботи

using namespace std; // Використання стандартного простору імен

 

char * fortunes [] = {

"Незабаром гроші потечуть до Вас рікою.\n"

"Ваше життя осяє нове кохання.\n"

"Ви житимете довго і щасливо.\n"

"Гроші, вкладені зараз в справу, незабаром принесуть дохід.\n"

"Близький друг шукатиме Вашої підтримки.\n"

};

 

int main ()

{

int chance;

cout << "Щоб дізнатися про свою долю, натисніть будь-яку клавішу: ";

 

// Рандомізуємо генератор випадкових чисел.

while (! kbhit ()) rand ();

cout << "\n";

 

chance = rand ();

chance = chance % 5;

cout << fortunes [chance];

 

getch (); return 0;

}

Звернемо Вашу увагу на цикл while, який викликає функцію rand () доти, доки не буде натиснуто на яку-небудь клавішу. Оскільки функція rand () завжди генерує одну і ту саму послідовність випадкових чисел, важливо мати можливість програмно використовувати цю послідовність з певної довільної позиції[23]. Ефект випадковості досягається за рахунок повторних звернень до функції rand (). Коли користувач натисне на клавішу, цикл зупиниться на деякій випадковій позиції послідовності чисел, що генеруються, і ця позиція визначить номер повідомлення, яке буде виведено на екран. Нагадаємо, що функція kbhit () є достатньо поширеним розширенням бібліотеки функцій мови програмування C++, що забезпечується багатьма компіляторами, але не входить в стандартний пакет бібліотечних функцій мови C++.

У наведеному нижче прикладі використовується двовимірний масив покажчиків для розроблення програми, яка відображає синтаксис-пам'ятку за ключовими словами мови програмування C++. У програмі ініціалізується перелік покажчиків на рядки. Перша розмірність масиву призначена для вказівки на ключові слова мови програмування C++, а друга – на короткий їх опис. Перелік завершується двома нульовими рядками, які використовуються як ознака кінця списку. Користувач вводить ключове слово, а програма повинна вивести на екран його опис. Як бачимо, цей перелік містить всього декілька ключових слів. Тому його продовження залишається за Вами.

Код програми 6.9. Демонстрація відображення синтаксис-пам'ятки за ключовими
словами мови програмування C++

#include <iostream> // Для потокового введення-виведення

#include <cstring> // Для роботи з рядковими типами даних

using namespace std; // Використання стандартного простору імен

 

char * keyword [][ 2 ] = {

"for", "for(ініціалізація; умова; інкремент)",

" if ", " if (умова)... else...",

"switch", "switch(значення) { case-перелік }",

"while", "while(умова)...",

// Сюди потрібно додати решту ключових слів мови програмування C++.

"", "" // Перелік повинен завершуватися нульовими рядками.

};

 

int main ()

{

char strMas[80];

int i;

cout << "Введіть ключове слово: ";

cin >> strMas;

 

// Відображаємо синтаксис.

for (i=0; * keyword [i][0]; i++)

if (! strcmp (keyword [i][0], strMas)) cout << keyword [i][1];

 

getch (); return 0;

}

Ось приклад виконання цієї програми:

Введіть ключове слово: for

for (ініціалізація; умова; інкремент)

У цій програмі зверніть увагу на керівний вираз циклом for. Він призводить до завершення циклу, коли елемент keyword [i][0] містить покажчик на нуль, який інтерпретується як значення ФАЛЬШ. Отже, цикл зупиняється тоді, коли трапляється нульовий рядок, який завершує масив покажчиків.

6.4.5. Покажчики і рядкові літерали

Можливо, Вас здивує спосіб оброблення С++-компіляторами рядкових літералів, подібних до такого:

cout << strlenf' С++-компілятор");

Якщо С++-компілятор виявляє рядковий літерал, то він зберігає його в таблиці рядків програми і генерує покажчик на потрібний рядок. Тому наведений нижче код програми є абсолютно коректною, у процесі виконання якої на екран виводиться фраза "Робота з покажчиками – суцільне задоволення!".

Код програми 6.10. Демонстрація роботи з рядковими літералами

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

char *s;

 

s = "Робота з покажчиками – суцільне задоволення!\n";

cout << s;

 

getch (); return 0;

}

У процесі виконання цієї програми символи, що утворюють рядковий літерал, зберігаються в таблиці рядків, а змінній s присвоюється покажчик на відповідний рядок у цій таблиці.

Таблиця рядків – це таблиця, що згенерується компілятором для зберігання рядків, що використовуються у програмі.

Оскільки покажчик на таблицю рядків конкретної програми під час використання рядкового літерала генерується автоматично, то можна спробувати використовувати цей факт для модифікації вмісту цієї таблиці. Проте таке рішення навряд чи можна назвати вдалим. Йдеться про те, що С++-компілятори створюють оптимізовані таблиці, у яких один рядковий літерал може використовуватися в двох (або більше) різних місцях програми. Тому "насильницька" зміна рядка може викликати небажані побічні ефекти. Понад це, рядкові літерали є константами, і деякі сучасні С++-компілятори просто не дають змоги змінювати їх вміст. А під час спроби зробити це С++-компілятор згенерує помилку тривалості виконання.

6.4.5. Приклад порівняння покажчиків

Вище ми вже наголошували на тому, що значення одного покажчика можна порівнювати з іншим. Але, щоб порівняння покажчиків мало сенс, порівнювані покажчики мають бути якимсь чином пов'язані один з одним. Найчастіше такий зв'язок встановлюється у разі, коли обидва покажчики вказують на елементи одного і того ж масиву. Наприклад, дано два покажчики (з іменами А і В), які посилаються на один і той самий масив. Якщо А менше ніж В, значить, покажчик А вказує на елемент, індекс якого менше від індексу елемента, яка адресується покажчиком В. Таке порівняння особливо корисне для визначення граничних умов.

Порівняння покажчиків продемонстровано у наведеному нижче коді програми, у якій створюються дві змінні типу покажчика. Одна (з іменем start) спочатку вказує на початок масиву, а друга (з іменем end) – на його кінець. У міру введення користувачем чисел масив послідовно заповнюється від початку до кінця. Кожного разу, коли в масив вводиться чергове число, покажчик start інкрементується. Щоб визначити, чи заповнився масив, у програмі просто порівнюються значення покажчиків start і end. Коли start перевищить end, то масив буде заповнений "повністю". Програмі залишиться тільки вивести вміст заповненого масиву на екран.

Код програми 6.11. Демонстрація порівняння покажчиків

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

int num[10];

int *start, *end;

 

start = num;

end = &num[9];

while (start <= end) {

cout << "Введіть число: ";

cin >> *start;

start++;

}

 

start = num; // Відновлення початкового значення покажчика

while (start <= end) {

cout << *start << " ";

start++;

}

 

getch (); return 0;

}

Як показано у цій програмі, оскільки start і end обидва вказують на спільний об'єкт (у цьому випадку ним є масив num), то їх порівняння може мати сенс. Подібне порівняння часто використовують у професійно написаному С++-коді програми.

6.5. Ініціалізація покажчиків

6.5.1. Домовленість про нульові покажчики

Оголошений, але не ініціалізований покажчик міститиме довільне значення. Під час спроби використати покажчик до присвоєння йому конкретного значення можна зруйнувати не тільки власну програму, але навіть і операційну систему (найгірший, треба сказати, тип помилки!). Оскільки не існує гарантованого способу уникнути використання неініціалізованого покажчика, то С++-програмісти прийняли процедуру, яка дає змогу уникати таких жахливих помилок. За домовленістю, якщо покажчик містить нульове значення, то вважається, що він ні на що не посилається. Це означає, що у випадку присвоєння нульового значення всім невживаним покажчикам і уникати його використання, то можна уникнути випадкового використання неініціалізованого покажчика. Рекомендуємо і Вам дотримуватися цієї практики програмування.

Під час оголошення покажчик будь-якого типу можна ініціалізувати нульовим значенням, наприклад, як це робиться в такій настанові.

float *p = 0; // p -- тепер нульовий покажчик.

Для тестування покажчика використовують настанову if (будь-який з таких її варіантів):

if (p) // Виконуємо щось, якщо p -- не нульовий покажчик.

if (!p) // Виконуємо щось, якщо p -- нульовий покажчик.

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

6.5.2. Покажчики і 16-розрядні середовища

На сьогодні більшість обчислювальних середовищ є 32-розряд­ними, однак раніше немало користувачів працювали в 16-розрядних (в основному, це DOS і Windows 3.1) і, природно, з 16-розрядним кодом. Ці операційні системи були розроблені для процесорів родини Intel 8086, які містять такі модифікації, як 80286, 80386, 80486 і Pentium (під час роботи в режимі емуляції процесора 8086). І хоча під час написання нового коду програми програмісти, як правило, орієнтуються на використання 32-розрядного середовища виконання, однак раніше створені програми підтримують компактні 16-розрядні середовища. Позачк деякі теми актуальні тільки для 16-розрядних середовищ, то програмістам, які працюють в них, буде корисно отримати інформацію про те, як адаптувати "старий" програмний код до нового середовища, тобто переорієнтовувати 16-розрядний код на 32-розрядний.

Під час написання 16-розрядного коду програми для процесорів родини Intel 8086 програміст має право розраховувати на шість способів компілювання програм, які відрізняються організацією комп'ютерної пам'яті. Програми можна компілювати для мініатюрної, малої, середньої, компактної, великої і величезної моделей пам'яті. Кожна з цих моделей по-своєму оптимізує простір, що резервується для даних, коду програми і стека. Відмінність в організації комп'ютерної пам'яті пояснюється використанням процесорами родини Intel 8086 сегментованої архітектури у процесі виконання 16-розрядного коду програми. У 16-розрядному сегментованому режимі процесори родини Intel 8086 ділять пам'ять на 16К сегментів.




Поделиться с друзьями:


Дата добавления: 2014-11-29; Просмотров: 516; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.139 сек.