C ++

C ++ standardkonverteringer

C ++ standardkonverteringer
Det er to enhetstyper i C ++, de grunnleggende typene og sammensatte typer. De grunnleggende typene er skalartypene. Sammensatte typer er resten av enhetstyper. Konvertering kan finne sted fra en enhetstype til en annen passende type. Tenk på følgende program:

#inkludere
#inkludere
bruker navneområde std;
int main ()

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

Resultatet er 2, 2, som betyr at programmet har returnert kvadratroten på 5 som 2 og kvadratroten på 8 også som 2. Så, de to første uttalelsene i hoved() funksjonen har lagt svar på kvadratroten på 5 og kvadratroten på 8. Denne artikkelen diskuterer ikke gulv eller tak i C++. Snarere diskuterer denne artikkelen konvertering av en C ++ -type til en annen passende C ++ -type; som indikerer enhver tilnærming i verdi, tap av presisjon eller begrensning som er lagt til eller fjernet. Grunnleggende kunnskap om C ++ er en forutsetning for å forstå denne artikkelen.

Artikkelinnhold

  • Integrerte konverteringer
  • Flytende konverteringer
  • Flytende integrerte konverteringer
  • Heltall konverteringsrangering
  • Integrerte kampanjer
  • Vanlige aritmetiske konverteringer
  • Flytende kampanje
  • Pointer Conversions
  • Funksjon til pekerkonverteringer
  • Boolske konverteringer
  • Lvalue, prvalue og xvalue
  • Xvalue
  • Lvalue-to-rvalue Conversions
  • Array-to-Pointer Conversions
  • Funksjon-til-peker-konverteringer
  • Midlertidige materialiseringskonverteringer
  • Kvalifiseringskonverteringer
  • Konklusjon

Integrerte konverteringer

Integrerte konverteringer er heltallskonverteringer. Usignerte heltall inkluderer "usignert røye", "usignert kort int", "usignert int", "usignert lang int" og "usignert lang lang int.”De tilsvarende signerte heltallene inkluderer“ signert char ”,“ short int ”,“ int ”,“ long int ”og“ long long int.”Hver int-type skal holdes i like mange byte som forgjengeren. For de fleste systemer kan en enhetstype konverteres til en tilsvarende type uten problemer. Problemet oppstår når du konverterer fra en større rekkevidde til en mindre rekkevidde, eller når du konverterer et signert nummer til et tilsvarende usignert nummer.

Hver kompilator har en maksimal verdi som den kan ta for kort int. Hvis et tall som er høyere enn det maksimale, ment for en int, er tilordnet den korte int, vil kompilatoren følge noen algoritme og returnere et tall innenfor området for kort int. Hvis programmereren er heldig, vil kompilatoren advare om problemer med å bruke upassende konvertering. Den samme forklaringen gjelder konvertering av andre int-typer.

Brukeren bør konsultere dokumentasjonen til kompilatoren for å bestemme grenseverdiene for hver enhetstype.

Hvis et negativt signert kort int-nummer skal konverteres til et usignert kort int-nummer, vil kompilatoren følge en eller annen algoritme og returnere et positivt tall innenfor området for den usignerte korte int-tallet. Denne typen konvertering bør unngås. Den samme forklaringen gjelder konverteringer av andre int-typer.

Ethvert heltall, unntatt 0, kan konverteres til boolsk sann. 0 konverteres til boolsk falsk. Følgende kode illustrerer dette:

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

1 for sant
1 for sant
0 for falsk

Flytende konverteringer

Flytpunkttyper inkluderer "float", "double" og "long double.”Flytpunkttyper er ikke gruppert i signerte og usignerte, som heltall. Hver type kan ha et signert eller usignert nummer. En flytende punkttype skal ha minst samme presisjon som forgjengeren. Det vil si at "lang dobbel" skal ha lik eller større presisjon til "dobbel", og "dobbel" skal ha lik eller større presisjon til å "flyte.”

Husk at rekkevidden til en flytende punkttype ikke er kontinuerlig; heller, det er i små trinn. Jo større presisjonen til typen, jo mindre trinn, og jo større antall byte for å lagre nummeret. Så når et flytende nummer konverteres fra en lavere presisjonstype til en høyere presisjonstype, må programmereren godta en falsk økning i presisjon og en mulig økning i antall byte for nummerlagring. Når et flytende nummer konverteres fra en høyere presisjonstype til en lavere presisjonstype, må programmereren akseptere et tap i presisjon. Hvis antall byte for nummerlagring må reduseres, vil kompilatoren følge en eller annen algoritme og returnere et tall som erstatning (som sannsynligvis ikke er det programmereren vil ha). Husk også problemer utenfor rekkevidden.

