Розраха(курсова) з Лисачки

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
ІКТА
Факультет:
КН
Кафедра:
Кафедра ЕПМС

Інформація про роботу

Рік:
2010
Тип роботи:
Розрахункова робота
Предмет:
Програмування частина 4 Технологія системного програмування
Група:
КІ

Частина тексту файла (без зображень, графіків і формул):

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА” Кафедра ЕОМ  Розрахункова робота з програмування "Представлення в пам’яті комп’ютера статичних даних" Завдання на розрахункову роботу Індивідуальне завдання 1: Визначити внутрішнє представлення в пам’яті комп’ютера даних базових типів. Розглянути основні прості (цілі, дійсні, символьні, логічні) типи даних: bool b = (25 * 5) % 10 * 11; //1 unsigned char ch2 = ’o’; //111 int i4 = -25 * 215; //-5375 double d2 = 275.25e+11; //27525000000000 2. Індивідуальне завдання 2: Визначити внутрішнє представлення в пам’яті комп’ютера даних похідних типів. рядки char *string9 = "34\xe5\\\\\\v3\x4g5\xdfvdfw""""f"; string9[0] = '5'; string9[2] = '8'; string9[4] = '8'; string9[6] = '2'; string9[8] = '6'; string9[10] = '6'; string9[12] = '1'; string9[14] = '4'; перерахування enum color18 { BLUE = -2, GREEN, CYAN, RED, BROWN, GRAY = 9, YELLOW, WHІTE, MAGENTA, LІGHTGRAY, DARKGRAY, BLACK } c1= CYAN, c2= BROWN, c3= DARKGRAY; масиви unsigned short array11[][2][4] = {{2,2,232}, '2','/'} array11[0][0][0] = 0 * 25; array11[0][0][1] = 9 * 25; array11[0][0][2] = 5 * 25; array11[0][0][3] = 8 * 25; array11[0][1][0] = 8 * 25; array11[0][1][1] = 2 * 25; array11[0][1][2] = 6 * 25; array11[0][1][3] = 6 * 25; array11[1][0][0] = 1 * 25; array11[1][0][1] = 4 * 25; структури struct str3 { double a; unsigned e:6; int d; unsigned b:5; unsigned :3; char c[7]; wchar_t f; }str; str.a = 25.275; str.b = 9 * 1 * 124; str.c[0] = 'S'; str.c[1] = 'o'; str.c[2] = 'p'; str.c[3] = 'u'; str.c[4] = 's'; str.d = 764 * 9 * 8; str.e = 25 * 11 * 36; str.f = 4; об’єдняння union un20{ int b; struct{ char c; double e; }; struct{ double f; char a[10]; }; }un; un.e = 1 * 325 + 1991 * 25; un.c = 25 * (11 + 9) * 100; un.a[0] = '2'; un.a[1] = '6'; un.a[2] = '6'; un.a[3] = '1'; un.a[4] = '4'; Зміст Теоретична частина Система тестів Завдання 1: Внутрішні формати базових типів 2.1.1. Змінна логічного типу 2.1.2. Змінна символьного типу 2.1.3. Змінна цілого типу 2.1.4. Змінна дійсного типу Завдання 2: Внутрішні формати похідних типів 3.2.1. Рядок символів 3.2.2. Перерахування 3.2.3. Масив 3.2.4. Структура 3.2.5. Об'єднання Результати виконання програми Висновки Список літератури Додатки Вступ В даній розрахунковій роботі буде розглянуто представлення в пам’яті основних типів даних мови С++. В першому завданні буде розглянуто представлення даних базових типів, а саме: логічного, символьного, цілого та дійсного типу даних, в другому завданні – дані похідних типів: рядки символів, переліки, масиви, структури та об’єднання. Дані задачі допоможуть зрозуміти принципи збереження даних в оперативній пам’яті. Це дозволить, в свою чергу, підвищити ефективність програмних продуктів і оптимізувати їх роботу найбільш ефективно використовуючи типи даних. Також це дасть змогу зробити програму компактною зекономити пам'ять комп’ютера і машинний час. Отже розуміння способу представлення даних в пам’яті комп’ютера має велике практичне значення. Теоретична частина В пам'яті комп'ютера змінна типу bool займає 1 байт. Логічні значення можна асоціювати зі значеннями типу int: значенню false відповідає нуль, значенню true відповідають всі інші числа. В арифметичних і логічних виразах логічні значення перетворюються в цілі числа. Арифметичні та бітові логічні операції виконуються над перетвореними величинами. Якщо результат приводиться знову до логічного типу, то 0 перетворюється в false, а ненульове значення перетворюється в true. (true - в пам’яті комп’ютера змінна х зберігається як послідовність: 0000 0000; false як послідовність: 0000 0001) Ідентифікатором символьного типу є ключове слово char. Символьні константи (символьні літерали) можна представляти як: клавіатурні: '1','s','Y' – записуються як символи в одинарних лапках; кодові: '\n','\\','\?', які використовуються для представлення деяких керуючих символів та символів-розділювачів – записуються як escape-послідовності (вони починаються з символу зворотної косої риски). кодові числові: '\0','\x5C','\124', які використовуються для представлення будь-яких символів – записуються у вигляді однієї, двох або трьох вісімкових цифр з символом зворотної косої риски ( \ ) перед ними або довільним шістнадцятковим числом з послідовністю \х перед ним. Послідовність вісімкових або шістнадцяткових цифр закінчується першим символом, який не є відповідно вісімковою або шістнадцятковою цифрою. Змінні типу сhar займають 1 байт пам’яті. Типи short, іnt і long призначені для представлення цілих чисел. Цілі типи можуть бути знаковими (sіgned) і беззнаковими (unsіgned). В знакових типах самий лівий біт використовується для зберігання знака числа (0 – плюс, 1 – мінус). Решта бітів містять числове значення. В беззнакових типах всі біти використаються для числового значення. За замовчуванням всі цілочисельні типи вважаються знаковими. Літерали цілих типів можна записати в десятковому, вісімковому або шістнадцятковому видах, наприклад: 20 (десяткове), 024 (вісімкове), 0х14 (шістнадцяткове). Якщо літерал починається з 0, він трактується як вісімковий, якщо з 0х або 0Х, то як шістнадцятковий. Звичний запис розглядається як десяткове число. Внутрішнє представлення змінної цілого типу — ціле число у двійковому коді. Згідно формату IEEE всі додатні цілі числа зберігаються в пам'яті комп'ютера в прямому коді, а всі від'ємні – в доповняльному коді. Цілі числа зберігаються в пам'яті комп'ютера у зворотньому порядку розміщення байт числа. У мові С++ дійсні типи або типи з рухомою комою представляються трьома розмірами, що характеризують точність представлення дійсних чисел: float – одиничної точності; double - подвійної точності; long double – розширеної точності (у деяких реалізаціях тип long double може бути відсутній) Константи з рухомою комою мають за замовчуванням тип double. Саме він є найбільш природнім для комп'ютера. У програмуванні треба по можливості уникати типу float, тому що його точність недостатня, а процесор однаково при виконанні операцій перетворить його в тип double. Один з випадків, де застосування типу float виправдане – тривимірна комп'ютерна графіка. Експонентна форма запису дійсної константи містить знак, мантису і десятковий порядок (експоненту). Мантиса – це будь-яка додатня дійсна константа у формі з фіксованою крапкою або цілою константою. Порядок вказує степінь числа 10, на яку домножується мантиса. Порядок відокремлюється від мантиси буквою 'E' або 'e' (від слова exponent). Порядок може мати знак плюс або мінус, у випадку додатнього порядку знак плюс можна опускати. Дійсні числа зберігаються в пам'яті комп'ютера у зворотньому порядку розміщення байт числа. Рядок символів у мові С++ зберігається як масив змінних char. Розмір масиву є на 1 більшим від кількості символів рядка. Останнім символом масиву є число 0016. Це ознака закінчення рядка. Розмір масиву можна не задавати при оголошенні, якщо відразу відбувається ініціалізація рядка. Ініціалізація елементів рядка така сама як і взмінної char. Ознакою початку і закінчення рядка є подвійні лапки. Кілька рядкових констант записаних одна за одною сприймаються як один рядок. В пам’яті рядок зберігається як послідовність змінних char плюс символ 0016 – ознака завершення рядка. Змінна, котра може приймати значення з деякого списку значень, називається змінною перелічуваного типу або переліком. Оголошення переліку задає тип змінної переліку і визначає список іменованих констант, що називається списком переліку. Імена елементів списку переліку задаються в фігурних дужках через кому. Значенням кожного імені списку є деяке ціле число. Змінна типу переліку може приймати значення однієї з іменованих констант списку. Змінні типу enum можуть використовуватись і як операнды в арифметичних операціях та в операціях відношення, і як індекси в індексних виразах. Список переліку може містити одну або декілька конструкцій виду: ідентифікатор [= константний вираз]. Кожен ідентифікатор іменує елемент переліку. Всі ідентифікатори в списку переліку повинні бути унікальними і повинні відрізнятись від всіх інших ідентифікаторів в тій самій області видимості, включаючи імена звичайних змінних та ідентифікатори з інших списків переліку. У випадку відсутності константного виразу перший ідентифікатор набуває значення 0, наступний ідентифікатор - значення 1, наступний - 2 і т.д. Отже, пам'ять, що відводиться під змінну типу перелік - це пам'ять, необхідна для розміщення значення типу іnt. Масив - це впорядкований скінченний набір даних одного типу, які зберігаються в послідовно розташованих комірках оперативної пам'яті і мають спільну назву. З оголошення масиву компілятор одержує інформацію про тип елементів масиву та їх кількість. Для роботи з масивом його елементи індексуються (нумеруються), а доступ до них здійснюється за допомогою операції взяття індексу. В мові С++ індексація масивів починається з 0, тому елемент із індексом 1 насправді є другим елементом масиву, а індекс першого дорівнює 0. Індекс може бути цілим числом або цілим виразом. Якщо в якості індекса використовується вираз, то спочатку обчислюється вираз, щоб визначити конкретний елемент масиву з яким буде виконуватись робота. На відміну від масиву, всі елементи якого однотипні, структура може містити елементи різних типів. В мові C++ структура є видом класу і має всі його властивості, але в багатьох випадках доситатньо використовувати структури так, як вони визначені в мові С. Елементи структури називаються полями структури і можуть мати будь-які типи, крім типу цієї ж структури, але можуть бути вказівниками на неї. Якщо відсутнє ім'я типу, то повинен бути заданий список оголошень перемінних, вказівників або масивів. В цьому випадку опис структури служить визначенням елементів цього списку. Як видно з прикладу, поля різних структур можуть мати однакові імена, оскільки в них різна область видимості. Більше того, можна оголошувати в одній області видимості структуру та інший об'єкт (наприклад, змінну або масив) з однаковими іменами. В пам'яті комп’ютера під кожний елемент структури виділяється визначений відповідно до типу цього елемента об’єм памяті. Елементи в пам'яті зберігаються в тому ж порядку, в якому вони були представлені в описі структури. Розмір змінної структурного типу не можна обчислити просто як суму його елементів, тому що змінні певних типів мають вирівнюватись в пам'яті комп’ютера по деяким залежним від реалізації границям, наприклад, повинні бути вирівняні по границі слова. Це може призводити до "дірок" в структурі. Значення в таких "дірках" невизначені. Навіть якщо значення двох змінних одного й того ж структурного типу дійсно рівні між собою, то не обов’язково, що при порівнянні вони виявляться рівними один одному, оскільки малоймовірно, що невизначені "дірки" містять однакові значення. Елементом структури може бути бітове поле, що забезпечує доступ до окремих бітів пам'яті. Поза структурами бітові поля використовувати не можна. Бітові поля - це особливий вид полів структури. Вони використовуються для щільного упакування даних, наприклад, прапорців типу "так/ні". Найменьша по довжині комірка пам'яті, яку можна адресувати - 1 байт, а для збереження прапорця досить одного біта. При описі бітового поля після імені через двокрапку вказується довжина поля в бітах, що задається цілим виразом або константою. Поле нульової довжини означає вирівнювання на границю наступного слова. Допускаються неіменовані поля бітів. Вони не впливають на зміст іменованих полів, але певним чином можуть поліпшувати розміщення полів в пам'яті. Структури бітових полів можуть містити і знакові елементи. Але, навіть цілі поля можуть розглядатись як беззнакові. Тому рекомендується описувати бітові поля як unsіgned. В пам'яті бітові поля розміщуються на відповідних границях слів, при цьому деякі біти слів можуть залишатись невикористаними. Поле, яке не можна розмістити у місце, що залишилося до границі слова, розміщується в наступне слово. Поле не може бути ширшим за слово. На деяких машинах бітові поля розміщуються справа наліво, а на деяких – зліва направо. Об'єднання дуже схожі на структури. Однак на відміну від структури об'єднання зберігає значення тільки одного елемента в кожний момент часу. Інакше кажучи, коли виконується операція присвоювання значення елементу об'єднання, то перезаписується будь-яке попереднє присвоювання. Головною особливістю об'єднання є те, що для кожного з оголошених елементів виділяється та сама область пам'яті, тобто вони перекриваються. Пам'ять, що відповідає змінній типу об'єднання, визначається величиною, необхідною для розміщення найбільш довгого елемента об'єднання. Коли використовується елемент меншої довжини, то змінна типу об'єднання може містити зайву пам'ять, що не використовується. Всі елементи об'єднання зберігаються в одній і тій cамій області пам'яті, починаючи з однієї адреси. Алгоритм розв’язання задачі. Рішення задачі проводимо за допомогою шаблону функції, що дає змогу працювати з усіма стандартними типами даних. В функції оголошуємо вказівник на змінну типу “unsigned char” і присвоюємо їй адресу змінної, яку необхідно прочитати. Побайтно зчитуємо дані з пам’яті і виводимо їх в шіснадцятковій системі численя, також виводимо десяткове значення змінної. Для другого завдання організовуємо функцію, що читає задану кількість байт починаючи з певної адреси, для того щоб побайтно зчитувати складні структури даних. Система тестів Завдання 1: Внутрішні формати базових типів Логічний тип bool b = (25 * 5) % 10 * 11; Результатом обчислення є 1. Логічна змінна b представлється в пам’яті як послідовність 0000 000012 = 0116. Займає 1 байт. Результат: 0116 Символьний тит unsigned char ch2 = ’o’; Змінна типу unsigned char зберігає ASCII код літери ’о’, який рівний 11110 = 0110 11112=6F16 і займає 1 байт пам’яті. Результат: 6F16 Цілий тип int i4 = -25 * 215; Результатом обчислення є число -537510 В пам’яті вонo буде збережене в оберненому доповняльному коді в зворотному порядку байт. -537510 = -14F116 = -0001 0100 1111 11112 Представимо число в оберненому доповняльному коді. 0000 0000 0000 0000 0001 0100 1111 1111 доповнюємо до 4 байт нулями  1111 1111 1111 1111 1110 1011 0000 0000 інвертуємо  1111 1111 1111 1111 1110 1011 0000 0001 додаємо 1  0000 0001 1110 1011 1111 1111 1111 1111 змінюємо порядок байт  01 EB FF FF Записуємо в 16 СЧ  Результат: 01 EB FF FF16 Дійсний тип double d2 = 275.25e+11; Представимо число в двійковому коді: 0001 1001 0000 1000 1010 1001 1101 1000 1111 0010 0000 0000, 0000 0000 0000 Переносимо кому до першої одиниці на 44 знаки ліворуч. 0001, 1001 0000 1000 1010 1001 1101 1000 1111 0010 0000 0000 0000 0000| 0000 Обчислюємо е: е = 1023 + 44. 01111111111 + 00000101100 10000101011 Звідси е = 10000101011 Число додатнє, отже s = 0. Мантиса m= 1001 0000 1000 1010 1001 1101 1000 1111 0010 0000 0000 0000 0000. Закрулення не змінює мантису. (53 біт = «0»). Запишемо число в вигляді таблиці: S E М  0 10000101011 1001 0000 1000 1010 1001 1101 1000 1111 0010 0000 0000 0000 0000  Переведемо шіснадцяткову систему числення: 42 B9 08 A9 D8 F2 00 00. Запишемо в оберненому порядку байт: 00 00 F2 D8 A9 08 B9 42. Результат: 00 00 F2 D8 A9 08 B9 4216 Завдання 2: Внутрішні формати похідних типів 3.2.1. Рядок символів char *string9 = "34\xe5\\\\\\v3\x4g5\xdfvdfw""""f"; Запишемо як виглядатиме рядок після перетворень string9[0] = '5'; string9[2] = '8'; string9[4] = '8'; string9[6] = '2'; string9[8] = '6'; string9[10] = '6'; string9[12] = '1'; string9[14] = '4'; Символи рядка зберігаються побайтно: кожен символ – один байт в такій самій послідовності що і в рядку. Тобто, щоб отримати представлення рядка в пам’яті комп’ютера треба кожен символ преставити 16-вим числом з таблиці ASCII. 5 – 35, 4 - 34, 8 - 38, \ - 5C, 8 - 38, \ - 5C, 2 - 32, 3 - 33, 6 - 36, g - 67, 6 - 36, ▀ - DF, 1 - 31, d -64, 4 - 34, w - 77, f - 66. Останньою буде записано ознаку кінця рядка 00. Результат: 35 34 38 5C 38 5C 32 33 36 67 36 DF 31 64 34 77 66 00 3.2.2. Перерахування Підрахуємо значення кожного члена переліку: BLUE = -2, отже GREEN=-1, CYAN=0, RED=1, BROWN=2, GRAY=9, YELLOW=10, WHITE= 11, MAGENTA=12, LIGHTGRAY=13, DARKGRAY=14, BLACK=15 Отже змінні матимуть значення c1=CYAN=0, c2=BROWN=2, c3=DARKGRAY=14 Кожен елемент більший від попереднього на 1. Якщо перший елемент не ініціалізований, тоді він приймає значення 0. Перерахування в пам’яті зберігається, як ціле число типу int. Число с1 = 0 Зберігатиметься в прямому коді, займатиме 4 байти. Число матиме значення 00. Результат: 00 00 00 0016 Число с2 = 2 Зберігатиметься в прямому коді, займатиме 4 байти. Число матиме значення 02. Доповнюємо його нулями до 4 байт (00 00 00 02) і обертаємо байти. Результат: 02 00 00 0016 Число с3 = 14 Зберігатиметься в прямому коді, займатиме 4 байти. Число матиме значення 0Е. Доповнюємо його нулями до 4 байт (00 00 00 0Е) і обертаємо байти. Результат: 0Е 00 00 0016 3.2.3. Масив unsigned short array11[][2][4] = {{2,2,232}, '2','/'} Після ініціалізації масив буде мати розмір 2 матриці по 2 рядки по 4 колонки. Числа {2,2,232} будуть записані в першій матриці а '2' = 5010,'/' = 4710 в другій. Решта елементів масиву будуть мати значення 0. Масив буде складатися з 2 матриць. 2 2 232 0  0 0 0 0  50 47 0 0  0 0 0 0   Далі виконуються наступні присвоювання. array11[0][0][0] = 0 * 25; //0 array11[0][0][1] = 9 * 25; //225 array11[0][0][2] = 5 * 25; //125 array11[0][0][3] = 8 * 25; //200 array11[0][1][0] = 8 * 25; //200 array11[0][1][1] = 2 * 25; //50 array11[0][1][2] = 6 * 25; //150 array11[0][1][3] = 6 * 25; //150 array11[1][0][0] = 1 * 25; //25 array11[1][0][1] = 4 * 25; //100 Після присвоювання масив набуде вигляду: 00 225 125 200  200 50 150 150  25 100 0 0  0 0 0 0   Перепишемо масив в 16-вій ситемі числення. 00 E1 7D C8  C8 32 96 96  19 64 00 00  00 00 00 00   Доповнимо масив до 2 байт нулями і обернемо їх порядок 0000 E100 7D00 C800  C800 3200 9600 9600  19 00 6400 0000 0000  00 00 0000 0000 0000   В пам’яті комп’ютера масив зберігається як послідовність чисел яка читається справа наліво і зверху вниз по матрицях масиву. Отже результатом є послідовність. Результат: 00 00 E1 00 7D 00 C8 00 C8 00 32 00 96 00 96 00 19 00 64 00 00 00 00 0 0 00 00 00 00 00 00 00 0016 3.2.4. Структура struct str3 { double a; unsigned e:6; int d; unsigned b:5; unsigned :3; char c[7]; wchar_t f; }str; str.a = 25.275; str.b = 9 * 1 * 124; str.c[0] = 'S'; str.c[1] = 'o'; str.c[2] = 'p'; str.c[3] = 'u'; str.c[4] = 's'; str.d = 764 * 9 * 8; str.e = 25 * 11 * 36; str.f = 4; Розгянемо як зберігається впам’яті кожен елемент структури. Структура, полям якої не присвоєно ніяких значень має всі байти однаковими і їх початковим значенням є число 11002 = С16, тому це може впливати на відображення певних бітових полів при виводі розміщення структури в пам’яті. double a = 25.27510 = 19.46666616= = 0001 1001. 0100 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 01102 Проводимо нормалізацію. Переносимо кому на 4 знаки ліворуч. 0001. 1001 0100 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110| 01102 Обчислюємо е: е = 1023 + 4. 01111111111 + 00000000100 10000000011 Звідси е = 10000000011 Число додатнє, отже s = 0. Мантиса m= 1001 0100 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110. Закрулення не змінює мантису. (53 біт = «0»). Запишемо число в вигляді таблиці: S E М  0 10000000011 1001 0100 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110  Переведемо шіснадцяткову систему числення: 40 39 46 66 66 66 66 66. Запишемо в оберненому порядку байт: 66 66 66 66 66 46 39 40. Результат: 66 66 66 66 66 46 39 4016 unsigned e:6; … str.e = 25 * 11 * 36; Даний елемент являє собою бітове поле, яке займає 6 біт в 4 байтах. Запишемо як буде виглядати поле після присвоювання. Обчислимо даний вираз: 25*11*36 = 26 АС16= 0010 0110 10|10 11002 Значущими будуть лише 6 молодших біт цього числа. Вони запишуться як молодші біти даного поля. Тобто 1100 1100 1100 1100 1100 1100 11|10 11002. В шіснадцятковій системі запишемо. СС СС СС ЕС16. Обернемо порядок байт: ЕС СС СС СС16. Результат: ЕС СС СС СС16. int d = 764 * 9 * 8 = 5500810 = D6 E016 В пам’яті число буде збережене в прямому коді в оберненому порядку байт. Для представлення числа в пам’яті доповнимо його до 4 байт (00 00 D6 E0) і обернемо байти (E0 D6 00 00) Результат: E0 D6 00 0016 unsigned b:5; unsigned :3; … str.b = 9 * 1 * 124; Даний рядки являють собою бітове поле, яке займає 5 і 3 біти в 4 байтахті. Запишемо як будуть виглядати поля після присвоювання. Обчислимо даний вираз: 9*1*124 = 111610 = 45С16 = 0100 010|1 11002. Значущими будуть лише 5 молодших біт цього числа. Тобто 1100 1100 1100 1100 1100 1100 110|1 11002. В шіснадцятковій системі запишемо. СС СС СС DС16. Наступні 3 біти непідписаного поля не використовуються і будуть мати те значення яке було в них записано при ініціалізації структури. Вони запишуться як молодші біти даного поля. Обернемо порядок байт поля: DС СС СС СС16. Результат: DС СС СС СС16. char c[7]; … str.c[0] = 'S'; str.c[1] = 'o'; str.c[2] = 'p'; str.c[3] = 'u'; str.c[4] = 's'; Кожен елемент масиву буде займати 1 байт пам’яті. Разом 7 байт. В масиві послідовно будуть записані 16-ві значення символів з таблички ASCII. ('S' – 53, 'o' - 6F, 'p' – 70, 'u' – 75, 's' – 73) Решта елементів будуть неініціалізовані і матимуть значення СC16=1100 11002. Результат: 53 6F 70 75 73 CC CC16. wchar_t f; … str.f = f; Тип wchar_t займає 2 байти пам’яті. Число 4 представляється в прямому коді. 410=01002. Доповнимо число до 2 байт нулями(00 04) і обернемо їх порядок (04 00). Результат: 04 0016. Тепер маючи значення усіх елементів структури можна записати її предсталення в пам’яті. Найдовшим елементом буде число типу double. Тому довжина структури кратна 8 байтам і дорівнює 32 байти. Число типу double. Перше бітове поле Число типу int. Два наступні бітові поля. Масив символів. Вирівнювання по довжині півслова. Число типу wchar_t Вирівнювання по довжині найбільшого елемента. 3.2.5. Об’єднання union un20{ int b; struct{ char c; double e; }; struct{ double f; char a[10]; }; }un; un.e = 1 * 325 + 1991 * 25; un.c = 25 * (11 + 9) * 100; un.a[0] = '2'; un.a[1] = '6'; un.a[2] = '6'; un.a[3] = '1'; un.a[4] = '4'; Обчислимо значення найдовшого елемента об’єднання. іnt b – 4 байти; перша структура займатиме 16 байт (сhar c займає 1 байт, плюс 7 байт вирівнювання до типу double, a double e займає 8 байт) Друга структура займатиме 24 байта пам’яті(double f – 8 байт, char a[10] – 10 байт, ще 6 байт буде займати вирівнювання до числа 24, яке кратне розміру найдовшого елемента структури, тобто кратне 8). Звідси - найдовшим елементом об’єднання є друга структура, отже об’єднання буде займати 24 байта пам’яті. Дані в даному об’днанні можуть зберігатися за трьома схемами розміщення. Покажемо представлення в пам’яті всього об’єднання і кожного елемента зокрема: int b; Число int Біти не використовуються struct{ char c; double e; }; Число сhar Вирівнювання по довжині подвійного слова Число double Біти не використовуються struct{ double f; char a[10]; }; Число double Масив сhar[10] Вирівнювання по довжині найдовшого елемента. При першому присвоюванні un.e = 1 * 325 + 1991 * 25; В 24 байта пам’яті запишеться число типу double по другій схемі (в третьому проміжку). Решта байт залишаться без змін. 1 * 325 + 1991 * 25 = 5010010 = С3B416 = =1100 0011 1011 0100. 0000 0000 0000 0000 0000 0000 0000 0000 0000 00002 Проводимо нормалізацію. Переносимо кому на 15 знаки ліворуч. 1.100 0011 1011 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0|0002 Обчислюємо е: е = 1023 + 15. 01111111111 + 00000001111 10000001110 Звідси е = 10000001110 Число додатнє, отже s = 0. Мантиса m= 100 0011 1011 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0. Закрулення не змінює мантису. (53 біт = «0»). Запишемо число в вигляді таблиці: S E М  0 10000001110 1000 0111 0110 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000  Переведемо шіснадцяткову систему числення: 40 E8 76 80 00 00 00 00. Запишемо в оберненому порядку байт: 00 00 00 00 80 76 E8 40. Результат: CC CC CC CC CC CC CC CC 00 00 00 00 80 76 E8 40 CC CC CC CC CC CC CC CC16 При другому присвоюванні un.c = 25 * (11 + 9) * 100; В 24 байта пам’яті запишеться число типу char по другій схемі (в першому проміжку). Решта байт залишаться без змін. 25 * (11 + 9) * 100 = 5000010 = С35010. Беремо 1 молодший байт і записуємо його в пам’ять. Результат: 50 CC CC CC CC CC CC CC 00 00 00 00 80 76 E8 40 CC CC CC CC CC CC CC CC16 При записі масиву в пам’ять значення елементів записуються послідовно за третьою схемою в другому проміжку. Значення елементів масиву ('2' - 3216, '6'- 3616, '6' - 3616, '1'- 3116, '4'- 3416) Результат: 50 CC CC CC CC CC CC CC 32 36 36 31 34 76 E8 40 CC CC CC CC CC CC CC CC16 Результати виконання програми  Висновки Виконуючи дану розрахункову роботу я засвоїв принципи збереження основних базових і похідних типів даних. Розглянув представлення логічного, символьного, цілого, дійсного типу даних, також розглянув представлення таких похідних типів як рядки символів, переліки, масиви, структури і об’єднання. Закріпив знання про представлення типів в пам’яті комп’ютера. Список літератури Б.Керниган, Д. Ритчи “Язык программирования Си”. Москва “Финансы и статистика”, 1992 Ч.Уэзерелл “Этюды для программистов”. М. Мир, 1982 Б.Керниган, Ф.Плоджер “Элементы стиля программирования”, М.”Радио и связь”, 1984 Ф.П.Брукс мл. “Как проектируются и создаются программные комплексы”, М. “Наука”, 1979 Ч. Петзолд “Программирование для Windows 95 в двух томах”, BHV, 1996 Трамбле Ж., Соренсон П. Введение в структуры данных. – М.:Машиностроение, 1982 Уильям Топп, Уильям Форд. Структуры данных в С++. – М.:Бином, 2000 - 700 с Додатки Текст програми //-------------------------------- Main.cpp --------------------------------- #include "Data.h" void main() { char key = 0; //клавіша PrintMenu(); //початковий меню //Даний цикл призначений для реагування на натискання //клавіш, Esc для виходу. while(key != 0x1b){ //0x1b 16-вий код клавіші Esc key = getch(); switch (key){ //При натисканні '1' виводиться тип bool case 0x31: PrintMenu(); Bool(); break; //При натисканні '2' виводиться тип char case 0x32: PrintMenu(); Char(); break; //При натисканні '3' виводиться тип int case 0x33: PrintMenu(); Int(); break; //При натисканні '4' виводиться тип double case 0x34: PrintMenu(); Double(); break; //При натисканні '5' виводиться рядок case 0x35: PrintMenu(); String(); break; //При натисканні '6' виводиться перелік case 0x36: PrintMenu(); Enum(); break; //При натисканні '7' виводиться масив
Антиботан аватар за замовчуванням

13.05.2013 21:05-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!