C ++

C ++ standardkonverteringer

C ++ standardkonverteringer
Der er to enhedstyper i C ++, de grundlæggende typer og sammensatte typer. De grundlæggende typer er de skalære typer. Sammensatte typer er resten af ​​enhedstyperne. Konvertering kan finde sted fra en enhedstype til en anden passende type. Overvej følgende program:

#omfatte
#omfatte
ved hjælp af namespace std;
int main ()

int rt1 = sqrt (5);
int rt2 = sqrt (8);
cout<returnere 0;

Outputtet er 2, 2, hvilket betyder, at programmet har returneret kvadratroden på 5 som 2 og kvadratroden på 8 også som 2. Så de to første udsagn i hoved () funktion har ordet svarene på kvadratroden på 5 og kvadratroden på 8. Denne artikel diskuterer ikke gulve eller loft i C++. Snarere diskuterer denne artikel konvertering af en C ++ - type til en anden passende C ++ - type; angiver enhver tilnærmelse i foretaget værdi, tab af præcision eller begrænsning tilføjet eller fjernet. Grundlæggende viden om C ++ er en forudsætning for at forstå denne artikel.

Artikelindhold

  • Integrerede konverteringer
  • Flydende konverteringer
  • Flydende-integrerede konverteringer
  • Heltals konverteringsrangering
  • Integrerede forfremmelser
  • Almindelige aritmetiske konverteringer
  • Flydende kampagne
  • Markørkonverteringer
  • Funktion til markørkonverteringer
  • Boolske konverteringer
  • Lvalue, prvalue og xvalue
  • Xværdi
  • Lvalue-to-rvalue-konverteringer
  • Array-to-Pointer-konverteringer
  • Funktion-til-markørkonverteringer
  • Midlertidige materialiseringskonverteringer
  • Kvalifikationskonverteringer
  • Konklusion

Integrerede konverteringer

Integrerede konverteringer er heltalskonverteringer. Usignerede heltal inkluderer "usigneret char", "usigneret kort int", "usigneret int", "usigneret lang int" og "usigneret lang lang int.”De tilsvarende underskrevne heltal inkluderer“ signeret char ”,“ kort int ”,“ int ”,“ lang int ”og“ lang lang int.”Hver int-type skal holdes i så mange byte som sin forgænger. For de fleste systemer kan en enhedstype konverteres til en tilsvarende type uden problemer. Problemet opstår, når man konverterer fra en større rækkevidde til en mindre rækkevidde, eller når man konverterer et underskrevet nummer til et tilsvarende usigneret nummer.

Hver compiler har en maksimumsværdi, som den kan tage for den korte int. Hvis et tal højere end det maksimale, der er beregnet til et int, tildeles short int, følger compileren en eller anden algoritme og returnerer et tal inden for området for short int. Hvis programmøren er heldig, advarer compileren om problemer med at bruge upassende konvertering. Den samme forklaring gælder for konverteringer af andre int-typer.

Brugeren bør konsultere dokumentationen til compileren for at bestemme grænseværdierne for hver enhedstype.

Hvis et negativt underskrevet kort int-nummer skal konverteres til et usigneret kort int-nummer, følger compileren en eller anden algoritme og returnerer et positivt tal inden for området for det usignerede korte int. Denne form for konvertering bør undgås. Den samme forklaring gælder for konverteringer af andre int-typer.

Ethvert heltal, undtagen 0, kan konverteres til boolsk sand. 0 konverteres til boolsk falsk. Følgende kode illustrerer dette:

int a = -27647;
flyde b = 2.5;
int c = 0;
bool a1 = a;
bool b1 = b;
bool c1 = c;
cout<cout<cout<Outputtet er:

1 for sandt
1 for sandt
0 for falsk

Flydende konverteringer

Flydepunkttyper inkluderer "flyde", "dobbelt" og "lang dobbelt.”Flydepunkttyper er ikke grupperet i underskrevet og usigneret, som heltal. Hver type kan have et underskrevet eller usigneret nummer. En flydende punkt-type skal have mindst samme præcision som sin forgænger. Det vil sige, "lang dobbelt" skal have lige eller større præcision til "dobbelt", og "dobbelt" skal have lige eller større præcision til at "flyde.”