Flytende integrerte konverteringer

Et flytende nummer konverteres til et helt tall ved å avkorte brøkdelen. Følgende kode illustrerer dette:

flyte f = 56.953;
int i = f;
cout<Resultatet er 56. Områdene for flottør og heltall må være kompatible.

Når et heltall blir konvertert til en flottør, er verdien som vises som en flottør den samme som ble skrevet inn som et heltall. Imidlertid kan flyteekvivalenten være den nøyaktige verdien eller ha en liten brøkforskjell som ikke vises. Årsaken til brøkforskjellen er at flytende tall blir representert i datamaskinen i små brøkstrinn, og det vil derfor være en tilfeldighet å representere heltallet nøyaktig. Så selv om heltallet som vises som en flottør er det samme som ble skrevet, kan skjermen være en tilnærming til det som er lagret.

Heltall konverteringsrangering

Enhver heltypstype har en rang som er gitt til den. Denne rangeringen hjelper til med konvertering. Rangeringen er relativ; rekkene er ikke på faste nivåer. Bortsett fra røye og signert røye har ingen to signerte heltall samme rang (forutsatt at røye er signert). Usignerte heltallstyper har samme rangering som deres tilsvarende signerte heltallstyper. Rangeringen er som følger:

  • Forutsatt at røye er signert, har røye og signert røye samme rang.
  • Rangeringen til en signert heltallstype er større enn rangen til en signert heltallstype med et mindre antall lagringsbyte. Så, rangeringen av signert lang lang int er større enn rangen for signert lang int, som er større enn rangen til signert int, som er større enn rangen for signert kort int, som er større enn rangen til signert rød.
  • Rangeringen til en hvilken som helst usignert heltallstype er lik rangeringen til den tilsvarende signerte heltallstypen.
  • Rangeringen av usignert røye er lik rangeringen av signert røye.
  • bool har minst rang; dens rang er mindre enn for signert røye.
  • char16_t har samme rang som kort int. char32_t har samme rang som int. For g ++ kompilatoren har wchar_t samme rang som int.

Integrerte kampanjer

Integrerte kampanjer er helhetskampanjer. Det er ingen grunn til at et heltall med færre byte ikke kan representeres av et heltall med større byte. Integer Promotions tar for seg alt som følger:

  • En signert kort int (to byte) kan konverteres til en signert int (fire byte). En usignert kort int (to byte) kan konverteres til en usignert int (fire byte). Merk: konvertering av en kort int til en lang int eller en lang lang int fører til bortkastet lagring (objektplassering) byte og bortkastet minne. Bool, char16_t, char32_t og wchar_t er unntatt fra denne kampanjen (med g ++ kompilator har char32_t og wchar_t samme antall byte).
  • Med g ++ kompilatoren kan en char16_t-type konverteres til en signert int-type eller en usignert int-type; en char32_t-type kan konverteres til en signert int-type eller en usignert int-type; og en wchar_t-type kan konverteres til en signert eller usignert int-type.
  • En bool-type kan konverteres til en int-type. I dette tilfellet blir true 1 (fire byte) og false blir 0 (fire byte). Int kan signeres eller signeres.
  • Heltallkampanjer eksisterer også for unscoped-oppregningstype - se senere.

Vanlige aritmetiske konverteringer

Vurder følgende kode:

flyte f = 2.5;
int i = f;
cout<Koden kompileres uten å indikere noen advarsel eller feil, og gir resultatet av 2, som sannsynligvis ikke er det som var forventet. = er en binær operatør fordi den tar en venstre og høyre operand. Vurder følgende kode:

int i1 = 7;
int i2 = 2;
flyte flt = i1 / i2;
cout<Resultatet er 3, men dette er galt; det skulle være 3.5. Divisjonsoperatøren, /, er også en binær operatør.

C ++ har vanlige aritmetiske konverteringer som programmereren må vite for å unngå feil i kodingen. De vanlige aritmetiske konverteringene på binære operatører er som følger:

  • Hvis en av operandene er av typen "lang dobbel", blir den andre konvertert til lang dobbel.
  • Ellers, hvis en av operandene er doble, blir den andre konvertert til dobbelt.
  • Ellers, hvis en av operandene er flytende, vil den andre bli konvertert til float. I koden ovenfor er resultatet av i1 / i2 offisielt 2; det er derfor flt er 2. Resultatet av binær, /, blir brukt som riktig operand til binær operator, =. Så den endelige verdien av 2 er en flottør (ikke en int).

