Ц ++

Ц ++ стандардне конверзије

Ц ++ стандардне конверзије
Постоје два типа ентитета у Ц ++, основни типови и сложени типови. Основни типови су скаларни типови. Сложени типови су остали типови ентитета. Конверзија се може извршити из једног типа ентитета у други одговарајући тип. Размотрите следећи програм:

#инцлуде
#инцлуде
коришћење простора имена стд;
инт маин ()

инт рт1 = скрт (5);
инт рт2 = скрт (8);
цоут<ретурн 0;

Излаз је 2, 2, што значи да је програм вратио квадратни корен 5 као 2 и квадратни корен 8 такође као 2. Дакле, прве две изјаве у главни() функција прекрила одговоре квадратног корена из 5 и квадратног корена из 8. Овај чланак не говори о подовима или плафонима у Ц++. Уместо тога, овај чланак говори о конверзији једног типа Ц ++ у други одговарајући тип Ц ++; што указује на било какву приближну вредност која је направљена, губитак прецизности или ограничење додато или уклоњено. Основно познавање Ц ++-а је предуслов за разумевање овог чланка.

Садржај чланка

  • Интегралне конверзије
  • Конверзије са покретном тачком
  • Плутајуће-интегралне конверзије
  • Целобројна ранг конверзија
  • Интеграл Промотионс
  • Уобичајене аритметичке претворбе
  • Промоција са покретном тачком
  • Конверзије показивача
  • Функција претварања показивача
  • Булове претворбе
  • Лвалуе, првалуе и квалуе
  • Ксвалуе
  • Конверзије Лвалуе-то-рвалуе
  • Конверзије низа у показивач
  • Конверзије функције у показивач
  • Привремене конверзије материјализације
  • Квалификационе конверзије
  • Закључак

Интегралне конверзије

Интегралне конверзије су целобројне конверзије. Непотписани цијели бројеви укључују „непотписани знак“, „непотписани кратки инт“, „непотписани инт“, „непотписани дуги инт“ и „непотписани дуги дуги инт“."Одговарајући потписани цели бројеви укључују" потписани знак "," кратки инт "," инт "," дуги инт "и" дуги дуги инт.”Сваки тип инт требао би се чувати у онолико бајтова колико и његов претходник. За већину система, један тип ентитета може се без проблема претворити у одговарајући тип. Проблем се јавља приликом конверзије из већег типа опсега у мањи тип опсега или приликом претварања потписаног броја у одговарајући непотписани број.

Сваки компајлер има максималну вредност коју може узети за кратки инт. Ако се кратком инт додели број већи од тог максимума, намењен за инт, компајлер ће следити неки алгоритам и вратити број унутар опсега кратког инт. Ако програмер има среће, компајлер ће упозорити на проблеме са коришћењем непримерене конверзије. Исто објашњење односи се на конверзије других инт типова.

Корисник треба да прегледа документацију компајлера како би одредио граничне вредности за сваки тип ентитета.

Ако се негативни потписани кратки инт број претвара у непотписани кратки инт број, компајлер ће следити неки алгоритам и вратити позитиван број у домету непотписаног кратког инт. Овакву конверзију треба избегавати. Исто објашњење односи се на конверзије других инт типова.

Било који целобројни број, осим 0, може се претворити у логичку вредност труе. 0 се претвара у логичку вредност фалсе. Следећи код то илуструје:

инт а = -27647;
флоат б = 2.5;
инт ц = 0;
боол а1 = а;
боол б1 = б;
боол ц1 = ц;
цоут<цоут<цоут<Излаз је:

1 за истину
1 за истину
0 за фалсе

Конверзије са покретном тачком

Типови с помичним зарезом укључују „флоат“, „доубле“ и „лонг доубле“.”Типови с помичном зарезом нису груписани у потписане и непотписане, попут цијелих бројева. Свака врста може имати потписани или непотписани број. Тип са покретном зарезом треба да има бар исту прецизност као и његов претходник. Односно, „лонг доубле“ треба да има једнаку или већу прецизност као „доубле“, а „доубле“ треба да има једнаку или већу прецизност да „плута“.”

