Знаймо

Додати знання

приховати рекламу

Цей текст може містити помилки.

Приведення типу



План:


Введення

Приведення типу (type conversion) - перетворення значення змінної одного типу в значення іншого типу. Виділяють явне і неявне приведення типів.

  • При явному приведенні вказується тип змінної, до якого необхідно перетворити вихідну змінну.
  • При неявному приведенні перетворення відбувається автоматично, за правилами, закладеним у цьому мові програмування.
  • Також в мові можуть бути задані спеціальні функції для приведення.

1. Неявне приведення

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

У мові C :

 double  d  ;  / / Речовинний тип  long  l  ;  / / Цілий тип  int  i  ;  / / Цілий тип  if  (  d  >  i  )  d  =  i  ;  if  (  i  >  l  )  l  =  i  ;  if  (  d  ==  l  )  d  * =  2  ; 

Кожного разу при виконанні операцій порівняння або присвоювання змінні різних типів будуть приведені до єдиного типу. Слід з обережністю використовувати неявне приведення типу. При перекладі числа з речовинного типу в цілочисельний, дробова частина відсікається. Зворотне приведення з цілочисельного типу до вещественному також може привести до пониження точності, що пов'язано з різним поданням речових і цілочисельних чисел на машинному рівні. Наприклад, речовинний тип single стандарту IEEE 754 не може точно уявити число 16777217, в той час як 32-бітовий цілочисельний тип може. Це може призвести до ситуацій, коли порівняння на рівність одного і того ж числа, представленого типами (int і single) буде видавати помилковий результат (числа не рівні один одному).


2. Явне приведення типу

2.1. У мові C

Для явного приведення типів деякої змінної перед ній слід вказати в круглих дужках ім'я нового типу, наприклад:

 int  X  ;  int  Y  =  200  ;  char  C  =  30  ;  X  =  (  int  )  C  *  10  +  Y  ;  / / Змінна С наведена до типу int. 

Грубих помилок в даному прикладі від автоматичного приведення типів не станеться, так як змінна C, яка має тип char буде приведена до типу int, так як тут йде мова про "підвищення" типу змінної до старшого в виразі (змінна С перед присвоюванням неявно приводиться до типу змінної Y). Але можливий один нюанс - в залежності від машинної реалізації типу char при перетворенні char в int може вийти негативне число, тому рекомендується використовувати явне перетворення, а якщо все-таки є перетворення типу char в int, char оголошувати як беззнакові (unsigned char).


2.2. У мові C + +

У мові C + + існує чотири різновиди приведення типу. Всі чотири типи записуються у вигляді

 xxx_cast  (expression_from) 

Наприклад:

 y  =  static_cast  <  signed  short  >  (  65534  )  ;  / / Буде присвоєно -2 

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

2.2.1. static_cast

  • Призначення: Приведення типу за звичайними правилами, коли компілятор відмовляється привести його автоматично (відрізняється від застосовуваного в Сі (type_to)expression_from тільки тим, що з покажчиками на довільні типу не працює, може застосовуватися тільки для перетворення void * до іншого покажчику і для перетворення вниз по ієрархії класів; для довільних покажчиків застосовується reinterpret_cast). Застосовується:
    • для обчислень в більш широкому числовому типі (наприклад, для дрібних обчислень з цілими числами);
    • щоб позбутися від попередження "Можлива втрата точності" при перекладі в більш вузький числовий тип;
    • для покажчиків і посилань при конвертації в батьківський тип;
    • для типів з конструкторами або операціями конвертації на зразок operator type_to;
    • в шаблонах - компілятор вже при спеціалізації шаблону вирішує, які операції використовувати;
    • в операції ?:, у якої then - і else-частини повинні мати один тип.
  • Обмеження на expression_from : немає.
  • Обмеження на type_to : повинен знайтися спосіб перетворення в type_to.
  • Виробляє чи код: у загальному випадку да.
  • Можливі помилки: відносно безпечно. Логічні помилки можливі, якщо привести в неправильний тип або взагалі пропустити приведення, коли воно потрібне. Не виключено, що після перетворення з'явиться тимчасовий об'єкт, який буде благополучно знищений разом з усіма змінами (більшість компіляторів на це видають попередження).
 / / Повертає відсоток влучень.  double  hitpercent  (  const  int  aHitCount,  const  int  aShotCount  )  {  if  (  aShotCount  ==  0  )  return  0.0  ;  / / Нам потрібно докладний поділ, а не цілочисельне - тому переведемо ділене і дільник в double  return  static_cast  <  double  >  (  aHitCount  *  100  )  /  static_cast  <  double  >  (  aShotCount  )  ;  }  string s  =  static_cast  <  string  >  (  "Hello!"  )  ;  / / Аналогічно string s = string ("Hello!");  string s  =  (  string  )  "Hello!"  ;  / / Синтаксис Сі теж працює  string s  =  static_cast  <  string  >  (  5  )  ;  / / Не компілюється - немає відповідного конструктора 