ELSERE, INTEGER-KAMPANJER VIL FØLGE SOM FØLGER:

  • Hvis begge operandene er av samme type, skjer ingen videre konvertering.
  • Ellers, hvis begge operandene er signerte heltallstyper eller begge er usignerte heltallstyper, så blir operanden av typen med lavere heltallrangering konvertert til typen operand med høyere rang.
  • Ellers, hvis en operand er signert og den andre ikke er signert, og hvis den usignerte operand-typen er større enn eller lik rangeringen til den signerte operand-typen, og hvis verdien av den signerte operanden er større enn eller lik null, så den signerte operanden blir konvertert til den usignerte operand-typen (med rekkevidde tatt i betraktning). Hvis den signerte operanden er negativ, vil kompilatoren følge en algoritme og returnere et tall som kanskje ikke er akseptabelt for programmereren.
  • Ellers, hvis en operand er en signert heltallstype, og den andre er en usignert heltallstype, og hvis alle mulige verdier av typen operand med den usignerte heltallstypen kan representeres av den signerte heltallstypen, vil den usignerte helgetypen konverteres til typen operand av signert heltallstype.
  • Ellers ville de to operandene (for eksempel en røye og en bool) bli konvertert til den usignerte heltallstypen.

Flytende kampanje

Flytpunkttyper inkluderer "flyt", "dobbelt" og "langt dobbeltrom.”En flytende punkttype skal ha minst samme presisjon som forgjengeren. Flytende kampanje tillater konvertering fra float til dobbelt eller fra dobbelt til langt dobbelt.

Pointer Conversions

En peker av en objekttype kan ikke tilordnes en peker av en annen objekttype. Følgende kode samles ikke:

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

En nullpeker er en peker hvis adresseverdi er null. En nullpeker av en objekttype kan ikke tilordnes en nullpeker av en annen objekttype. Følgende kode samles ikke:

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

En nullpekerkonst av en objekttype kan ikke tildeles en nullpekerkonst av en annen objekttype. Følgende kode samles ikke:

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

En nullpeker kan få en annen adresseverdi for sin type. Følgende kode illustrerer dette:

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

Resultatet er 2.5.

Som forventet kan en nullpekerkonstant ikke tildeles noen adresseverdi av typen. Følgende kode samles ikke:

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

Imidlertid kan en nullpekerkonstant tilordnes til en vanlig peker, men av samme type (dette kan forventes). Følgende kode illustrerer dette:

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

Resultatet er 0.

To nullpekerverdier av samme type sammenligner (==) like.

En peker til en objekttype kan tilordnes en peker som skal ugyldiggjøres. Følgende kode illustrerer dette:

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

Koden kompileres uten advarsel eller feilmelding.

Funksjon til pekerkonverteringer

En peker til en funksjon som ikke gir et unntak, kan tilordnes en peker som skal fungere. Følgende kode illustrerer dette:

#inkludere
bruker navneområde std;
ugyldig fn1 () noexcept

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

ugyldig fn2 ()

// uttalelser

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

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

Resultatet er uten unntak.

Boolske konverteringer

I C ++ inkluderer enheter som kan resultere i falsk "null", "nullpeker" og "nullmedlemspeker.”Alle andre enheter resulterer i sant. 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';

Utgangen er:

0 // for falsk
0 // for falsk
1 // for sant
1 // for sant

Lvalue, prvalue og xvalue

Vurder følgende kode:

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

Resultatet er 35. I koden er id og id1 verdier fordi de identifiserer en plassering (objekt) i minnet. Utgangen 35 er en verdi. Enhver bokstavelig, bortsett fra en streng bokstavelig, er en verdi. Andre verdier er ikke så åpenbare, som i eksemplene som følger. Vurder følgende kode:

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

Ptr er en verdi fordi den identifiserer en plassering (objekt) i minnet. På den annen side er pter ikke en verdi. Pter er en peker, men den identifiserer ikke noe sted i minnet (det peker ikke på noe objekt). Så, pter er en verdi.

Vurder følgende kode:

ugyldig fn ()

// uttalelser

ugyldig (* func) () = &fn;
flyte (* functn) ();

Fn () og (* func) () er uttrykksverdier fordi de identifiserer en enhet (funksjon) i minnet. På den annen side er (* functn) () ikke et lvalueuttrykk. (* functn) () er en peker til en funksjon, men den identifiserer ikke noen enhet i minnet (den peker ikke på noen funksjon i minnet). Så, (* functn) () er et prvalueuttrykk.

Vurder nå følgende kode:

struct S

int n;
;
S obj;

S er en klasse og obj er et objekt instantiert fra klassen. Obj identifiserer et objekt i minnet. En klasse er en generalisert enhet. Så S identifiserer egentlig ikke noe objekt i minnet. S sies å være et ikke navngitt objekt. S er også et verdifullt uttrykk.

