Die Ausgabe ist 2, 2, Dies bedeutet, dass das Programm die Quadratwurzel von 5 als 2 und die Quadratwurzel von 8 auch als 2 zurückgegeben hat. Also die ersten beiden Aussagen in der hauptsächlich() Funktion hat die Antworten auf die Quadratwurzel von 5 und die Quadratwurzel von 8 geführt. In diesem Artikel wird keine Bodenbeläge oder Decke in C besprochen++. In diesem Artikel wird vielmehr die Konvertierung eines C ++ -Typs in einen anderen geeigneten C ++ -Typ erörtert. Angeben einer Annäherung an Wert, Präzision oder Einschränkung hinzugefügt oder entfernt. Grundkenntnisse von C ++ ist eine Voraussetzung, um diesen Artikel zu verstehen.
Artikelinhalt
Integrale Konvertierungen
Integrale Konvertierungen sind Ganzzahlkonvertierungen. Nicht signierte Ganzzahlen umfassen „vorzeichenloses Zeichen“, „nicht signiertes kurzes int“, „nicht signiert int“, „nicht signiertes langes int“ und „nicht signiertes lange int int int."Die entsprechenden unterzeichneten Ganzzahlen enthalten" Signed Char "," Short Int "," int "," Long int "und" Long Long Int ".”Jeder INT -Typ sollte in so vielen Bytes wie sein Vorgänger gehalten werden. Für die meisten Systeme kann ein Entitätstyp ohne Probleme in einen entsprechenden Typ konvertiert werden. Das Problem tritt beim Konvertieren von einem größeren Bereichstyp in einen kleineren Bereichstyp oder beim Umwandeln einer signierten Zahl in eine entsprechende nicht signierte Zahl auf.
Jeder Compiler hat einen maximalen Wert, den er für den kurzen Int dauern kann. Wenn eine Zahl höher als das Maximum, das für einen INT bestimmt ist, dem kurzen Int zugeordnet ist, folgt der Compiler einem Algorithmus und gibt eine Zahl innerhalb des Bereichs des kurzen Int zurück. Wenn der Programmierer Glück hat, warnt der Compiler vor Ärger bei der Verwendung unangemessener Konvertierung. Die gleiche Erklärung gilt für Conversions anderer Int -Typen.
Der Benutzer sollte die Dokumentation des Compilers konsultieren, um die Grenzwerte für jeden Entitätstyp zu bestimmen.
Wenn eine negativ signierte kurze Int -Zahl in eine nicht signierte kurze Int -Zahl umgewandelt werden soll, folgt der Compiler einem Algorithmus und gibt eine positive Zahl innerhalb des Bereichs des nicht signierten Short Int zurück. Diese Art von Umwandlung sollte vermieden werden. Die gleiche Erklärung gilt für Conversions anderer Int -Typen.
Jede Ganzzahlnummer, mit Ausnahme von 0, kann in boolean true konvertiert werden. 0 wird in boolean false umgewandelt. Der folgende Code zeigt dies:
int a = -27647;1 bedeutet wahr und 0 bedeutet falsch in der Ausgabe
Schwimmpunktkonvertierungen
Schwimmpunkttypen umfassen "Float", "Double" und "Long Double".„Gleitkomma-Typen werden nicht in signiert und nicht signiert, wie Ganzzahlen. Jeder Typ kann eine signierte oder nicht signierte Nummer haben. Ein Gleitkomma-Typ sollte mindestens die gleiche Präzision wie sein Vorgänger haben. Das heißt, "langes Doppel" sollte gleich oder mehr Präzision wie "doppelt" haben, und "Doppel" sollte gleich oder mehr Präzision haben wie "Schweben.”
Denken Sie daran, dass der Bereich eines Gleitpunkts nicht kontinuierlich ist. Vielmehr ist es in kleinen Schritten. Je größer die Genauigkeit des Typs ist, desto kleiner die Schritte und desto größer die Anzahl der Bytes, um die Anzahl zu speichern. Wenn also eine Schwimmpunktzahl von einem niedrigeren Präzisionstyp zu einem höheren Genauigkeitstyp umgewandelt wird, muss der Programmierer eine falsche Zunahme der Präzision und eine mögliche Erhöhung der Anzahl der Bytes für die Zahl-Storage akzeptieren. Wenn eine Schwimmpunktzahl von einem höheren Präzisionstyp zu einem niedrigeren Genauigkeitstyp umgewandelt wird, muss der Programmierer einen Präzisionsverlust akzeptieren. Wenn die Anzahl der Bytes für die Zahlen-Storage reduziert werden muss, folgt der Compiler einem Algorithmus und gibt eine Zahl als Ersatz zurück (was wahrscheinlich nicht das ist, was der Programmierer will). Beachten Sie auch Probleme außerhalb des Bereichs.
Schwimmende Integralkonvertierungen
Eine schwimmende Punktzahl wird in eine Ganzzahl umgewandelt, indem der Bruchteil abgeschnitten wird. Der folgende Code zeigt dies:
float f = 56.953;Wenn eine Ganzzahl in einen Schwimmer konvertiert wird, ist der als Float angezeigte Wert der gleiche wie ein Tipp als Ganzzahl. Das Float -Äquivalent kann jedoch den genauen Wert sein oder einen leichten Bruchunterschied aufweisen, der nicht angezeigt wird. Der Grund für den fraktionalen Unterschied ist, dass im Computer schwimmende Punktzahlen in kleinen Bruchschritten dargestellt werden, und so wäre es ein Zufall, die Ganzzahl genau darzustellen. Obwohl die als Float angezeigte Ganzzahl dieselbe ist wie bei der Eingabe, kann die Anzeige eine Annäherung an das sein, was gespeichert wird.
Ganzzahl -Konvertierungsranking
Jeder ganzzahlige Typ hat einen Rang, der ihm gegeben wurde. Diese Rangliste hilft bei der Konvertierung. Das Ranking ist relativ; Die Ränge befinden sich nicht auf festen Ebenen. Mit Ausnahme von Char und Signed Char haben keine zwei unterzeichneten Ganzzahlen den gleichen Rang (vorausgesetzt, CHAR ist unterschrieben). Unsignierte Ganzzahltypen haben das gleiche Ranking wie die entsprechenden signierten Ganzzahltypen. Das Ranking lautet wie folgt:
Integrale Werbeaktionen
Integrale Promotionen sind ganzzahlige Werbeaktionen. Es gibt keinen Grund, warum eine ganze Zahl von weniger Bytes nicht durch eine ganze Zahl größerer Bytes dargestellt werden kann. Integer Promotions befasst sich mit allem, was folgt:
Übliche arithmetische Konvertierungen
Betrachten Sie den folgenden Code:
float f = 2.5;C ++ hat übliche arithmetische Konvertierungen, die der Programmierer wissen muss, um Fehler bei der Codierung zu vermeiden. Die üblichen arithmetischen Konvertierungen von Binäroperatoren sind wie folgt:
Andernfalls würde die Ganzzahl -Promotion wie folgt stattfinden:
Schwimmende Punktförderung
Schwimmpunkttypen umfassen "Float", "Double" und "Long Double".”Ein Floating-Punkt-Typ sollte mindestens die gleiche Präzision wie sein Vorgänger haben. Die Gleitkomma-Promotion ermöglicht die Konvertierung von Float zu doppelt oder von doppelt zum langen Doppel.
Zeigerkonvertierungen
Ein Zeiger eines Objekttyps kann einem Zeiger eines anderen Objekttyps nicht zugewiesen werden. Der folgende Code wird nicht kompilieren:
int id = 6;Ein Nullzeiger ist ein Zeiger, dessen Adresswert Null ist. Ein Nullzeiger eines Objekttyps kann einem Nullzeiger eines anderen Objekttyps nicht zugewiesen werden. Der folgende Code wird nicht kompilieren:
int id = 6;Ein Nullzeigerkonst von einem Objekttyp kann nicht einem Nullzeiger -Konst von einem anderen Objekttyp zugeordnet werden. Der folgende Code wird nicht kompilieren:
int id = 6;Ein Nullzeiger kann einen anderen Adresswert für seinen Typ erhalten. Der folgende Code zeigt dies:
float idf = 2.5;Die Ausgabe ist 2.5.
Wie erwartet kann einer Nullzeigerkonstante keinen Adresswert seines Typs zugewiesen werden. Der folgende Code wird nicht kompilieren:
float idf = 2.5;Eine Nullzeigerkonstante kann jedoch einem gewöhnlichen Zeiger zugeordnet werden, aber vom gleichen Typ (dies ist zu erwarten). Der folgende Code zeigt dies:
float idf = 2.5;Die Ausgabe ist 0.
Zwei Nullzeigerwerte desselben Typs vergleiche (==) gleich.
Ein Zeiger auf einen Objekttyp kann einem Zeiger auf void zugeordnet werden. Der folgende Code zeigt dies:
float idf = 2.5;Der Code erstellt ohne Warnung oder Fehlermeldung.
Funktion zu Zeigerkonvertierungen
Ein Zeiger auf eine Funktion, die keine Ausnahme auswirft, kann einem Zeiger zugewiesen werden, um zu funktionieren. Der folgende Code zeigt dies:
#enthaltenDie Ausgabe ist ohne Ausnahme.
Boolesche Konvertierungen
In C ++ umfassen Entitäten, die zu False führen können.„Alle anderen Unternehmen führen zu wahr. Der folgende Code zeigt dies:
bool a = 0.0; Cout << a <<'\n';Die Ausgabe ist:
0 // für falseLvalue, Prvalue und XValue
Betrachten Sie den folgenden Code:
int id = 35;Die Ausgabe ist 35. Im Code sind ID und ID1 LVALUES, da sie einen Ort (Objekt) im Speicher identifizieren. Der Ausgang 35 ist ein PrValue. Jeder buchstäbliche, außer einer Streicherliteral, ist ein Prvalue. Andere Prvalues sind nicht so offensichtlich, wie in den folgenden Beispielen. Betrachten Sie den folgenden Code:
int id = 62;PTR ist ein LVALUE, da es einen Ort (Objekt) im Speicher identifiziert. Andererseits ist Pter kein Lvalue. Pter ist ein Zeiger, identifiziert jedoch keinen Speicherort im Speicher (es zeigt nicht auf ein Objekt). Pter ist also ein Prvalue.
Betrachten Sie den folgenden Code:
void fn ()FN () und (*func) () sind lvalue -Ausdrücke, weil sie eine Entität (Funktion) im Speicher identifizieren. Andererseits ist (*functn) () kein LVALUE -Ausdruck. (*functn) () ist ein Zeiger auf eine Funktion, identifiziert jedoch keine Entität im Speicher (es zeigt nicht auf eine Funktion im Speicher). Also ist (*functn) () ein prvaler Ausdruck.
Betrachten Sie nun den folgenden Code:
Struktur sS ist eine Klasse und OBJ ist ein Objekt, das aus der Klasse instanziiert ist. OBJ identifiziert ein Objekt im Speicher. Eine Klasse ist eine verallgemeinerte Einheit. S identifiziert also kein Objekt im Speicher wirklich. S soll ein unbenanntes Objekt sein. S ist auch ein prorue -Ausdruck.
Der Schwerpunkt dieses Artikels liegt auf Prvalues. Prvalue bedeutet reines Rvalue.
XVALUE
XValue steht für den Ablaufwert. Temporäre Werte sind ablaufende Werte. Ein Lvalue kann ein XValue werden. Ein Prvalue kann auch ein XValue werden. Der Schwerpunkt dieses Artikels liegt auf Prvalues. Ein XValue ist ein LVALUE oder ein unbenannter RValue -Referenz, dessen Speicher wiederverwendet werden kann (normalerweise, weil er am Ende seiner Lebensdauer ist). Betrachten Sie den folgenden Code, der funktioniert:
Struktur sDer Ausdruck “int q = s ().N;" Kopiert den Wert n an q. S () ist nur ein Mittel; Es ist kein regelmäßig verwendeter Ausdruck. S () ist ein PrValue, dessen Verwendung es in einen XValue umgewandelt hat.
Lvalue-to-Relevalue-Konvertierungen
Betrachten Sie die folgende Erklärung:
int ii = 70;70 ist ein PrValue (rvalue) und II ist ein Lvalue. Betrachten Sie nun den folgenden Code:
int ii = 70;In der zweiten Aussage befindet sich II in der Situation eines Prvalue, so dass II dort zu einem Prvalue wird. Mit anderen Worten, der Compiler wandelt II in ein Prvalue implizit um. Das heißt, wenn ein Lvalue in einer Situation verwendet wird, in der die Implementierung von einem PrValue erwartet.
Array-to-Pointer-Konvertierungen
Betrachten Sie den folgenden Code, der funktioniert:
char* p;Die Ausgabe ist B. Die erste Aussage ist Ausdruck und ein Zeiger auf einen Charakter. Aber auf welchen Charakter ist die Aussage zum Zeigen? - Kein Charakter. Es ist also ein Prvalue und kein Lvalue. Die zweite Aussage ist ein Array, in dem q [] ein LVALUE -Ausdruck ist. Die dritte Aussage verwandelt das Prvalue P in einen LVALUE -Ausdruck, der auf das erste Element des Arrays hinweist.
Funktionen zu Zeigerkonvertierungen
Betrachten Sie das folgende Programm:
#enthaltenDer Ausdruck "void (*func) ();" ist ein Zeiger auf eine Funktion. Aber auf welche Funktion ist der Ausdruck, der zeigt? - Keine Funktion. Es ist also ein Prvalue und kein Lvalue. FN () ist eine Funktionsdefinition, wobei FN ein LVALUE -Ausdruck ist. In main (), „func = &fn;Verwandelt das PrValue, den Func, in einen LVALUE -Ausdruck, der auf die Funktion fn () hinweist.
Temporäre Materialisierungsumwandlungen
In C ++ kann ein PrValue in einen XValue desselben Typs umgewandelt werden. Der folgende Code zeigt dies:
Struktur sHier wurde der PrValue () in einen XValue umgewandelt. Als XValue würde es nicht lange dauern - siehe mehr Erklärung oben.
Qualifikationsumwandlungen
Ein CV-qualifizierter Typ ist ein Typ, der durch das reservierte Wort „const“ und/oder das reservierte Wort „volatil“ qualifiziert ist.”
CV-Qualifikation ist ebenfalls eingestuft. Keine CV-Qualifikation ist weniger als die Qualifikation „Const“, was weniger als „const volatile“ Qualifikation ist. Keine CV-Qualifikation ist weniger als „flüchtig“ Qualifikation, was weniger als „const volatile“ Qualifikation ist. Es gibt also zwei Ströme von Qualifikationsranking. Ein Typ kann mehr CV-qualifiziert sein als ein anderer.
Ein niedrigerer prValue-CV-qualifizierter Typ kann in einen CV-qualifizierten Prvalue-Typ umgewandelt werden. Beide Typen sollten Zeiger auf CV sein.
Abschluss
C ++ - Entitäten können von einem Typ in einen verwandten Typ implizit oder explizit konvertiert werden. Der Programmierer muss jedoch verstehen, was konvertiert werden kann und was nicht, in welcher Form umgewandelt werden kann. Die Konvertierung kann in den folgenden Domänen stattfinden: Integrale Konvertierungen, Schwimmpunktkonvertierungen, schwebende Integralkonvertierungen, übliche arithmetische Konvertierungen, Zeigerkonvertierungen, Funktionen auf Zeigerkonvertierungen, booleale Konvertierungen, Konvertierungen von Lvalue-to-Relevern, Array-to-Pointer-Konvertierungen , Funktionen zu Zeigerumwandlungen, Konvertierungen der temporären Materialisierung und Qualifikationsumwandlungen.