МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
/
Кафедра ЕОМ
" Перетворення типів даних"
ЗВІТ
до лабораторної роботи № 3
з
"Програмування. Частина III.
Структури даних та алгоритми"
МЕТА РОБОТИ
Дослідження методів та засобів явного та неявного перетворення типів даних.
ВИБІР ІНДИВІДУАЛЬНОГО ЗАВДАННЯ
Завдання 1:
Визначити, які неявні перетворення типів будуть відбуватись при обчисленнях. З’ясувати, чи відбудуться втрати значимості даних. Хід міркувань підтвердити програмними результатами. В звіти пояснити кожне перетворення і метод, яким воно здійснено.
typedef unsigned int type_0;
typedef unsigned short int type_1;
typedef unsigned long int type_2;
typedef signed short int type_3;
typedef signed int type_4;
typedef signed long int type_5;
typedef bool type_6;
typedef char type_7;
typedef wchar_t type_8;
typedef float type_9;
typedef double type_10;
typedef long double type_11;
// позначимо через DN=6 - день народження, MN=2 – місяць народження
type_6 x0=0; // замість № підставити значення: DN % 9
type_0 x1=6; // замість № підставити значення: DN % DN
type_2 x2=2; // замість № підставити значення: MN % 9
type_2 x3=3; // замість № підставити значення: MN % 13
type_3 x4=4; // замість № підставити значення: (DN * MN) % 9
type_6 x5=5; // замість № підставити значення: DN % 12
type_2 x6=6; // замість № підставити значення: MN % 3
type_0 x7=7; // замість № підставити значення: (DN * MN) % 12
type_6 x8=8; // замість № підставити значення: DN % 13
type_2 x9=9; // замість № підставити значення: MN % 6
type_2 x10=10; // замість № підставити значення: (DN * MN) % 10
type_0 x11=11; // замість № підставити значення: DN % 3
/* 1 */ x1 = x1 – 0xFFFFFFFA;
/* 2 */ x3 = ’a’ + x0 – x2;
/* 3 */ x7 = x4 + x5 + x6 * 0.1;
/* 4 */ x8 = x9 + x10 – x11*10;
1) x1 = x1 – 0xFFFFFFFA
x1 має тип unsigned int
0xFFFFFFFA неявно приводиться до типу unsigned int
x1 = 610 = 616
0xFFFFFFFA = 429496729010 = FF FF FF FA16
x1 = 610 - 0xFFFFFFFA16 = 610 – 429496729010 = -429496728410
При відніманні утвориться від’ємне число. Unsigned не може мати від’ємних значень, тому у пам’яті число буде зберігатися у доповняльному коді.
-429496728410 =111111111111111111111111111101002(прямий код)= 0000 0000 0000 0000 0000 0000 0001 01002(доповняльний)= - FF FF FF FF16(прямий) = 00 00 00 14(доповняльний)16 = 2010
2) x3 = ’a’ + x0 – x2
x2, x3 – unsigned long int
’a’ – char
x0 – signed int
‘a’ неявно приводиться до типу x0 (‘a’ = 9710 x0 = 010): 97 + 0 = 9710
x2 неявно приводиться до типу x0. (x2 =210): 97 - 2 = 9510
Після цього значення виразу присвоюється змінній x3(unsigned long int), тому в даному випадку значення не зміниться, але у випадку чисел величини більшої ніж допустима для int втрачається точність.
х3 = 9510
3) x7 = x4 + x5 + x6 * 0.1
х4 – signed short int
x7 – unsigned int
x6 – unsigned long int
x5 - bool
x6 неявно приводиться до типу double: 6 * 0.1 = 0.6
x5 неявно приводиться до типу x4(signed short int): 4 + 1 = 5
значення виразу x4+x5 неявно приводиться до типу виразу x6*0.1 (double): 5 + 0.6 = 5.6
Після цього значення виразу присвоюється змінній x7(unsigned int), тому значення виразу буде заокругленим та буде дорівнювати 5.
x7 = 510
4) x8 = x9 + x10 – x11*10
x8 – bool
x9, x10 – unsigned long int
x11 – unsigned int
10 набуває типу unsigned int(x11), результат x9 + x10 -> unsigned long int, тоді: 9 + 10 – 11*10 = -91
При відніманні утвориться від’ємне число. Unsigned не може мати від’ємних значень, тому у пам’яті буде зберігатися у доповняльному коді.
Тоді значенням виразу буде: 4294967205 (FF FF FF A5)
Після цього змінна x8(bool) отримає це значення та приведе його у bool і буде дорівнювати:
x8 = 110
Завдання 2
Визначити, які явні і неявні перетворення типів будуть відбуватись. Результати обчислень підтвердити програмними результатами. В звіти пояснити кожне перетворення і кожний отриманий результат.
(місяць народження студента) % 4 = 2 % 4 = 2
(день народження студента) % 4 = 6 % 4 = 2
Завдання до (2,2) варіанту: Вибрати назви змінних для дослідження в завданні 2 згідно з варіантом з таблиці: v2 ,v6, w4, w1
const int x_4= 0x0814;
const double y_2= 08. 14 e +2
int x = х_4;
double y = y_2;
char v2 = *reinterpret_cast<char*> (&x) + 1;
Оператор reinterpret_cast працює з внутрішніми представленями об’єктів, причому правильність даної операції цілком залежить від програміста.
Адреса змінної х приводиться до типу вказівника на тип char.(розіменування вказівника):
x типу int приводиться до x типу char
До вказівника додається 1, тобто тепер він вказує не на перший байт, а на третій
При присвоєнні змінній v2 значення після дорівнює:
Типу char
При виведенні на екран, у випадку %d(десяткове ціле число зі знаком) v2(char) -> v2(int) та у випадку %x(шістнадцяткове ціле число без знаку) v2(char) -> v2(unsigned int). У випадку %c(символ типу char) змінна v2 виводиться на екран без змін.
printf("%d %x %c \n", v2, v2, v2);
char v6=*reinterpret_cast<char*> (&x)+2) +22;
printf("%d %x %c \n", v6,v6,v6);
Оператор reinterpret_cast працює з внутрішніми представленями об’єктів, причому правильність даної операції цілком залежить від програміста.
Адреса змінної х приводиться до типу вказівника на тип char.(розіменування вказівника):
x типу int приводиться до x типу char
До вказівника додається 2, тобто тепер він вказує не на перший байт, а на четвертий
Далі додаємо x(char) та 22(int)
Тип char приводиться до типу int
При присвоєнні змінній v6 значення після дорівнює:
Тип int приводиться до типу char
*reinterpret_cast<char*> (&x+2) + 22
При виведенні на екран, у випадку %d(десяткове ціле число зі знаком) v6(char) -> v6(int) та у випадку %x(шістнадцяткове ціле число без знаку) v6(char) -> v6(unsigned int). У випадку %c(символ типу char) змінна v6 виводиться на екран без змін.
printf("%d %x %c \n", v6, v6, v6);
short w4=*(reinterpret_cast<short*>(&y)+1)+11;
Адреса змінної y приводиться до типу вказівника на тип short.(розіменування вказівника)
До вказівника додається 1, тобто тепер він вказує не на перший байт, а на третій. Далі виконуємо додавання y(short)+11(int), y(short) приводиться до типу int, після цього результат приводиться до типу short і присвоюється змінні w4(short).
При виведенні на екран, у випадку %x(шістнадцяткове ціле число без знака) та у випадку %u(десяткове ціле число без знаку) w4(short) -> w4(unsigned short). У випадку %d(десяткове ціле число зі знаком) змінна w4 виводиться на екран без змін.
printf("%x %u %d \n", w4,w4,w4);
long w1 = *reinterpret_cast<long*>(&y) + 33;
Адреса змінної y приводиться до типу вказівника на тип long.(розіменування вказівника)
Далі виконуємо додавання y(long)+33(int), 33(int) приводиться до типу long, після цього результат приводиться до типу long і присвоюється змінні w1(long).
При виведенні на екран, у випадку %x(шістнадцяткове ціле число без знака) та у випадку %u(десяткове ціле число без знаку) w1(long) -> w1(unsigned short). У випадку %d(десяткове ціле число зі знаком) змінна w1 виводиться на екран без змін.
Код програми:
#include <iostream>
#include<conio.h>
using namespace std;
void main()
{
/*
Завдання 1
*/
typedef unsigned int type_0;
typedef unsigned short int type_1;
typedef unsigned long int type_2;
typedef signed short int type_3;
typedef signed int type_4;
typedef signed long int type_5;
typedef bool type_6;
typedef char type_7;
typedef wchar_t type_8;
typedef float type_9;
typedef double type_10;
typedef long double type_11;
type_6 x0 = 0;
type_0 x1 = 14;
type_2 x2 = 2;
type_2 x3 = 3;
type_3 x4 = 4;
type_6 x5 = 5;
type_2 x6 = 6;
type_0 x7 = 7;
type_6 x8 = 8;
type_2 x9 = 9;
type_2 x10 = 10;
type_0 x11 = 11;
x1 = x1 - 0xFFFFFFFA;
x3 = 'a' + x0 - x2;
x7 = x4 + x5 + x6 * 0.1;
x8 = x9 + x10 - x11 * 10;
cout << "x1 = " << x1 << endl;
cout << "x3 = " << x3 << endl;
cout << "x7 = " << x7 << endl;
cout << "x8 = " << x8 << endl;
cout << "======================================Task2====================================="<<endl;
/*
Завдання 2
*/
const int x_1 = 006020;
const double y_2 = 02.06e+2;
int x = x_1;
double y = y_2;
char v2 = *reinterpret_cast<char*> (&x) + 1;
printf("%d %x %c \n", v2, v2, v2);
char v6 = *(reinterpret_cast<char*> (&x) + 2) + 22;
printf("%d %x %c \n", v6, v6, v6);
long w1 = *reinterpret_cast<long*>(&y) + 33;
printf("%lx %lu %ld \n", w1, w1, w1);
short w4 = *(reinterpret_cast<short*>(&y) + 1) + 11;
printf("%x %u %d \n", w4, w4, w4);
system("pause");
}
Скріншот виконання:
Висновок
У цій лабораторній роботі проводилося дослідження методів та засобів явного та неявного перетворення типів даних.