Fokuset i denne artikkelen er på verdier. Prvalue betyr ren rvalue.

Xvalue

Xvalue står for Expiring Value. Midlertidige verdier er verdier som utløper. En lvalue kan bli en xvalue. En prverdi kan også bli en xverdi. Fokuset i denne artikkelen er på verdier. En xvalue er en lvalue eller en ikke-navngitt rvalue-referanse hvis lagring kan gjenbrukes (vanligvis fordi den er nær slutten av levetiden). Vurder følgende kode som fungerer:

struct S

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

Uttrykket “int q = S ().n; ” kopierer hvilken verdi n holder til q. S () er bare et middel; det er ikke et vanlig uttrykk. S () er en verdi som har konvertert den til en x-verdi.

Lvalue-to-rvalue Conversions

Tenk på følgende utsagn:

int ii = 70;

70 er en verdi (rverdi) og ii er en verdi. Vurder nå følgende kode:

int ii = 70;
int tt = ii;

I den andre uttalelsen er ii i situasjonen til en prvalue, så ii blir en prvalue der. Med andre ord konverterer kompilatoren ii til en prverdi implisitt. Når en verdi brukes i en situasjon der implementeringen forventer en verdi, konverterer implementeringen verdien til en verdi.

Array-to-Pointer Conversions

Vurder følgende kode som fungerer:

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

Resultatet er b. Den første utsagnet er et uttrykk og er en pekepinn til et tegn. Men til hvilken karakter peker påstanden? - Ingen karakter. Så det er en verdi og ikke en verdi. Den andre setningen er en matrise der q [] er et uttrykk for en verdi. Den tredje setningen gjør om prvalue, p, til et lvalueuttrykk, som peker på det første elementet i matrisen.

Funksjon-til-peker-konverteringer

Tenk på følgende program:

#inkludere
bruker navneområde std;
ugyldig (* func) ();
ugyldig fn ()

// uttalelser

int main ()

func = &fn;
retur 0;

Uttrykket “ugyldig (* func) ();” er en peker til en funksjon. Men til hvilken funksjon er uttrykket som peker? - Ingen funksjon. Så det er en verdi og ikke en verdi. Fn () er en funksjonsdefinisjon, der fn er et lvalueuttrykk. I hovedsak (), “func = &fn;”Forvandler prvalue, func, til et lvalueuttrykk som peker på funksjonen, fn ().

Midlertidige materialiseringskonverteringer

I C ++ kan en prverdi konverteres til en xverdi av samme type. Følgende kode illustrerer dette:

struct S

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

Her er prverdien, S (), konvertert til en xverdi. Som en x-verdi ville det ikke vare lenge - se mer forklaring ovenfor.

Kvalifiseringskonverteringer

En cv-kvalifisert type er en type som er kvalifisert av det reserverte ordet, "const", og / eller det reserverte ordet, "flyktig.”

Cv-kvalifisering er også rangert. Ingen cv-kvalifisering er mindre enn "const" kvalifisering, som er mindre enn "const flyktig" kvalifisering. Ingen cv-kvalifisering er mindre enn "flyktig" kvalifisering, som er mindre enn "const flyktig" kvalifisering. Så det er to strømmer av kvalifiseringsrangering. En type kan være mer cv-kvalifisert enn en annen.

En lavere cV-kvalifisert type kan konverteres til en mer cv-kvalifisert prvalue-type. Begge typene skal være peker-til-cv.

Konklusjon

C ++ enheter kan konverteres fra en type til en relatert type implisitt eller eksplisitt. Imidlertid må programmereren forstå hva som kan konverteres og hva som ikke kan konverteres, og til hvilken form. Konvertering kan finne sted i følgende domener: Integrerte konverteringer, flytende punktkonverteringer, flytende integrerte konverteringer, vanlige aritmetiske konverteringer, pekerkonverteringer, funksjon til pekerkonverteringer, boolske konverteringer, konvertering av verdi til verdi, array-til-peker-konverteringer , Funksjon-til-peker-konverteringer, midlertidige materialiseringskonverteringer og kvalifiseringskonverteringer.

Hvordan bruke GameConqueror Cheat Engine i Linux
Artikkelen dekker en guide om bruk av GameConqueror-juksemotoren i Linux. Mange brukere som spiller spill på Windows bruker ofte "Cheat Engine" -appli...
Beste spillkonsollemulatorer for Linux
Denne artikkelen vil liste opp populære programvare for spillkonsollemulering tilgjengelig for Linux. Emulation er et programvarekompatibilitetslag so...
Beste Linux Distros for spill i 2021
Linux-operativsystemet har kommet langt fra det originale, enkle, serverbaserte utseendet. Dette operativsystemet har forbedret seg enormt de siste år...