2.2.2. dynamic_cast

  • Призначення: Проводить перетворення типу, попередньо переконавшись (за допомогою RTTI), що об'єкт expression_from в дійсності є об'єктом типу type_to. Якщо немає: для покажчиків повертає NULL, для посилань встановлює аварійну ситуацію std::bad_cast.
  • Обмеження на expression_from : вираз повинен бути посиланням або покажчиком на об'єкт з хоча б однією віртуальної функцією.
  • Обмеження на type_to : посилання або покажчик на дочірній по відношенню до expression_from тип.
  • Виробляє чи код: так.
  • Можливі помилки: відносно безпечно. Логічні помилки можливі, якщо подати аргумент, який не має тип type_to, в той час як код не пристосований до цього.

2.2.3. const_cast

  • Призначення: Зняття / встановлення модифікатора const або volatile.
  • Обмеження на expression_from : посилання або покажчик.
  • Обмеження на type_to : повинен збігатися з типом expression_from з точністю до модифікаторів const або volatile.
  • Виробляє чи код: немає.
  • Можливі помилки: чревато спробою змінити незмінний об'єкт.
 namespace  {  / / Кожна завантаження DLL створює новий сегмент даних.  / / Так що з такими глобальними змінними одна програма не буде  / / Заважати іншій.  string s  =  "Wikipedia"  ;  }  typedef  char  *  PChar  ;  / / Функція експортується DLL'ем і повертає якусь рядок  / / У вигляді char *. Проблема в тому, що std :: string :: c_str () повертає  / / Const char *.  void  __declspec  (  dllexport  )  WINAPI SomeDllFunction  (  PChar  &  rMessage  )  {  rMessage  =  const_cast  <  char  *  >  (  s.  c_str  (  )  )  ;  } 

2.2.4. reinterpret_cast

  • Призначення: Ділянка пам'яті розглядається як об'єкт іншого типу.
  • Обмеження на expression_from : порядковий тип (логічний, символьний, цілий, перелічуваний), покажчик, посилання.
  • Обмеження на type_to : для порядкового типу або покажчика - порядковий тип або покажчик. Для посилання - посилання.
  • Виробляє чи код: немає.
  • Можливі помилки: Ділянка в реальності може і не мати цього типу. Немає ніякої можливості перевірити це, всю відповідальність за коректність перетворення програміст бере на себе.
 / / Повертає true, якщо число кінцеве, і false - якщо безкінечне або NaN.  / / Працює на 32 - і 64-бітному IBM PC.  bool  isfinite  (  const  double  x  )  {  const  long  long  &  y  =  reinterpret_cast  <  const  long  long  &  >  (  x  )  ;  return  (  (  y  &  0x7FF0000000000000LL  )  !  =  0x7FF0000000000000LL  )  ;  }  / / Помилка - вираз x +5.0 не є посиланням.  const  long  long  &  y  =  reinterpret_cast  <  const  long  long  &  >  (  x  +  5.0  )  ; 



Цей текст може містити помилки.

Схожі роботи | скачати

Схожі роботи:
Приведення до абсурду
Напівпровідник n-типу
Нейрофіброматоз I типу
Нейрофіброматоз II типу
Напівпровідник p-типу
Вагон метро типу Єв
Вагон метро типу І
Вагон метро типу В
Броненосці типу Девастейшн
© Усі права захищені
написати до нас