Husk, at rækkevidden for en flydende punkt-type ikke er kontinuerlig; snarere er det i små trin. Jo større præcisionen af ​​typen er, jo mindre trin og jo større antal byte til at gemme nummeret. Så når et flydende punkt tal konverteres fra en lavere præcisionstype til en højere præcisionstype, skal programmøren acceptere en falsk stigning i præcision og en mulig stigning i antallet af byte til nummerlagring. Når et flydende nummer konverteres fra en højere præcisionstype til en lavere præcisionstype, skal programmøren acceptere et tab af præcision. Hvis antallet af byte til nummerlagring skal reduceres, følger compileren nogle algoritmer og returnerer et tal som erstatning (hvilket sandsynligvis ikke er, hvad programmøren ønsker). Husk også problemer uden for rækkevidde.

Flydende-integrerede konverteringer

Et flydende nummer konverteres til et heltal ved at afkorte den brøkdel. Følgende kode illustrerer dette:

flyde f = 56.953;
int i = f;
cout<Outputtet er 56. Områderne for float og heltal skal være kompatible.

Når et heltal konverteres til en float, er værdien, der vises som en float, den samme som blev indtastet som et heltal. Imidlertid kan flydeækvivalenten være den nøjagtige værdi eller have en lille brøkforskel, der ikke vises. Årsagen til brøkforskellen er, at flydende tal er repræsenteret i computeren i små brøkstrin, og det ville derfor være en tilfældighed at repræsentere heltal nøjagtigt. Så selvom det heltal, der vises som en float, er det samme som blev skrevet, kan displayet være en tilnærmelse af det, der er gemt.

Heltals konverteringsrangering

Enhver heltalstype har en rang, der er givet til den. Denne placering hjælper med konvertering. Rangeringen er relativ; rækkerne er ikke på faste niveauer. Bortset fra char og signeret char har ingen to signerede heltal samme rang (forudsat at char er underskrevet). Usignerede heltalstyper har samme placering som deres tilsvarende signerede heltalstyper. Rangeringen er som følger:

  • Forudsat at char er underskrevet, har char og signeret char samme rang.
  • Rangen for en signeret heltalstype er større end rangen for en signeret heltalstype for et mindre antal lagerbyte. Så, rangeringen af ​​underskrevet lang lang int er større end rangen for underskrevet lang int, som er større end rangen for underskrevet int, som er større end rangen for underskrevet kort int, som er større end rangen for signeret char.
  • Rangeringen af ​​en hvilken som helst usigneret heltalstype svarer til rangen for den tilsvarende underskrevne heltalstype.
  • Rangeringen af ​​usigneret rød er lig med rangen for underskrevet rød.
  • bool har mindst rang; dens rang er mindre end signaturrød.
  • char16_t har samme rang som den korte int. char32_t har samme rang som int. For g ++ -kompilatoren har wchar_t samme rang som int.

Integrerede forfremmelser

Integrerede kampagner er heltalskampagner. Der er ingen grund til, at et heltal med færre byte ikke kan repræsenteres af et heltal med større byte. Integer Promotions beskæftiger sig med alt det følgende:

  • En signeret kort int (to byte) kan konverteres til en signeret int (fire byte). En usigneret kort int (to byte) kan konverteres til en usigneret int (fire byte). Bemærk: konvertering af en kort int til en lang int eller en lang lang int fører til spild af lagring (objektplacering) byte og spild af hukommelse. Bool, char16_t, char32_t og wchar_t er undtaget fra denne kampagne (med g ++ compileren har char32_t og wchar_t det samme antal bytes).
  • Med g ++ compileren kan en char16_t-type konverteres til en signeret int-type eller en usigneret int-type; en char32_t-type kan konverteres til en signeret int-type eller en usigneret int-type; og en wchar_t-type kan konverteres til en signeret eller usigneret int-type.
  • En bool-type kan konverteres til en int-type. I dette tilfælde bliver sandt 1 (fire byte) og falsk bliver 0 (fire byte). Int kan underskrives eller underskrives.
  • Heltalsfremme findes også for ikke-udpeget optællingstype - se senere.

Almindelige aritmetiske konverteringer

Overvej følgende kode:

