Wyjście jest 2, 2, co oznacza, że program zwrócił pierwiastek kwadratowy 5 jako 2, a pierwiastek kwadratowy 8 również jako 2. Tak więc pierwsze dwa stwierdzenia w główny() Funkcja wzbudziła odpowiedzi pierwiastka kwadratowego 5 i pierwiastka kwadratowego 8. W tym artykule nie omawia podłogi ani sufitu w C++. Raczej w tym artykule omówiono konwersję jednego typu C ++ na inny odpowiedni typ C ++; wskazując na wszelkie przybliżenie wartości wykonanej, utrata precyzji lub ograniczenie dodane lub usunięte. Podstawowa znajomość C ++ jest warunkiem zrozumienia tego artykułu.
Treść artykułu
Integralne konwersje
Integralne konwersje to konwersje całkowitowe. Unsigned Liczbuski obejmują „niepodpisany char”, „niepodpisany krótki int”, „unsigned int”, „unsigned long int” i „niepodpisane długie int.„Odpowiednie podpisane liczby całkowite obejmują„ podpisany char ”,„ Short Int ”,„ int ”,„ Long Int ”i„ Long Long Int.„Każdy typ int powinien być utrzymywany w tylu bajtach, co jego poprzednik. W przypadku większości systemów jeden typ jednostki można przekonwertować na odpowiedni typ. Problem występuje podczas konwersji z większego rodzaju zasięgu na mniejszy typ zakresu lub podczas konwersji podpisanej liczby w odpowiednią liczbę niepodpisaną.
Każdy kompilator ma maksymalną wartość, jaką może przyjąć dla krótkiego int. Jeśli liczba wyższa niż ta maksimum, przeznaczona do INT, jest przypisana do krótkiego INT, kompilator będzie śledzić jakiś algorytm i zwróci liczbę w zakresie krótkiego int. Jeśli programista ma szczęście, kompilator ostrzega przed kłopotami z użyciem niewłaściwej konwersji. To samo wyjaśnienie dotyczy konwersji innych typów int.
Użytkownik powinien zapoznać się z dokumentacją kompilatora, aby określić wartości ograniczające dla każdego typu encji.
Jeśli ujemny podpisany krótki numer INT ma zostać przekonwertowany w niepodpisany krótki numer INT, kompilator będzie śledzić jakiś algorytm i zwróci liczbę dodatnią w zakresie niepodpisanego krótkiego int. Tego rodzaju konwersji należy unikać. To samo wyjaśnienie dotyczy konwersji innych typów int.
Każdy numer liczbowy, z wyjątkiem 0, można przekonwertować na boolean true. 0 jest przekonwertowane na boolean false. Poniższy kod to ilustruje:
int a = -27647;1 oznacza prawdziwe, a 0 oznacza fałszywe na wyjściu
Przewijające się konwersje
Typy punktów zmiennoprzecinkowych obejmują „Float”, „Double” i „Long Double.„Typy punktów zmiennoprzecinkowych nie są zgrupowane w podpisane i niepodpisane, jak liczby całkowite. Każdy typ może mieć podpisany lub niepodpisany numer. Typ zmiennoprzecinkowy powinien mieć przynajmniej taką samą precyzję jak jego poprzednik. To znaczy „długa podwójna” powinna mieć równą lub większą precyzję jak „podwójne”, a „podwójne” powinny mieć równą lub większą precyzję w stosunku do „pływaka."
Pamiętaj, że zakres typu zmiennoprzecinkowego nie jest ciągły; jest raczej w małych krokach. Im większa precyzja typu, tym mniejsze kroki i tym większa liczba bajtów do przechowywania liczby. Tak więc, gdy liczba zmiennoprzecinkowa jest konwertowana z niższego typu precyzyjnego na wyższy typ precyzyjny, programista musi zaakceptować fałszywy wzrost precyzji i możliwy wzrost liczby bajtów dla magazynu numeru. Gdy liczba zmiennoprzecinkowa jest konwertowana z wyższego typu precyzyjnego na niższy typ precyzyjny, programista musi zaakceptować utratę precyzji. Jeśli liczba bajtów dla magazynu numerycznych musi zostać zmniejszona, kompilator będzie śledzić jakiś algorytm i zwróci liczbę jako zastępcę (co prawdopodobnie nie jest tym, czego chce programista). Pamiętaj także o problemach z odległości.
Pliczące konwersje integracyjne
Liczba zmiennoprzecinkowa jest konwertowana na liczbę całkowitą poprzez obcięcie części ułamkowej. Poniższy kod to ilustruje:
Float f = 56.953;Gdy liczba całkowita jest przekonwertowana na pływak, wartość wyświetlana jako pływak jest taka sama, jak wpisana jako liczba całkowita. Jednak równoważny float może być dokładną wartością lub mieć niewielką różnicę ułamkową, która nie jest wyświetlana. Powodem różnicy ułamkowej jest to, że liczby zmiennoprzecinkowych są reprezentowane w komputerze w małych ułamkowych etapach, a zatem reprezentowanie całkowitej liczby całkowitej byłoby zbiegiem okoliczności. Tak więc, chociaż liczba całkowita wyświetlana jako pływak jest taka sama, jak pisano, wyświetlacz może być przybliżeniem tego, co jest przechowywane.
Ranking konwersji liczb całkowitych
Każdy typ liczb całkowitych ma ranga, która została mu podana. Ten ranking pomaga w konwersji. Ranking jest względny; Rangi nie są na stałym poziomie. Z wyjątkiem Char i podpisanego Char, żadne dwa podpisane liczby całkowite nie mają takiej samej rangi (zakładając, że Char jest podpisany). Niepodpisane typy liczb całkowitych mają taki sam ranking, jak odpowiadające im podpisane typy całkowitej. Ranking jest następujący:
Integralne promocje
Integralne promocje to promocje całkowitowe. Nie ma powodu, dla którego całkowitej mniejszej liczby bajtów nie może być reprezentowana przez liczbę całkowitą większych bajtów. Promocje liczb całkowitych dotyczy wszystkiego, co następuje:
Zwykłe konwersje arytmetyczne
Rozważ następujący kod:
float f = 2.5;C ++ ma zwykle konwersje arytmetyczne, które programista musi wiedzieć, aby uniknąć błędów w kodowaniu. Zwykłe konwersje arytmetyczne na operatorach binarnych są następujące:
W przeciwnym razie promocja liczb całkowita miałaby miejsce w następujący sposób:
Promocja zmiennoprzecinkowa
Typy punktów zmiennoprzecinkowych obejmują „Float”, „Double” i „Long Double.„Typ zmiennoprzecinkowy powinien mieć co najmniej taką samą precyzję jak jego poprzednik. Promocja zmiennoprzecinkowa pozwala na konwersję z pływaków do podwójnej lub z podwójnej do długiego do długiego.
Konwersje wskaźników
Wskaźnika jednego typu obiektu nie można przypisać do wskaźnika innego typu obiektu. Poniższy kod nie skompiluje:
int id = 6;Wskaźnik zerowy to wskaźnik, którego wartość adresu wynosi zero. Nie można przypisać wskaźnika zerowego jednego obiektu do wskaźnika zerowego innego typu obiektu. Poniższy kod nie skompiluje:
int id = 6;Nie można przypisać wskaźnika zerowego jednego typu obiektu do wskaźnika zerowego, stał. Poniższy kod nie skompiluje:
int id = 6;Wskaźnik zerowy może otrzymać inną wartość adresu dla swojego typu. Poniższy kod to ilustruje:
float idf = 2.5;Wyjście jest 2.5.
Zgodnie z oczekiwaniami, stałą wskaźnika zerowego nie można przypisać żadnej wartości adresu tego typu. Poniższy kod nie skompiluje:
float idf = 2.5;Jednak stałą wskaźnika zerowego można przypisać do zwykłego wskaźnika, ale tego samego typu (należy się tego spodziewać). Poniższy kod to ilustruje:
float idf = 2.5;Wyjście jest 0.
Dwie wartości zerowych wskaźników tego samego typu Porównaj (==) równe.
Wskaźnik do typu obiektu można przypisać do wskaźnika do pustki. Poniższy kod to ilustruje:
float idf = 2.5;Kod kompikuje się bez komunikatu ostrzegawczego lub błędu.
Funkcja do konwersji wskaźnika
Wskaźnik do funkcji, która nie rzuciłaby wyjątku, można przypisać do wskaźnika do funkcjonowania. Poniższy kod to ilustruje:
#włączaćWyjście jest bez z wyjątkiem.
Boolean konwersje
W C ++ jednostki, które mogą skutkować fałszem, obejmują „zero”, „null wskaźnik” i „null wskaźnik członka.„Wszystkie inne podmioty powodują prawdziwe. Poniższy kod to ilustruje:
bool a = 0.0; Cout << a <<'\n';Wyjście to:
0 // dla fałszuLValue, PrValue i XValue
Rozważ następujący kod:
int id = 35;Wyjście jest 35. W kodzie ID i ID1 są LVALES, ponieważ identyfikują lokalizację (obiekt) w pamięci. Wyjście 35 jest pralelem. Wszelkie dosłowne, z wyjątkiem dosłownego sznurka, jest pralue. Inne praledy nie są tak oczywiste, jak w następujących przykładach. Rozważ następujący kod:
int id = 62;PTR to LValue, ponieważ identyfikuje lokalizację (obiekt) w pamięci. Z drugiej strony Pter nie jest LValue. Pter jest wskaźnikiem, ale nie identyfikuje żadnej lokalizacji w pamięci (nie wskazuje na żaden obiekt). Więc Pter jest pralelem.
Rozważ następujący kod:
void fn ()Fn () i (*func) () to wyrażenia LVALUE, ponieważ identyfikują one (funkcję) w pamięci. Z drugiej strony (*functn) () nie jest wyrażeniem LValue. (*functn) () jest wskaźnikiem funkcji, ale nie identyfikuje żadnej jednostki w pamięci (nie wskazuje na żadną funkcję w pamięci). Tak więc (*functn) () jest wyrażeniem pralue.
Teraz rozważ następujący kod:
struktura sS jest klasą, a OBJ to obiekt utworzony z klasy. OBJ identyfikuje obiekt w pamięci. Klasa to jednostka uogólniona. Tak naprawdę nie identyfikuje żadnego obiektu w pamięci. Mówi się, że jest nienazwanym obiektem. S jest również wyrażeniem pralera.
Ten artykuł koncentruje się na pralelach. Prvalue oznacza czystą relację.
XValue
XValue oznacza wygasną wartość. Wartości tymczasowe wygasają wartości. LValue może stać się wartością X. Pralela może również stać się xalecem. Ten artykuł koncentruje się na pralelach. WVALUE to lValue lub nienazwane odniesienie RValue, którego przechowywanie można ponownie wykorzystać (zwykle dlatego, że znajduje się pod koniec swojego życia). Rozważ następujący kod, który działa:
struktura sWyrażenie „int q = s ().N;" kopiuje jakąkolwiek wartość n utrzymuje Q. S () to tylko sposób; Nie jest to regularnie używane wyrażenie. S () to pralera, której użycie przekonwertowało go na wartość xValue.
Konwersje LVALUE-to-Ralue
Rozważ następujące stwierdzenie:
int II = 70;70 to pralue (RValue), a II to lowca. Teraz rozważ następujący kod:
int II = 70;W drugim stwierdzeniu II znajduje się w sytuacji pralela, więc ii staje się tam. Innymi słowy, kompilator przekształca II w niejawnie. To znaczy, gdy lowca jest używana w sytuacji, w której implementacja oczekuje pralela, implementacja przekształca lValue na pralera.
Konwersje tablicy do wskaźnika
Rozważ następujący kod, który działa:
char* p;Wyjście jest B. Pierwsze stwierdzenie jest wyrażeniem i jest wskaźnikiem postaci. Ale na który postać jest wskazującym? - Brak charakteru. Jest to więc pralera, a nie lValue. Drugie stwierdzenie to tablica, w której Q [] jest wyrażeniem LValue. Trzecie stwierdzenie przekształca pralue, p, w wyrażenie LValue, które wskazuje na pierwszy element tablicy.
Konwersje funkcji do punktu
Rozważ następujący program:
#włączaćWyrażenie „void (*func) ();” jest wskaźnikiem funkcji. Ale do której funkcji jest wyrażenie wskazującym? - Brak funkcji. Jest to więc pralera, a nie lValue. Fn () jest definicją funkcji, w której FN jest wyrażeniem LValue. W Main (), „func = &fn;„Zmienia pralue, FUNC, w wyrażenie LValue, które wskazuje na funkcję, fn ().
Tymczasowe konwersje materializacyjne
W C ++ pralera można przekonwertować na XValue tego samego typu. Poniższy kod to ilustruje:
struktura sTutaj PrValue, s (), został przekonwertowany na xvalue. Jako xvalue nie trwałoby to długo - zobacz więcej wyjaśnień powyżej.
Konwersje kwalifikacyjne
Typ kwalifikowanym przez CV jest typem kwalifikowanym przez zarezerwowane słowo „const” i/lub zarezerwowane słowo „niestabilne."
Kwalifikacja CV jest również rankingowa. Żadna kwalifikacja CV nie jest mniejsza niż kwalifikacja „const”, która jest mniejsza niż „const niestabilna” kwalifikacje. Żadne kwalifikacja CV nie jest niższa niż „niestabilna” kwalifikacja, która jest mniejsza niż „niestabilna” kwalifikacja. Istnieją więc dwa strumienie rankingu kwalifikacji. Jeden typ może być bardziej kwalifikowany CV niż inny.
Niższy typ CV-kwalifikowany CV można przekonwertować na bardziej kwalifikowany przez CV typu PrValue. Oba typy powinny być wskaźnikiem do CV.
Wniosek
Podmioty C ++ można przeliczyć z jednego typu na powiązany typ lub jawnie. Jednak programista musi zrozumieć, co można przekonwertować, a czego nie można przekonwertować, i w jakiej formie. Konwersja może odbywać się w następujących domenach: Konwersje integralne, konwersje zmiennoprzecinkowe, konwersje pływające-integracyjne, zwykłe konwersje arytmetyczne, konwersje wskaźników, funkcja konwersji wskaźnika, konwersje boolec , Konwersje funkcjonalne do punktu, tymczasowe konwersje materializacyjne i konwersje kwalifikacyjne.