Имајте на уму да опсег типа са покретном зарезом није континуиран; него малим корацима. Што је већа прецизност типа, то су кораци мањи и већи је број бајтова за чување броја. Дакле, када се број са помичном зарезом конвертује из типа мање прецизности у тип више прецизности, програмер мора прихватити лажно повећање прецизности и могуће повећање броја бајтова за складиштење бројева. Када се број са помичном зарезом претвори из типа веће прецизности у тип ниже прецизности, програмер мора прихватити губитак прецизности. Ако се мора смањити број бајтова за складиштење бројева, тада ће преводилац следити неки алгоритам и вратити број као замену (што вероватно није оно што програмер жели). Такође имајте на уму проблеме изван домета.

Плутајуће-интегралне конверзије

Број са покретном зарезом претвара се у цео број одсецањем делимичног дела. Следећи код то илуструје:

флоат ф = 56.953;
инт и = ф;
цоут<Излаз је 56. Распони за флоат и интегер морају бити компатибилни.

Када се цели број претвори у флоат, вредност приказана као флоат је иста она која је унесена као цео број. Међутим, плутајући еквивалент може бити тачна вредност или има малу делимичну разлику која се не приказује. Разлог за разломљене разлике је тај што су бројеви с помичном зарезом у рачунару представљени малим разломљеним корацима, па би тачно представљање целог броја било случајност. Дакле, иако је цео број приказан као флоат исти као што је откуцан, приказ може бити приближан приказ онога што је сачувано.

Целобројна ранг конверзија

Било који целобројни тип има ранг који му је додељен. Ово рангирање помаже у конверзији. Рангирање је релативно; чинови нису на фиксним нивоима. Осим цхар и сигн цхар, нема два потписана цијела броја која имају исти ранг (под претпоставком да је цхар потписан). Непотписани целобројни типови имају исти ранг као и њихови одговарајући потписани целобројни типови. Поредак је следећи:

  • Под претпоставком да је цхар потписан, онда цхар и потписани цхар имају исти ранг.
  • Ранг потписаног целобројног типа већи је од ранга потписаног целобројног типа мањег броја бајтова меморије. Дакле, ранг потписаног лонг лонг инт је већи од ранга потписаног лонг инт, који је већи од ранга потписаног инт, који је већи од ранга потписаног кратког инт, који је већи од ранга потписаног цхар.
  • Ранг било којег непотписаног целобројног типа једнак је рангу одговарајућег потписаног целобројног типа.
  • Чин непотписаног знака једнак је рангу потписаног знака.
  • боол има најмањи ранг; његов ранг је мањи од рангираног знака.
  • цхар16_т има исти ранг као и кратки инт. цхар32_т има исти ранг као и инт. За г ++ компајлер, вцхар_т има исти ранг као и инт.

Интеграл Промотионс

Интеграл Промотионс је Интегер Промотионс. Нема разлога зашто цео број мањег бајта не може бити представљен целим бројем већих бајтова. Интегер промоције се баве свиме што следи:

  • Потписани кратки инт (два бајта) може се претворити у потписани инт (четири бајта). Непотписани кратки инт (два бајта) може се претворити у непотписани инт (четири бајта). Напомена: претварање кратког инт у лонг инт или лонг лонг инт доводи до губитка бајтова складишта (локације објекта) и губитка меморије. Боол, цхар16_т, цхар32_т и вцхар_т су изузети од ове промоције (са компајлером г ++ цхар32_т и вцхар_т имају исти број бајтова).
  • Са компајлером г ++, тип цхар16_т може се претворити у потписан инт тип или непотписани инт тип; тип цхар32_т се може претворити у потписани инт тип или непотписани инт тип; а тип вцхар_т се може претворити у потписан или непотписан инт тип.
  • Боол тип се може претворити у инт тип. У овом случају, труе постаје 1 (четири бајта), а фалсе постаје 0 (четири бајта). Инт може бити потписан или потписан.
  • Целобројна промоција постоји и за необухваћени тип набрајања - видети касније.

Уобичајене аритметичке претворбе

Узмите у обзир следећи код:

