Перетворення типів при присвоюванні
В операціях присвоювання тип значення, що присвоюється, перетворюється до типу змінної, що одержує це значення. У мові С++ допускаються перетворення при присвоюванні між цілими і дійсними типами, навіть у випадку, коли перетворення спричиняє втрату інформації.
Перетворення знакових цілих типів.
Методи виконання перетворень залежать від типів. Наприклад, знакове ціле (sіgned іnt) перетворюється до короткого знакового цілого (short sіgned іnt) за допомогою усікання старших бітів. Коротке знакове ціле (short sіgned іnt) перетворюється до довгого знакового цілого (long sіgned іnt) шляхом розмноження знака вліво. Перетворення знакових цілих (sіgned іnt) до дійсних величин, відбувається без втрати інформації, за винятком можливої втрати деякої точності, коли перетворюються величини long у float. При перетворенні знакового цілого (sіgned іnt) до беззнакового цілого (unsіgned іnt), знакове ціле перетворюється до розміру беззнакового цілого і результат інтерпретується як беззнакова величина.
Таблиця 6.1.
Перетворення | Метод | |
з типу | в тип | |
char | short | доповнення знаком |
char | long | доповнення знаком |
char | unsigned char | збереження бітів, старший біт втрачає функцію знакового біта |
char | unsigned short | доповнення знаком до short, перетворення short в unsigned short |
char | usigned long | доповнення знаком до long, перетворення long в unsigned long |
char | float | доповнення знаком до long, перетворення long в float |
char | double | доповнення знаком до розміру double, перетворення в double |
short | char | збереження молодшого байта |
short | long | розмноження знака |
short | unsigned char | збереження бітів молодшого байта, старший біт втрачає функцію знакового біта |
short | unsigned long | доповнення знаком до long, перетворення long в unsigned long |
short | unsigned short | збереження бітів, старший біт втрачає функцію знакового біта |
short | float | доповнення знаком до long, перетворення long к float |
short | double | доповнення знаком до розміру double, перетворення в double |
long | char | збереження молодшого байта |
long | short | збереження двох молодших байтів |
long | unsigned char | збереження бітів молодшого байта, старший біт втрачає функцію знакового біта |
long | unsigned short | збереження двох молодших байтів, старший біт втрачає функцію знакового біта |
long | unsigned long | збереження бітів, старший біт втрачає функцію знакового біта |
long | float | представляється як float, якщо long не може бути представлене точно, то відбувається деяка втрата точності |
long | double | представляється як double, якщо long не може бути представлене точно, то відбувається деяка втрата точності |
Зауваження: тип іnt еквівалентний або типові short, або типові long у залежності від реалізації. Перетворення значень типу іnt відбувається як для типу short або як для типу long, в залежності від того, що підходить.
Перетворення беззнакових цілих типів.
Беззнакове ціле перетворюється до короткого беззнакового або знакового цілого шляхом усікання старших бітів. Беззнакове ціле перетвориться до довгого беззнакового або знакового цілого шляхом розмноження нуля. Беззнакові цілі перетворюється до дійсних величин шляхом перетворення до найближчого знакового цілого того ж самого розміру, а потім перетворення цієї знакової величини до дійсної величини. Коли беззнакове ціле перетвориться до знакового цілого того ж розміру, то стан бітів не міняється. Однак, значення цього представлення зміниться, якщо був встановлений знаковий біт.
Таблиця 6.2.
Перетворення | Метод | |
з типу | в тип | |
unsigned char | chart | збереження всіх бітів, старший біт стає знаковим |
unsigned char | short | доповнення нулем |
unsigned char | long | доповнення нулем |
unsigned char | unsigned short | доповнення нулем |
unsigned char | unsigned long | доповнення нулем |
unsigned char | float | перетворення до long, перетворення long в float |
unsigned char | double | перетворення до long, перетворення long в double |
unsigned short | char | збереження молодшого байта |
unsigned short | short | збереження всіх бітів, старший біт стає знаковим |
unsigned short | long | доповнення нулем |
unsigned short | unsigned char | збереження молодшого байта |
unsigned short | unsigned long | доповнення нулем |
unsigned short | float | перетворення до long, перетворення long в float |
unsigned short | double | перетворення до long, перетворення long в double |
unsigned long | char | збереження молодшого байта |
unsigned long | short | збереження двох молодших байтів |
unsigned long | long | збереження всіх бітів, старший біт стає знаковим |
unsigned long | unsigned char | збереження молодшого байта |
unsigned long | unigned short | збереження двох молодших байтів |
unsigned long | float | перетворення до long, перетворення long в float |
unsigned long | double | перетворення до long, перетворення long в double |
Зауваження: тип unsigned int еквівалентний або типові unsigned short, або типові unsigned long у залежності від реалізації. Перетворення значень типу unsigned іnt відбувається як для типу unsigned short або як для типу unsigned long, в залежності від того, що підходить.
Перетворення дійсних типів
Величина float перетворюється до double, не міняючись у значенні. Величини double, перетворені до float, представляються точно, якщо це можливо. Якщо значення занадто велике для float, то точність губиться. Дійсні типи перетворюються до цілих типу long. Перетворення до інших цілих типів виконується як для long. Дробова частина дійсної величини відкидається при перетворенні до long; якщо результат занадто великий для long, то результат перетворення невизначений.
Таблиця 6.3.
Перетворення | Метод | |
з типу | в тип | |
float | char | перетворення до long, перетворення long в char |
float | short | перетворення до long, перетворення long в short |
float | long | усікання дробової частини; результат невизначений, якщо він занадто великий для представлення в long |
float | unsigned short | перетворення до long, перетворення long в unsigned short |
float | unsigned long | перетворення до long, перетворення long в unsigned long |
float | double | зміна внутрішнього представлення |
double | char | перетворення до float, перетворення float в char |
double | short | перетворення до float, перетворення float в short |
double | long | усікання дробової частини; результат невизначений, якщо він занадто великий для представлення в long |
double | unsigned short | перетворення до long, перетворення long в unsigned short |
double | unsigned long | перетворення до long, перетворення long в unsigned long |
double | float | представляється як float; якщо значення double не може бути точно представлено як float, то точність губиться; якщо значення занадто велике для представлення як float, то результат невизначений |
Перетворення адресних типів
Вказівник на величину одного типу може бути перетворений до вказівника на величину іншого типу. Результат може бути, однак, невизначеним через відмінність у вимогах до вирівнювання і розмірів пам'яті.
У деяких реалізаціях є спеціальні ключові слова near, far, huge, що модифікують розмір вказівників у програмах.
Значення вказівника може бути перетворене до цілої величини. Шлях перетворення залежить від розміру вказівника і розміру цілого типу наступним чином:
- якщо вказівник має той самий або менший розмір, чим цілий тип, то вказівник перетвориться точно так само як беззнакове ціле, за винятком того, що він не може бути перетворений до дійсної величини;
- якщо розмір вказівника менший ніж розмір цілого типу, то вказівник спочатку перетворюється до вказівника з тим самим розміром, що й цілий тип, і потім перетворюється до цілого типу. Метод перетворення вказівника до більш довгого вказівника залежить від реалізації.
Цілий тип може бути перетворений до адресного типу. Якщо цілий тип того ж самого розміру, що й адресний, то виконується просте перетворення до виду вказівника (беззнакового цілого). Якщо розмір цілого типу відмінний від розміру адресного типу, то цілий тип спочатку перетворюється до розміру вказівника, використовуючи методи перетворення даних, і потім отримане значення представляється як вказівник.
Цілочисельний константний вираз зі значенням 0 або він же, але приведений до типу voіd *, може бути перетворений у вказівник будь-якого типу операторами приведення, присвоювання і порівняння. Результатом буде NULL-вказівник, що дорівнює будь-якому іншому NULL-вказівникові того ж типу, але не дорівнює ніякому вказівникові на реальний об'єкт або функцію.
Вказівник може також перетворюватися в voіd * і назад, значення вказівника при цьому не змінюється.
Вказівник може неявно перетворюватися в значення типу bool, при цьому ненульовий вказівник перетвориться в true, а нульовий у false.
Присвоювання вказівників допускається в двох випадках:
· вказівникам типу voіd*:
· якщо тип вказівників праворуч і ліворуч від операції присвоювання той самий.
Таким чином, неявне перетворення виконується тільки до типу voіd*. Значення 0 неявно перетворюється до вказівника на будь-який тип.
Перетворення інших типів
Згідно з визначенням типу enum випливає, що величини enum є величинами типу іnt. Тому перетворення в тип enum або з типу enum здійснюється так само, як для іnt-типів.
Неприпустимі перетворення об’єктів типу структура або об'єднання.