flyde f = 2.5;
int i = f;
cout<Koden kompileres uden at angive nogen advarsel eller fejl, hvilket giver output af 2, hvilket sandsynligvis ikke er, hvad man havde forventet. = er en binær operator, fordi den tager en venstre og højre operand. Overvej følgende kode:

int i1 = 7;
int i2 = 2;
flyde flt = i1 / i2;
cout<Outputtet er 3, men dette er forkert; det skulle være 3.5. Opdelingsoperatøren, /, er også en binær operatør.

C ++ har sædvanlige aritmetiske konverteringer, som programmøren skal kende for at undgå fejl i kodning. De sædvanlige aritmetiske konverteringer på binære operatører er som følger:

  • Hvis den ene operand er af typen "lang dobbelt", konverteres den anden til lang dobbelt.
  • Ellers, hvis den ene operand er dobbelt, konverteres den anden til dobbelt.
  • Ellers, hvis den ene operand flyder, konverteres den anden til float. I ovenstående kode er resultatet af i1 / i2 officielt 2; derfor er flt 2. Resultatet af binær, /, anvendes som den rette operand til binær operatør, =. Så den endelige værdi på 2 er en float (ikke en int).

ELSERE, INTEGER-FREMME VIL FØLGE SOM FØLGENDE:

  • Hvis begge operander er af samme type, finder ingen yderligere konvertering sted.
  • Ellers, hvis begge operander er signerede heltalstyper eller begge er usignerede heltalstyper, så konverteres operanden af ​​typen med den lavere heltalrangering til typen af ​​operanden med den højere rang.
  • Ellers, hvis den ene operand er underskrevet, og den anden er underskrevet, og hvis den usignerede operandtype er større end eller lig med rangen for den underskrevne operandtype, og hvis værdien af ​​den underskrevne operand er større end eller lig med nul, så den underskrevne operand konverteres til den usignerede operandtype (med rækkevidde taget i betragtning). Hvis den underskrevne operand er negativ, følger kompilatoren en algoritme og returnerer et tal, der muligvis ikke er acceptabelt for programmøren.
  • Ellers, hvis en operand er en signeret heltalstype, og den anden er en usigneret heltalstype, og hvis alle mulige værdier af typen af ​​operand med den usignerede heltalstype kan repræsenteres af den underskrevne heltalstype, vil den usignerede heltalstype konverteres til typen af ​​operanden af ​​den signerede heltalstype.
  • Ellers ville de to operander (f.eks. En char og en bool) blive konverteret til den usignerede heltalstype.

Flydende kampagne

Flydepunkttyper inkluderer "flyde", "dobbelt" og "lang dobbelt.”En flydende punkttype skal have mindst samme præcision som sin forgænger. Flydende promovering giver mulighed for konvertering fra float til dobbelt eller fra dobbelt til lang dobbelt.

Markørkonverteringer

En markør af en objekttype kan ikke tildeles en markør af en anden objekttype. Følgende kode kompileres ikke:

int id = 6;
int * intPtr = &id;
float idf = 2.5;
float * floatPtr = &idf;
intPtr = floatPtr; // fejl her

En nul pointer er en pointer, hvis adresse værdi er nul. En nulmarkør af en objekttype kan ikke tildeles en nulmarkør af en anden objekttype. Følgende kode kompileres ikke:

int id = 6;
int * intPtr = &id;
intPtr = 0;
float idf = 2.5;
float * floatPtr = &idf;
floatPtr = 0;
intPtr = floatPtr; // fejl her

En nul pointer const af en objekttype kan ikke tildeles en nul pointer const af en anden objekttype. Følgende kode kompileres ikke:

int id = 6;
int * intPtr = &id;
int * const intPC = 0;
float idf = 2.5;
float * floatPtr = &idf;
float * const floatPC = 0;
intPC = floatPC; // fejl her

En nul pointer kan få en anden adresse værdi for sin type. Følgende kode illustrerer dette:

float idf = 2.5;
float * floatPtr = 0;
floatPtr = &idf;
cout<<*floatPtr<<'\n';

Outputtet er 2.5.

Som forventet kan en nul pointer konstant ikke tildeles nogen adresse værdi af sin type. Følgende kode kompileres ikke:

float idf = 2.5;
float * const floatPC = 0;
floatPC = &idf; // fejl her

Imidlertid kan en nul pointer konstant tildeles en almindelig pointer, men af ​​samme type (dette kan forventes). Følgende kode illustrerer dette:

float idf = 2.5;
float * const floatPC = 0;
float * floatPter = &idf;
floatPter = floatPC; //OKAY
cout << floatPter << '\n';

Outputtet er 0.

To nullmarkørværdier af samme type sammenligner (==) ens.

En markør til en objekttype kan tildeles en markør, der skal annulleres. Følgende kode illustrerer dette:

float idf = 2.5;
float * floatPtr = &idf;
ugyldigt * vd;
vd = floatPtr;

Koden kompileres uden en advarsel eller fejlmeddelelse.

Funktion til markørkonverteringer

En markør til en funktion, der ikke kaster en undtagelse, kan tildeles en markør, der skal fungere. Følgende kode illustrerer dette:

#omfatte
ved hjælp af namespace std;
ugyldigt fn1 () noexcept

cout << "with noexcept" << '\n';

ugyldigt fn2 ()

// udsagn

ugyldig (* func1) () noexcept;
ugyldig (* func2) ();
int main ()

func1 = &fn1;
func2 = &fn2;
func2 = &fn1;
func2 ();
returnere 0;

Outputtet er uden undtagelse.

Boolske konverteringer

I C ++ inkluderer enheder, der kan resultere i falsk, "zero", "null pointer" og "null member pointer.”Alle andre enheder resulterer i sandt. Følgende kode illustrerer dette:

bool a = 0.0; cout << a <<'\n';
float * floatPtr = 0;
bool b = floatPtr; cout << b <<'\n';
bool c = -2.5; cout << c <<'\n';
bool d = +2.5; cout << d <<'\n';

Outputtet er:

0 // for falsk
0 // for falsk
1 // for sandt
1 // for sandt

Lvalue, prvalue og xvalue

Overvej følgende kode:

int id = 35;
int & id1 = id;
cout << id1 << '\n';

Outputtet er 35. I koden er id og id1 værdier, fordi de identificerer en placering (objekt) i hukommelsen. Outputtet 35 er en værdi. Enhver bogstavelig, undtagen en streng bogstavelig, er en værdi. Andre værdier er ikke så indlysende, som i de følgende eksempler. Overvej følgende kode:

int id = 62;
int * ptr = &id;
int * pter;

Ptr er en værdi, fordi den identificerer en placering (objekt) i hukommelsen. På den anden side er pter ikke en værdi. Pter er en markør, men den identificerer ikke nogen placering i hukommelsen (den peger ikke på noget objekt). Så pter er en værdi.

Overvej følgende kode:

ugyldigt fn ()

// udsagn

ugyldigt (* func) () = &fn;
flyde (* functn) ();

Fn () og (* func) () er udtryk for værdier, fordi de identificerer en enhed (funktion) i hukommelsen. På den anden side er (* functn) () ikke et lvalue-udtryk. (* functn) () er en markør til en funktion, men det identificerer ikke nogen enhed i hukommelsen (den peger ikke på nogen funktion i hukommelsen). Så (* functn) () er et udtryk for værdien.

Overvej nu følgende kode:

struct S

int n;
;
S obj;

S er en klasse, og obj er et objekt, der instantieres fra klassen. Obj identificerer et objekt i hukommelsen. En klasse er en generaliseret enhed. Så S identificerer ikke rigtig noget objekt i hukommelsen. S siges at være et unavngivet objekt. S er også et udtryk for værdien.

Fokus i denne artikel er på værdier. Prvalue betyder ren rvalue.

Xværdi

Xvalue står for Expiring Value. Midlertidige værdier udløber værdier. En lvalue kan blive en xvalue. En prværdi kan også blive en xværdi. Fokus i denne artikel er på værdier. En xvalue er en lvalue eller en ikke-navngivet rvalue-reference, hvis opbevaring kan genbruges (normalt fordi det er nær slutningen af ​​dets levetid). Overvej følgende kode, der fungerer:

struct S

int n;
;
int q = S ().n;

Udtrykket “int q = S ().n; ” kopierer den værdi n holder til q. S () er bare et middel; det er ikke et regelmæssigt anvendt udtryk. S () er en prvalue, hvis brug har konverteret den til en xvalue.

Lvalue-to-rvalue-konverteringer

Overvej følgende udsagn:

int ii = 70;

70 er en værdi (rværdi) og ii er en værdi. Overvej nu følgende kode:

int ii = 70;
int tt = ii;

I den anden erklæring er ii i en prvalues ​​situation, så ii bliver en prvalue der. Med andre ord konverterer compileren ii til en prværdi implicit. Når en lvalue bruges i en situation, hvor implementeringen forventer en prvalue, konverterer implementeringen lvaluen til en prvalue.

Array-to-Pointer-konverteringer

Overvej følgende kode, der fungerer:

char * p;
char q [] = 'a', 'b', 'c';
p = & q [0];
++p;
cout<<*p<<'\n';

Outputtet er b. Den første sætning er et udtryk og er en markør til et tegn. Men til hvilken karakter peger udsagnet? - Ingen karakter. Så det er en værdi og ikke en værdi. Den anden sætning er en matrix, hvor q [] er et udtryk for værdien. Den tredje sætning forvandler prværdien, p, til et udtryk for værdien, der peger på det første element i arrayet.

Funktion-til-markørkonverteringer

Overvej følgende program:

#omfatte
ved hjælp af namespace std;
ugyldig (* func) ();
ugyldigt fn ()

// udsagn

int main ()

func = &fn;
returnere 0;

Udtrykket "ugyldigt (* func) ();" er en markør til en funktion. Men til hvilken funktion peger udtrykket? - Ingen funktion. Så det er en værdi og ikke en værdi. Fn () er en funktionsdefinition, hvor fn er et udtryk for en værdi. I main (), “func = &fn;”Forvandler prvalue, func, til et lvalue-udtryk, der peger på funktionen, fn ().

Midlertidige materialiseringskonverteringer

I C ++ kan en prværdi konverteres til en xværdi af samme type. Følgende kode illustrerer dette:

struct S

int n;
;
int q = S ().n;

Her er prværdien, S (), konverteret til en xværdi. Som en x-værdi ville det ikke vare længe - se mere forklaring ovenfor.

Kvalifikationskonverteringer

En cv-kvalificeret type er en type, der er kvalificeret af det reserverede ord, "const", og / eller det reserverede ord, "flygtigt.”

Cv-kvalifikation er også rangeret. Ingen cv-kvalifikation er mindre end "const" kvalifikation, hvilket er mindre end "const flygtig" kvalifikation. Ingen cv-kvalifikation er mindre end "flygtig" kvalifikation, hvilket er mindre end "const flygtig" kvalifikation. Så der er to strømme af kvalifikationsrangering. En type kan være mere cv-kvalificeret end en anden.

En lavere prvalue cv-kvalificeret type kan konverteres til en mere cv-kvalificeret prvalue type. Begge typer skal være pointer-to-cv.

Konklusion

C ++ enheder kan konverteres fra en type til en relateret type implicit eller eksplicit. Programmøren skal dog forstå, hvad der kan konverteres, og hvad der ikke kan konverteres, og til hvilken form. Konvertering kan finde sted i følgende domæner: Integrale konverteringer, flydende punktkonverteringer, flydende-integrerede konverteringer, almindelige aritmetiske konverteringer, markørkonverteringer, funktion til markørkonverteringer, boolske konverteringer, konvertering af værdi til værdi, array-til-markørkonverteringer , Funktion-til-markørkonverteringer, midlertidige materialiseringskonverteringer og kvalifikationskonverteringer.

Mus Sådan vender du musens og touchpadsens rulle retning i Windows 10
Sådan vender du musens og touchpadsens rulle retning i Windows 10
Mus og Touchpads gør ikke kun computing let, men mere effektiv og mindre tidskrævende. Vi kan ikke forestille os et liv uden disse enheder, men det er...
Mus Sådan ændres musemarkør og markørstørrelse, farve og skema på Windows 10
Sådan ændres musemarkør og markørstørrelse, farve og skema på Windows 10
Musemarkøren og markøren i Windows 10 er meget vigtige aspekter af operativsystemet. Dette kan også siges om andre operativsystemer, så i sandhed er d...
Gratis og open source-spilmotorer til udvikling af Linux-spil
Denne artikel dækker en liste over gratis og open source-spilmotorer, der kan bruges til at udvikle 2D- og 3D-spil på Linux. Der er mange sådanne spil...