флоат ф = 2.5;
инт и = ф;
цоут<Код се компајлира без навођења било каквог упозорења или грешке, дајући излаз из 2, што вероватно није оно што се очекивало. = је бинарни оператор јер је потребан леви и десни операнд. Узмите у обзир следећи код:

инт и1 = 7;
инт и2 = 2;
флоат флт = и1 / и2;
цоут<Излаз је 3, али ово је погрешно; требало је да буде 3.5. Оператор дељења, /, је такође бинарни оператор.

Ц ++ има уобичајене аритметичке претворбе које програмер мора знати да би избегао грешке у кодирању. Уобичајене аритметичке претворбе на бинарним операторима су следеће:

  • Ако је један од операнда типа „лонг доубле“, тада ће други бити претворен у лонг доубле.
  • Иначе, ако је један операнд двоструки, други ће се претворити у двоструки.
  • У супротном, ако је један од операнда флоат, други ће се претворити у флоат. У горњем коду, резултат и1 / и2 је званично 2; зато је флт 2. Резултат бинарног, /, се примењује као десни операнд на бинарни оператор, =. Дакле, коначна вредност 2 је флоат (не инт).

ОСТАЛО, ИНТЕГРИСАНА ПРОМОЦИЈА БИЛА БИ СЕ ОДРЖАЛА СЛЕДЕЋЕ:

  • Ако су оба операнда истог типа, тада се не врши даље претварање.
  • Иначе, ако су оба операнда потписана целобројна типа или су оба непотписана целобројна типа, тада ће се операнд типа са нижим целобројним рангом претворити у тип операнда са вишим рангом.
  • Иначе, ако је један операнд потписан, а други непотписан, и ако је непотписани тип операнда већи или једнак рангу типа потписаног операнда, и ако је вредност потписаног операнда већа или једнака нули, тада потписани операнд ће се претворити у непотписани тип операнда (узимајући у обзир опсег). Ако је потписани операнд негативан, тада ће преводилац следити алгоритам и вратити број који програмеру можда неће бити прихватљив.
  • Иначе, ако је један операнд потписан цео број, а други непотписани целобројни тип, и ако све могуће вредности типа операнда са непотписаним целобројним типом могу бити представљене потписаним целобројним типом, тада ће непотписани целобројни тип бити претворена у тип операнда потписаног целобројног типа.
  • У супротном, два операнда (на пример цхар и боол) претворила би се у непотписани целобројни тип.

Промоција са покретном тачком

Типови с помичним зарезом укључују „флоат“, „доубле“ и „лонг доубле“.”Тип са покретном зарезом треба да има бар исту прецизност као и његов претходник. Промоција са помичним зарезом омогућава конверзију из флоат у доубле или из доубле у лонг доубле.

Конверзије показивача

Показивач једног типа објекта не може се доделити показивачу другог типа објекта. Следећи код се неће компајлирати:

инт ид = 6;
инт * интПтр = &id;
флоат идф = 2.5;
флоат * флоатПтр = &idf;
интПтр = флоатПтр; // овде грешка

Нулти показивач је показивач чија је адреса адреса нула. Нулти показивач једног типа објекта не може се доделити нултом показивачу другог типа објекта. Следећи код се неће компајлирати:

инт ид = 6;
инт * интПтр = &id;
интПтр = 0;
флоат идф = 2.5;
флоат * флоатПтр = &idf;
флоатПтр = 0;
интПтр = флоатПтр; // грешка овде

Садржај нултог показивача једног типа објекта не може се додијелити нултој конст. Следећи код се неће компајлирати:

инт ид = 6;
инт * интПтр = &id;
инт * цонст интПЦ = 0;
флоат идф = 2.5;
флоат * флоатПтр = &idf;
флоат * цонст флоатПЦ = 0;
интПЦ = флоатПЦ; // грешка овде

Нултом показивачу може се доделити другачија адреса за свој тип. Следећи код то илуструје:

флоат идф = 2.5;
флоат * флоатПтр = 0;
флоатПтр = &idf;
цоут<<*floatPtr<<'\n';

Излаз је 2.5.

