Міністерство освіти і науки України
Національний університет „Львівська політехніка”
Старий
Кафедра ЕОМ
Звіт
з лабораторної роботи №2
з дисципліни
"Програмування. Частина III.
Структури даних та алгоритми"
Варіант:
RN = 1992
MN = 11 % 8 = 3
DN = 11
mn = 03
dn = 11
Pr1 = №(D) = 68
рr2 = №(a) = 97
рr3 = №(s) = 115
Львів
2012
1. Мета роботи: Дослідження методів та засобів явного і неявного перетворення типів даних.
2. Постановка задачі:
Завдання 1. Неявні перетворення типів даних
char x0 = 0x1992 - 10;
float x1;
unsigned short x2 = 03;
short x3 = 68 - 110;
bool x4 = 11 % 3 * 10;
x1 = x0 + x2 + x4 + 0Х123;
x2 = x2 + x3 - 0123;
x3 = x1 + x2 * 0.123 + ’1’;
Завдання 2. Явні перетворення типів даних
const int x_0=11*3*100 = 3300;
const int x_1= 011030;
const int x_2= 0x1103;
const int x_3= 003110;
const int x_4= 0x0311;
const double y_0=11*3/100 = 0,33;
const double y_1= - 11.3;
const double y_2= 3.11e+2;
const double y_3= - 11.3e1;
const double y_4= - 3.11e-1;
int x = х_1;
double y = y_3;
float v1 = static_cast< float > (x);
char v2 = static_cast<char> (x);
float v3 =*reinterpret_cast<float*> (&x)+1;
char v4 =*(reinterpret_cast<char*> (&x)+2)+3;
int w1 = static_cast<int>(y)+0X0E2;
long w2 =*reinterpret_cast<long*>(&y)+1;
short w3 =*(reinterpret_cast<short*>(&y)+2);
char w4 =*(reinterpret_cast<char*>(&y)+7)+3;
3. Система тестів:
3.1. Неявні перетворення типів даних:
1) x1 = x0 + x2 + x4+0Х123;
2) x2 = x2 + x3 - 0123;
3) x3 = x1 + x2 * 0.123 + ’1’;
3.2 Явні перетворення типів даних:
1) float v1 = static_cast<float> (x);
2) char v2 = static_cast<char> (x);
3) float v3 =*reinterpret_cast<float*> (&x)+1;
4) char v4 =*(reinterpret_cast<char*> (&x)+2)+3;
5) int w1 =static_cast<int>(y)+0X0E2;
6) long w2 =*reinterpret_cast<long*>(&y)+1;
7) short w3 =*(reinterpret_cast<short*>(&y)+2);
8) char w4 =*(reinterpret_cast<char*>(&y)+7)+3;
Завдання 1.1
char x0 = 0x1992 - 10;
float x1;
unsigned short x2 = 03;
short x3 = 68 - 110;
bool x4 = 11 % 3 * 10;
Обчислимо значення виразу: x1 = x0 +x2 + x4 + 0х123;
Оскільки в арифметичному виразі х1 в нас є операнди різного типу, то згідно правил неявного перетворення типів всі типи переводяться до типу операнда розмір якого є найбільшим.
0x123 – це константа, а константи в мові С++ зберігаються в типі int. Отже, в даному виразі int є операнд найбільшого розміру, тому x0(char), x2(unsigned shor) та x4(bool) будуть неявно переведені до типу int.
Результуючим типом буде тип об’єкта якому присвоюється значення, тому після виконання операцій, які знаходяться ліворуч від символа присвоєння результат їхнього типу буде переведено в тип операнда якому присвоюється значення, а саме float (x1).
char x0 = 0x1992 - 10; // Переводимо в тип int вираз, що знаходиться ліворуч, а потім результат в тип char
Для виразу ліворуч при ініціалізації:
199216 - 1010 = 654610 - 1010 = 653610
Число: 653610 = 00 00 19 8816
ВПК(int): 88 19 00 00
Результат присвоєння змінній х0:
ВПК(char): 88
Змінна х0 переведена в тип int:
ВПК(int): 88 FF FF FF
FF FF FF 8816 = 1111 1111 1111 1111 1111 1111 1000 10002
1111 1111 1111 1111 1111 1111 1000 1000 – доповняльний
0000 0000 0000 0000 0000 0000 0111 0111 – обернений
Модуль числа: 00 00 00 7716 = 11910
Число х0 в типі int: - 11910
unsigned short x2 = 03;
ВПК(short):03 00
ВПК(int):03 00 00 00
Згідно неявного перетворення:
Число х2 в типі int: 310
bool x4 = 11 % 3 * 10; // 11%3 =2
x4 = 2;
ВПК(bool): 02
ВПК(int): 02 00 00 00
Число х4 в типі int: 210
0x123 = 12316 = 29110
x1 = x0 + x2 + x4 + 0x123 = -119 + 3 + 2 + 291 = 175
Відповідь: x1 = 175.0
Завдання 1.2
char x0 = 0x1992 - 10;
float x1;
unsigned short x2 = 03;
short x3 = 68 - 110;
bool x4 = 11 % 3 * 10;
Обчислимо значення виразу: x2 = x2 + x3 - 0123;
В виразі праворуч типу операнда розмір якого найбільший є int (константа 0123), тому x2 та x3 будуть переведені до int. Результат обчислення буде переведено до операнду якому присвоюється вираз, а саме unsigned short
unsigned short x2 = 03;
ВПК(short):03 00
ВПК(int):03 00 00 00
Згідно неявного перетворення:
Число х2 в типі int: 310
short x3 = 68 - 110;
Згідно правил неявного перетворення
Число х3 в типі int: -4210
Число 1238 в типі int: 8310
Обчислюємо значення виразу: x2 = x2 + x3 – 0123
x2 + x3 – 0123 = 3 – 42 – 83 = - 122 (int) // Результат виразу який присвоюється x2
Результуючим типом буде тип об’єкта якому присвоюється значення, тому -122(int) потрібно перевести в (x2)unsigned short:
Модуль числа 12210 = 7A16
Прямий код: 00 00 00 7A16
0000 0000 0000 0000 0000 0000 0111 1010
1111 1111 1111 1111 1111 1111 1000 0101
__________________________________1
1111 1111 1111 1111 1111 1111 1000 0110
F F F F F F 8 6
ВПК(int): 86 FF FF FF
ВПК(unsigned short): 86 FF
Число: FF 8616 = 6541410
Відповідь: x2 = 65414
Завдання 1.3
char x0 = 0x1992 - 10;
float x1;
unsigned short x2 = 03;
short x3 = 68 - 110;
bool x4 = 11 % 3 * 10;
Обчислимо значення виразу: x3 = x1 + x2 * 0.123 + ’1’;
В виразі праворуч типу операнда розмір якого найбільший є float), тому x1,x2 та ‘1’ будуть переведені до float. Результат обчислення буде переведено до операнду x3 якому присвоюється вираз, а саме short
З попереднього обчислення float x1 = -175.0;
unsigned short x2 = 65414 // Переводимо в тип double
Згідно правил неявного переведення типу:
Число х2 в типі double: 65414.0
Символ ‘1’ потрібно перевести в тип float:
Згідно таблиці ASSCI ‘1’ дорівнює 49
Константа символ „1” в типі double матиме значення 49.0
Підставляємо відповідні значення в вираз:
175.0 + 65414 * 0.123 + 49.0 = 175 + 8045.922 + 49.0 = 8269.922;
В результаті присвоювання і переведення числа в тип short результат буде ціла частина числа: x3 = 8269
Відповідь: x3 = 8269
Завдання 2.1
Обчислимо значення виразу: float v1 = static_cast<float> (x);
Використовуючи оператор явного перетворення static_cast можливі ті перетворення, які можуть бути виконані неявно на основі правил за замовчуванням, але в цьому випадку компілятор не видасть попередження про втрату точності:
const int x_1= 011030;
int x = x_1;
float v1 = static_cast<float> (x);
Цей оператор є альтернативою неявного перетворення, оскільки він узгоджується з правилами неявного перетворення, тому результат для змінної v1 буде:
1103016 = 463210
Відповідь: 4632.0
Завдання 2.2
Обчислимо значення виразу: char v2 = static_cast<char> (x);
int x = x_1; // x = 463210
463210 =121816
Число x: 00 00 12 18
ВПК (х): 18 12 00 00 // int
ВПК(v2): 18 // беремо 1 байт для типу char
1816=2410
Відповідь: в таблиці ASCIIпід номером 24 знаходиться символ ↑
Завдання 2.3
const int x_2= 0x1205;
int x = х_2;
Обчислимо значення виразу: float v3 =*reinterpret_cast<float*> (&x)+1;
В даному випадку відбувається збільшення отриманого числа на 1, а не зсув адреси:
ВПК типу int (х): 18 12 00 00
ВПК типу float: 18 12 00 00
Число: 00 00 12 1816 = 0000 0000 0000 0000 0001 0010 0001 10002
s = 0
e = 0
m = 000 0000 0001 0010 0001 1000
Значення числа: 1. 000 0000 0001 0010 0001 1000* 2-127 = 0
До отриманого значення додаємо 1.
Відповідь: v3 = 1.0
Завдання 2.4
…
const int x_2= 0x1103;
int x = х_2;
…
Обчислимо значення виразу: char v4 =*(reinterpret_cast<char*> (&x)+2)+3;
В даному випадку відбувається зсув адреси на 2 одиниці типу char та збільшення числа на 3:
ВПК типу int(х): 18 12 00 00
ВПК для reinterpret_cast<char*> (&x)+2: 00;
ВПК типу char (v4): 03; // До попереднього значення додаємо 3
Відповідь: В ASCII таблиці число 03 відповідає символу v4 = ♥
Завдання 2.5
…
const double y_3=-11.3e1;
double y = y_3;
…
Обчислимо значення виразу: int w1 = static_cast<int>(y)+0x0E2;
Переводимо змінну y яка є типу double в тип int за допомогою правил неявного переведення типу, оскільки використовуємо оператор static_cast:
Значення double y = -113 в типі int її значення буде -113
До попереднього значення додаємо константу 0х0Е216 = 22610
Отож, -11310 + 22610 = 11310
Відповідь: w1= 113
Завдання 2.6
long w2 =*reinterpret_cast<long*>(&y)+1
const double y_3= - 11.3e1;
- 11310 = - 7116 =-1110 001
s =1
m =1110 001.0
Нормалізація мантиси
1. 110 001 * 10110
e = 102310 + 610 =102910 = 100 0000 01012
s
e
m
1
100 0000 0101
1100 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
В 16-ій формі : C0 5С 40 00 00 00 00 00
ВПК(double) : 00 00 00 00 00 40 5С C016
ВПК(long):00 00 00 0016
Число : 0000 0000 0000 0000 0000 0000 0000 00002
Оскільки 1-ий біт 1-го байту числа є 0, то це означає що число є додатне, а отже представлене в прямому коді, тому виконуємо переведення:
00 00 00 0016 = 010
Тепер до отриманого числа 0 додаємо 1 і отримуємо результат для змінної w2:
Відповідь: w2 = 1
Завдання 2.7
short w3 =*(reinterpret_cast<short*>(&y)+2);
double y = y_3;
const double y_3= - 11.3e1;
З попередніх обчислень число double y в ВПК: 00 00 00 00 00 40 5С C016
short в ВПК займає 2 байти, зсунути на 2 одиниці типу short означає зсунути на 4 байти, тому
в-дь буде:
ВПК short: 00 4016
Число :0100 0000 0000 0000
Оскільки число відємне то потрібно робити інверсію і додати одиницю
4000 16 =1638410
Відповідь : w3 = 1638410
Завдання 2.8
Обчислимо значення виразу: char w4 =*(reinterpret_cast<char*>(&y)+7)+3;
const double y_3=-11.3e1;
double y = y_0;
З попередніх обчислень число double y в ВПК: 00 00 00 00 00 40 5C C016
char в ВПК займає 1 байт, зсунути на 7 одиниць типу char означає зсунути на 7 байти, тому в-дь буде:
ВПК char: C016
Число: C0 16 = 19210
Тепер до даного числа необхідно додати 3:
19210 + 310 = 19510
Відповідь: char w4 = 195, в таблиці ASCII кодів це символ ├
4. Результати виконання програми:
/
/
Висновки:
Ознайомившись з теоретичним матеріалом даної лабораторної роботи, а також застосувавши його на практиці я зрозумів явне та неявне перетворення типів даних в комп’ютері.
Додатки:
Програма для завдання 1:#include <stdio.h> // Підключаємо відповідні бібліотеки
#include <conio.h>
void main (void){
char x0 = 0x1992 - 10;
float x1;
unsigned short x2 = 03;
short x3 = 68 - 110;
bool x4 = 11 % 3 * 10;
float x5;
x1 = x0 + x2 + x4 + 0x123;
x2 = x2 + x3 - 0123;
x3 = x1 + x2 * 0.123 + '1';
x5 = x1 + x2 * 0.123 + '1';;
printf("x1 = %f\n",x1);
printf("x2 = %d\n",x2);
printf("x3 = %d\n",x3);
getch();
}
Програма для завдання 2:#include <stdio.h> // Підключаємо відповідні бібліотеки
#include <conio.h>
#include <math.h>
void main (void){
const int x_0=11*3*100;
const int x_1= 011030;
const int x_2= 0x1103;
const int x_3= 003110;
const int x_4= 0x0311;
const double y_0 = 11*3/100;
const double y_1= - 11.3;
const double y_2= 3.11e+2;
const double y_3= - 11.3e1;
const double y_4= - 3.11e-1;
int x = x_1;
double y = y_3;
float v1 = static_cast< float > (x);
char v2 = static_cast<char> (x);
float v3 =*reinterpret_cast<float*> (&x)+1;
char v4 =*(reinterpret_cast<char*> (&x)+2)+3;
int w1 = static_cast<int>(y)+0X0E2;
long w2 =*reinterpret_cast<long*>(&y)+1;
short w3 =*(reinterpret_cast<short*>(&y)+2);
char w4 =*(reinterpret_cast<char*>(&y)+7)+3;
printf ("v1 = %f\n", v1);
printf ("v2 = %c\n", v2);
printf ("v3 = %f\n", v3);
printf ("v4 = %c\n", v4);
printf ("w1 = %d\n", w1);
printf ("w2 = %d\n", w2);
printf ("w3 = %d\n", w3);
printf ("w4 = %c\n", w4);
unsigned char *vi1=(unsigned char *)(&y); /* За допомогою вказівника отримуємо адресу на комірку пам’яті де записана відповідна змінна */
printf("i1 = ");
for (int i=0;i<sizeof(y);i++)
printf("%02X ",vi1[i]);
getch();
}