Као што се и очекивало, константи нултог показивача не може се доделити ниједна адреса адреса свог типа. Следећи код се неће компајлирати:

флоат идф = 2.5;
флоат * цонст флоатПЦ = 0;
флоатПЦ = &idf; // грешка овде

Међутим, обичном показивачу може се доделити нулта константа показивача, али истог типа (ово се очекује). Следећи код то илуструје:

флоат идф = 2.5;
флоат * цонст флоатПЦ = 0;
флоат * флоатПтер = &idf;
флоатПтер = флоатПЦ; //У РЕДУ
цоут << floatPter << '\n';

Излаз је 0.

Две вредности нулл показивача истог типа упоређују (==) једнаке.

Показивач на тип објекта може се доделити показивачу на воид. Следећи код то илуструје:

флоат идф = 2.5;
флоат * флоатПтр = &idf;
воид * вд;
вд = флоатПтр;

Код се компајлира без упозорења или поруке о грешци.

Функција претварања показивача

Показивач на функцију која не би изузела изузетак може се доделити показивачу на функцију. Следећи код то илуструје:

#инцлуде
коришћење простора имена стд;
воид фн1 () без изузетка

цоут << "with noexcept" << '\n';

воид фн2 ()

// изјаве

воид (* фунц1) () ноекцепт;
воид (* фунц2) ();
инт маин ()

фунц1 = &fn1;
фунц2 = &fn2;
фунц2 = &fn1;
фунц2 ();
ретурн 0;

Излаз је без изузетка.

Булове претворбе

У Ц ++, ентитети који могу резултирати лажним укључују „нулу“, „нулти показивач“ и „нул-показивач члана“.”Сви остали ентитети резултирају истином. Следећи код то илуструје:

боол а = 0.0; цоут << a <<'\n';
флоат * флоатПтр = 0;
боол б = флоатПтр; цоут << b <<'\n';
боол ц = -2.5; цоут << c <<'\n';
боол д = +2.5; цоут << d <<'\n';

Излаз је:

0 // за фалсе
0 // за фалсе
1 // тачно
1 // тачно

Лвалуе, првалуе и квалуе

Узмите у обзир следећи код:

инт ид = 35;
инт & ид1 = ид;
цоут << id1 << '\n';

Излаз је 35. У коду су ид и ид1 вредности, јер идентификују локацију (објекат) у меморији. Излаз 35 је прва вредност. Било који литерал, осим литералног низа, је прва вредност. Остале вредности нису толико очигледне, као у примерима који следе. Узмите у обзир следећи код:

инт ид = 62;
инт * птр = &id;
инт * птер;

Птр је вредност, јер идентификује локацију (објекат) у меморији. С друге стране, птер није вредност. Птер је показивач, али не идентификује ниједну локацију у меморији (не показује ниједан објекат). Дакле, птер је прва вредност.

Узмите у обзир следећи код:

воид фн ()

// изјаве

воид (* фунц) () = &fn;
флоат (* фунцтн) ();

Фн () и (* фунц) () су изрази вредности, јер идентификују ентитет (функцију) у меморији. С друге стране, (* фунцтн) () није израз вредности. (* фунцтн) () је показивач на функцију, али не идентификује ниједан ентитет у меморији (не показује ниједну функцију у меморији). Дакле, (* фунцтн) () је израз прве вредности.

Сада узмите у обзир следећи код:

струцт С

инт н;
;
С обј;

С је класа, а обј је објект инстанциран из класе. Обј идентификује објекат у меморији. Час је уопштена јединица. Дакле, С заправо не идентификује ниједан објекат у меморији. За С се каже да је неименовани објекат. С је такође израз прве вредности.

Фокус овог чланка је на вредностима. Првалуе значи чисту вредност.

Ксвалуе

Ксвалуе је скраћеница од Вредност која истиче. Привремене вредности су вредности које истичу. Лвалуе може постати квалуе. Првалуе такође може постати квалуе. Фокус овог чланка је на вредностима. Ксвалуе је лвалуе или неименована референца рвалуе чије се складиште може поново користити (обично зато што је при крају његовог животног века). Размотрите следећи код који ради:

струцт С

инт н;
;
инт к = С ().н;

Израз „инт к = С ().н; ” копира сву вредност коју н има у к. С () је само средство; није редовно употребљаван израз. С () је прва вредност чија је употреба претворила у квалуе.

Конверзије Лвалуе-то-рвалуе

Размотрите следећу изјаву:

инт ии = 70;

70 је прва вредност (рвалуе), а ии је вредност. Сада узмите у обзир следећи код:

инт ии = 70;
инт тт = ии;

У другој изјави, ии је у ситуацији прве вредности, па ии тамо постаје прва вредност. Другим речима, преводилац имплицитно претвара ии у прву вредност. То јест, када се лвалуе користи у ситуацији у којој имплементација очекује прву вредност, имплементација претвара лвалуе у прву вредност.

Конверзије низа у показивач

Размотрите следећи код који ради:

цхар * п;
цхар к [] = 'а', 'б', 'ц';
п = & к [0];
++п;
цоут<<*p<<'\n';

Излаз је б. Прва изјава је израз и показивач је на знак. Али на који карактер упућује изјава? - Нема лика. Дакле, то је прва вредност, а не вредност. Друга изјава је низ у којем је к [] израз вредности. Трећа изјава претвара првалуе, п, у израз лвалуе, који указује на први елемент низа.

Конверзије функције у показивач

Размотрите следећи програм:

#инцлуде
коришћење простора имена стд;
воид (* фунц) ();
воид фн ()

// изјаве

инт маин ()

фунц = &fn;
ретурн 0;

Израз „воид (* фунц) ();“ је показивач на функцију. Али на коју функцију упућује израз? - Нема функције. Дакле, то је прва вредност, а не вредност. Фн () је дефиниција функције, где је фн израз вредности. У маин (), „фунц = &fn;”Претвара првалуе, фунц, у израз лвалуе који указује на функцију, фн ().

Привремене конверзије материјализације

У Ц ++-у, прва вредност се може претворити у к-вредност истог типа. Следећи код то илуструје:

струцт С

инт н;
;
инт к = С ().н;

Овде је прва вредност, С (), претворена у квалуе. Као квалуе, неће трајати дуго - погледајте више објашњења горе.

Квалификационе конверзије

Цв-квалификовани тип је тип квалификован резервисаном речју „цонст“ и / или резервисаном речју „волатиле“.”

Цв-квалификација је такође рангирана. Ниједна цв-квалификација није мања од квалификације „цонст“, што је мање од квалификације „цонст волатиле“. Ниједна цв-квалификација није мања од „испарљиве“ квалификације, што је мање од квалификације „цонст волатиле“. Дакле, постоје два тока квалификационог рангирања. Један тип може бити квалификованији за цв од другог.

Нижи првалуе цв-квалификовани тип може се претворити у цв-квалификовани првалуе тип. Обе врсте треба да буду показивач на цв.

Закључак

Ц ++ ентитети се могу претворити из једног типа у сродни тип имплицитно или експлицитно. Међутим, програмер мора да разуме шта се може претворити, а шта не може претворити и у који облик. Конверзија се може извршити у следећим доменима: Интегралне конверзије, Конверзије са помичном тачком, Плутајуће-Интегралне конверзије, Уобичајене аритметичке претворбе, Претворбе показивача, Функција у претворбе показивача, Боолеове претворбе, Претворбе Лвалуе-то-Рвалуе, Претворбе поља у показивач , Претворбе функције у показивач, привремене конверзије материјализације и претворбе квалификација.

ОпенТТД вс Симутранс
Стварање сопствене симулације превоза може бити забавно, опуштајуће и изузетно примамљиво. Због тога морате да испробате што више игара како бисте про...
Водич за ОпенТТД
ОпенТТД је једна од најпопуларнијих игара за пословну симулацију. У овој игри морате створити диван посао превоза. Међутим, почет ћете у почетку око 1...
СуперТукКарт за Линук
СуперТукКарт је сјајан наслов дизајниран да вам пружи Марио Карт искуство бесплатно на вашем Линук систему. Прилично је изазовно и забавно играти, диз...