C++

C++-Standardkonvertierungen

C++-Standardkonvertierungen
In C++ gibt es zwei Entitätstypen, die grundlegenden Typen und die zusammengesetzten Typen. Die grundlegenden Typen sind die Skalartypen. Die zusammengesetzten Typen sind die restlichen Entitätstypen. Die Konvertierung kann von einem Entitätstyp in einen anderen geeigneten Typ erfolgen. Betrachten Sie das folgende Programm:

#einschließen
#einschließen
Verwenden von Namespace-Std;
int main()

int rt1 = sqrt(5);
int rt2 = sqrt(8);
cout<0 zurückgeben;

Die Ausgabe ist 2, 2, Das bedeutet, dass das Programm die Quadratwurzel von 5 als 2 und die Quadratwurzel von 8 ebenfalls als 2 . zurückgegeben hat. Also, die ersten beiden Aussagen in der Main() Funktion haben die Antworten der Quadratwurzel von 5 und der Quadratwurzel von 8. Dieser Artikel behandelt nicht den Boden oder die Decke in C++. Dieser Artikel beschreibt vielmehr die Konvertierung eines C++-Typs in einen anderen geeigneten C++-Typ; Angabe einer Wertannäherung, eines Genauigkeitsverlusts oder hinzugefügter oder entfernter Beschränkungen. Grundkenntnisse in C++ sind Voraussetzung, um diesen Artikel zu verstehen.

Artikelinhalt

  • Integrale Konvertierungen
  • Gleitkomma-Konvertierungen
  • Floating-Integral-Umrechnungen
  • Integer-Conversion-Ranking
  • Integrale Werbeaktionen
  • Übliche arithmetische Umrechnungen
  • Gleitkomma-Werbung
  • Zeigerumwandlungen
  • Konvertierungen von Funktionen in Zeiger
  • Boolesche Konvertierungen
  • Lvalue, prvalue und xvalue
  • X-Wert
  • L-Wert-zu-R-Wert-Konvertierungen
  • Array-to-Pointer-Konvertierungen
  • Funktion-zu-Zeiger-Konvertierungen
  • Temporäre Materialisations-Konvertierungen
  • Qualifikationsumwandlungen
  • Fazit

Integrale Konvertierungen

Integrale Umrechnungen sind ganzzahlige Umrechnungen. Ganzzahlen ohne Vorzeichen umfassen „unsigned char“, „unsigned short int“, „unsigned int“, „unsigned long int“ und „unsigned long long int“.” Zu den entsprechenden vorzeichenbehafteten Ganzzahlen gehören „signed char“, „short int“, „int“, „long int“ und „long long int“.”Jeder int-Typ sollte in so vielen Bytes enthalten sein wie sein Vorgänger. Bei den meisten Systemen kann ein Entitätstyp problemlos in einen entsprechenden Typ konvertiert werden. Das Problem tritt beim Konvertieren von einem größeren Bereichstyp in einen kleineren Bereichstyp oder beim Konvertieren einer vorzeichenbehafteten Zahl in eine entsprechende vorzeichenlose Zahl auf.

Jeder Compiler hat einen maximalen Wert, den er für das kurze int . annehmen kann. Wenn dem kurzen int eine Zahl zugewiesen wird, die höher als dieses Maximum ist und für ein int bestimmt 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 Problemen mit unangemessener Konvertierung. Die gleiche Erklärung gilt für Konvertierungen anderer int-Typen.

Der Benutzer sollte die Dokumentation des Compilers konsultieren, um die Grenzwerte für jeden Entitätstyp zu bestimmen.

Wenn eine negative Short Int-Zahl mit Vorzeichen in eine Short-Int-Zahl ohne Vorzeichen umgewandelt werden soll, folgt der Compiler einem Algorithmus und gibt eine positive Zahl im Bereich der Short-Int-Zahl ohne Vorzeichen zurück. Diese Art der Konvertierung sollte vermieden werden. Die gleiche Erklärung gilt für Konvertierungen anderer int-Typen.

Jede ganze Zahl außer 0 kann in Boolean true umgewandelt werden. 0 wird in Boolean false umgewandelt. Der folgende Code veranschaulicht dies:

int a = -27647;
Schwimmer b = 2.5;
intc = 0;
bool a1 = a;
bool b1 = b;
bool c1 = c;
cout<cout<cout<Die Ausgabe ist:

1 für wahr
1 für wahr
0 für falsch

Gleitkomma-Konvertierungen

Gleitkommatypen umfassen "float", "double" und "long double".” Gleitkommatypen werden nicht in vorzeichenbehaftete und vorzeichenlose gruppiert, wie Integer. Jeder Typ kann eine vorzeichenbehaftete oder vorzeichenlose Nummer haben. Ein Gleitkommatyp sollte mindestens die gleiche Genauigkeit wie sein Vorgänger haben. Das heißt, „long double“ sollte die gleiche oder größere Genauigkeit wie „double“ haben und „double“ sollte die gleiche oder größere Genauigkeit wie „float“ haben.”

Denken Sie daran, dass der Bereich eines Gleitkommatyps nicht kontinuierlich ist; eher in kleinen Schritten. Je größer die Genauigkeit des Typs, desto kleiner die Schritte und desto mehr Bytes zum Speichern der Zahl store. Wenn also eine Gleitkommazahl von einem Typ mit niedrigerer Genauigkeit in einen Typ mit höherer Genauigkeit umgewandelt wird, muss der Programmierer eine falsche Erhöhung der Genauigkeit und eine mögliche Erhöhung der Anzahl von Bytes für die Zahlenspeicherung akzeptieren. Wenn eine Gleitkommazahl von einem Typ mit höherer Genauigkeit in einen Typ mit niedrigerer Genauigkeit umgewandelt wird, muss der Programmierer einen Genauigkeitsverlust in Kauf nehmen. Wenn die Anzahl der Bytes für die Zahlenspeicherung 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). Denken Sie auch an Probleme außerhalb der Reichweite.

Floating-Integral-Umrechnungen

Eine Gleitkommazahl wird in eine ganze Zahl umgewandelt, indem der Nachkommateil abgeschnitten wird. Der folgende Code veranschaulicht dies:

Schwimmer f = 56.953;
int i = f;
cout<Die Ausgabe ist 56. Die Bereiche für Float und Integer müssen kompatibel sein.

Wenn eine Ganzzahl in eine Gleitkommazahl umgewandelt wird, ist der als Gleitkomma angezeigte Wert derselbe, der als Ganzzahl eingegeben wurde. Das Float-Äquivalent kann jedoch der genaue Wert sein oder eine geringfügige Differenz aufweisen, die nicht angezeigt wird. Der Grund für die gebrochene Differenz ist, dass Gleitkommazahlen im Computer in kleinen Bruchschritten dargestellt werden und daher die exakte Darstellung der ganzen Zahl ein Zufall wäre. Obwohl die als Gleitkommazahl angezeigte Ganzzahl dieselbe ist, wie sie eingegeben wurde, kann die Anzeige eine Annäherung an das sein, was gespeichert ist.

Integer-Conversion-Ranking

Jeder Integer-Typ hat einen Rang, der ihm zugewiesen wurde. Dieses Ranking hilft bei der Konvertierung. Die Rangfolge ist relativ; die Ränge sind nicht auf festen Ebenen. Mit Ausnahme von char und signed char haben keine zwei vorzeichenbehafteten Ganzzahlen den gleichen Rang (vorausgesetzt, char ist vorzeichenbehaftet). Ganzzahltypen ohne Vorzeichen haben die gleiche Rangfolge wie ihre entsprechenden Ganzzahltypen mit Vorzeichen. Die Rangfolge lautet wie folgt:

  • Angenommen, char ist signiert, dann haben char und signiert char den gleichen Rang.
  • Der Rang eines Integer-Typs mit Vorzeichen ist höher als der Rang eines Integer-Typs mit Vorzeichen einer kleineren Anzahl von Speicherbytes. Der Rang von signed long long int ist also höher als der Rang von signed long int, der größer ist als der Rang von signed int, der größer ist als der Rang von signed short int, der größer ist als der Rang von vorzeichenbehaftetem char.
  • Der Rang jedes vorzeichenlosen Integer-Typs entspricht dem Rang des entsprechenden vorzeichenbehafteten Integer-Typs.
  • Der Rang von unsigned char entspricht dem Rang von signed char.
  • bool hat den niedrigsten Rang; sein Rang ist niedriger als der von signierten char.
  • char16_t hat den gleichen Rang wie das kurze int. char32_t hat den gleichen Rang wie int. Für den g++-Compiler hat wchar_t den gleichen Rang wie der int.

Integrale Werbeaktionen

Integrale Werbeaktionen sind ganzzahlige Werbeaktionen. Es gibt keinen Grund, warum eine ganze Zahl mit weniger Bytes nicht durch eine ganze Zahl mit größeren Bytes dargestellt werden kann. Integer Promotions befasst sich mit allem, was folgt:

  • Ein vorzeichenbehaftetes kurzes Int (zwei Bytes) kann in ein vorzeichenbehaftetes Int (vier Bytes) umgewandelt werden. Ein unsigned short int (zwei Bytes) kann in ein unsigned int (vier Bytes) umgewandelt werden. Hinweis: Das Konvertieren von short int in long int oder long long int führt zu einer Verschwendung von Speicherbytes (Objektstandort) und zu einer Verschwendung von Arbeitsspeicher. Bool, char16_t, char32_t und wchar_t sind von dieser Promotion ausgenommen (mit dem g++-Compiler haben char32_t und wchar_t die gleiche Anzahl von Bytes).
  • Mit dem g++-Compiler kann ein char16_t-Typ in einen vorzeichenbehafteten int-Typ oder einen unsignierten int-Typ umgewandelt werden; ein char32_t-Typ kann in einen vorzeichenbehafteten int-Typ oder einen unsignierten int-Typ umgewandelt werden; und ein wchar_t-Typ kann in einen vorzeichenbehafteten oder unsignierten int-Typ umgewandelt werden.
  • Ein bool-Typ kann in einen int-Typ umgewandelt werden. In diesem Fall wird true zu 1 (vier Bytes) und false zu 0 (vier Bytes). Int kann signiert oder signiert sein.
  • Integer-Hochstufung existiert auch für Aufzählungstypen ohne Bereich - siehe später.

Übliche arithmetische Umrechnungen

Betrachten Sie den folgenden Code:

Schwimmer f = 2.5;
int i = f;
cout<Der Code wird kompiliert, ohne eine Warnung oder einen Fehler anzuzeigen, und gibt die Ausgabe von 2, was wohl nicht erwartet wurde. = ist ein binärer Operator, weil er einen linken und einen rechten Operanden braucht. Betrachten Sie den folgenden Code:

int i1 = 7;
int i2 = 2;
Schwimmer flt = i1 / i2;
cout<Die Ausgabe ist 3, aber das ist falsch; es sollte sein 3.5. Der Divisionsoperator / ist ebenfalls ein binärer Operator.

C++ hat übliche arithmetische Konvertierungen, die der Programmierer kennen muss, um Fehler beim Codieren zu vermeiden. Die üblichen arithmetischen Konvertierungen für binäre Operatoren sind wie folgt:

  • Wenn einer der Operanden vom Typ „Long Double“ ist, wird der andere in Long Double umgewandelt.
  • Andernfalls, wenn einer der Operanden double ist, wird der andere in double umgewandelt.
  • Andernfalls, wenn einer der Operanden float ist, wird der andere in float umgewandelt. Im obigen Code ist das Ergebnis von i1/i2 offiziell 2; deshalb ist flt 2. Das Ergebnis des binären, /, wird als rechter Operand auf den binären Operator angewendet, =. Der Endwert von 2 ist also ein Float (kein Int).

SONST WÜRDE DIE INTEGER-FÖRDERUNG WIE FOLGT ERFOLGEN:

  • Sind beide Operanden vom gleichen Typ, erfolgt keine weitere Konvertierung.
  • Andernfalls, wenn beide Operanden Integer-Typen mit Vorzeichen oder beide Integer-Typen ohne Vorzeichen sind, wird der Operand des Typs mit dem niedrigeren Integer-Rang in den Typ des Operanden mit dem höheren Rang konvertiert.
  • Andernfalls, wenn ein Operand mit Vorzeichen und der andere ohne Vorzeichen ist und wenn der vorzeichenlose Operandentyp größer oder gleich dem Rang des vorzeichenbehafteten Operandentyps ist und wenn der Wert des vorzeichenbehafteten Operanden größer oder gleich Null ist, dann der vorzeichenbehaftete Operand wird in den vorzeichenlosen Operandentyp umgewandelt (mit Berücksichtigung des Bereichs). Wenn der Operand mit Vorzeichen negativ ist, folgt der Compiler einem Algorithmus und gibt eine Zahl zurück, die für den Programmierer möglicherweise nicht akzeptabel ist.
  • Andernfalls, wenn ein Operand ein Integer-Typ mit Vorzeichen und der andere ein Integer-Typ ohne Vorzeichen ist und wenn alle möglichen Werte des Typs des Operanden mit dem Integer-Typ ohne Vorzeichen durch den Integer-Typ mit Vorzeichen dargestellt werden können, wird der Integer-Typ ohne Vorzeichen in den Typ des Operanden des vorzeichenbehafteten Integer-Typs umgewandelt werden.
  • Andernfalls würden die beiden Operanden (z. B. ein char und ein bool) in den vorzeichenlosen Integer-Typ umgewandelt.

Gleitkomma-Werbeaktion

Gleitkommatypen umfassen "float", "double" und "long double".” Ein Gleitkommatyp sollte mindestens die gleiche Genauigkeit wie sein Vorgänger haben. Gleitkomma-Promotion ermöglicht die Umwandlung von Float in Double oder von Double in Long Double.

Zeigerumwandlungen

Ein Zeiger eines Objekttyps kann keinem Zeiger eines anderen Objekttyps zugewiesen werden assigned. Der folgende Code wird nicht kompiliert:

int-ID = 6;
int* intPtr = &id;
Schwimmer-IDf = 2.5;
float* floatPtr = &idf;
intPtr = floatPtr; // Fehler hier

Ein Nullzeiger ist ein Zeiger, dessen Adresswert null ist. Ein Nullzeiger eines Objekttyps kann keinem Nullzeiger eines anderen Objekttyps zugewiesen werden. Der folgende Code wird nicht kompiliert:

int-ID = 6;
int* intPtr = &id;
intPtr = 0;
Schwimmer-IDf = 2.5;
float* floatPtr = &idf;
floatPtr = 0;
intPtr = floatPtr; // Fehler hier

Ein Nullzeiger const eines Objekttyps kann keinem Nullzeiger const eines anderen Objekttyps zugewiesen werden. Der folgende Code wird nicht kompiliert:

int-ID = 6;
int* intPtr = &id;
int* const intPC = 0;
Schwimmer-IDf = 2.5;
float* floatPtr = &idf;
float* const floatPC = 0;
intPC = floatPC; // Fehler hier

Einem Nullzeiger kann ein anderer Adresswert für seinen Typ zugewiesen werden. Der folgende Code veranschaulicht dies:

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

Die Ausgabe ist 2.5.

Einer Null-Zeiger-Konstante kann erwartungsgemäß kein Adresswert ihres Typs zugewiesen werden. Der folgende Code wird nicht kompiliert:

Schwimmer-IDf = 2.5;
float* const floatPC = 0;
floatPC = &idf; //Fehler hier

Eine Null-Zeiger-Konstante kann jedoch einem gewöhnlichen Zeiger zugewiesen werden, jedoch vom gleichen Typ (dies ist zu erwarten). Der folgende Code veranschaulicht dies:

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

Die Ausgabe ist 0.

Zwei Nullzeigerwerte des gleichen Typs vergleichen (==) gleich.

Ein Zeiger auf einen Objekttyp kann einem Zeiger auf void zugewiesen werden. Der folgende Code veranschaulicht dies:

Schwimmer-IDf = 2.5;
float* floatPtr = &idf;
nichtig* vd;
vd = floatPtr;

Der Code wird ohne Warnung oder Fehlermeldung kompiliert.

Konvertierungen von Funktionen in Zeiger

Ein Zeiger auf eine Funktion, die keine Ausnahme auslösen würde, kann einem Zeiger auf eine Funktion zugewiesen werden. Der folgende Code veranschaulicht dies:

#einschließen
Verwenden von Namespace-Std;
void fn1() keine Ausnahme

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

Leere fn2()

//Aussagen

void (*func1)() noaußer;
void (*func2)();
int main()

funk1 = &fn1;
fun2 = &fn2;
fun2 = &fn1;
func2();
0 zurückgeben;

Die Ausgabe ist ohne Ausnahme.

Boolesche Konvertierungen

In C++ sind Entitäten, die zu false führen können, „Null“, „Null-Zeiger“ und „Null-Member-Zeiger“.” Alle anderen Entitäten ergeben wahr. Der folgende Code veranschaulicht dies:

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';

Die Ausgabe ist:

0 //für falsch
0 //für falsch
1 //für wahr
1 //für wahr

Lvalue, prvalue und xvalue

Betrachten Sie den folgenden Code:

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

Die Ausgabe ist 35. Im Code sind id und id1 lWerte, weil sie einen Ort (Objekt) im Speicher identifizieren. Die Ausgabe 35 ist ein pr-Wert. Jedes Literal, außer einem String-Literal, ist ein Prvalue. Andere prvalues ​​sind nicht so offensichtlich, wie in den folgenden Beispielen. Betrachten Sie den folgenden Code:

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

Ptr ist ein lvalue, weil er einen Ort (Objekt) im Speicher identifiziert. Auf der anderen Seite ist pter kein lvalue. Pter ist ein Zeiger, aber er identifiziert keinen Speicherort (er zeigt nicht auf ein Objekt). pter ist also ein prvalue.

Betrachten Sie den folgenden Code:

Leere fn()

//Aussagen

void (*funktion)() = &fn;
float (*functn)();

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 aber keine Entität im Speicher (zeigt auf keine Funktion im Speicher). (*functn)() ist also ein Prvalue-Ausdruck.

Betrachten Sie nun den folgenden Code:

strukt S

int n;
;
S obj;

S ist eine Klasse und obj ist ein aus der Klasse instanziiertes Objekt. Obj identifiziert ein Objekt im Speicher. Eine Klasse ist eine verallgemeinerte Einheit. Also identifiziert S nicht wirklich irgendein Objekt im Speicher. S heißt ein unbenanntes Objekt. S ist auch ein Prvalue-Ausdruck.

Der Fokus dieses Artikels liegt auf Prvalues. Prvalue bedeutet reiner rvalue.

X-Wert

Xvalue steht für Expiring Value. Temporäre Werte sind auslaufende Werte. Ein L-Wert kann ein x-Wert werden. Ein pr-Wert kann auch ein x-Wert werden. Der Fokus dieses Artikels liegt auf Prvalues. Ein xvalue ist ein lvalue oder eine unbenannte rvalue-Referenz, deren Speicher wiederverwendet werden kann (normalerweise weil er sich dem Ende seiner Lebensdauer nähert). Betrachten Sie den folgenden Code, der funktioniert:

strukt S

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

Der Ausdruck „int q = S().n;“ kopiert jeden Wert n auf q. S() ist nur ein Mittel; es ist kein regelmäßig verwendeter Ausdruck. S() ist ein Pr-Wert, dessen Verwendung ihn in einen x-Wert umgewandelt hat.

L-Wert-zu-R-Wert-Konvertierungen

Betrachten Sie die folgende Aussage:

intii = 70;

70 ist ein prvalue (rvalue) und ii ist ein lvalue. Betrachten Sie nun den folgenden Code:

intii = 70;
int tt = ii;

In der zweiten Aussage befindet sich ii in der Situation eines prvalue, also wird ii dort zu einem prvalue. Mit anderen Worten, der Compiler wandelt ii implizit in einen prvalue um. Das heißt, wenn ein lvalue in einer Situation verwendet wird, in der die Implementierung einen prvalue erwartet, konvertiert die Implementierung den lvalue in einen prvalue.

Array-to-Pointer-Konvertierungen

Betrachten Sie den folgenden Code, der funktioniert:

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

Die Ausgabe ist b. Die erste Anweisung ist ein Ausdruck und ein Zeiger auf ein Zeichen. Aber auf welchen Charakter weist die Aussage hin? - Kein Charakter. Es ist also ein prvalue und kein lvalue. Die zweite Anweisung ist ein Array, in dem q[] ein lvalue-Ausdruck ist. Die dritte Anweisung verwandelt den prvalue, p, in einen lvalue-Ausdruck, der auf das erste Element des Arrays zeigt.

Funktion-zu-Zeiger-Konvertierungen

Betrachten Sie das folgende Programm:

#einschließen
Verwenden von Namespace-Std;
void (*funktion)();
Leere fn()

//Aussagen

int main()

Funktion = &fn;
0 zurückgeben;

Der Ausdruck „void (*func)();“ ist ein Zeiger auf eine Funktion. Aber auf welche Funktion zeigt der Ausdruck?? - Keine Funktion. Es ist also ein prvalue und kein lvalue. Fn() ist eine Funktionsdefinition, wobei fn ein lvalue-Ausdruck ist. In main() ist „func = &fn;” verwandelt den prvalue, func, in einen lvalue-Ausdruck, der auf die Funktion fn() zeigt.

Temporäre Materialisations-Konvertierungen

In C++ kann ein prvalue in einen xvalue des gleichen Typs umgewandelt werden. Der folgende Code veranschaulicht dies:

strukt S

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

Hier wurde der pr-Wert, S(), in einen x-Wert umgewandelt. Als x-Wert 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 „volatile“ qualifiziert ist.”

Lebenslauf-Qualifikation wird ebenfalls gerankt. Keine CV-Qualifikation ist geringer als die „const“-Qualifikation, die kleiner ist als die „const volatile“. Keine CV-Qualifikation ist geringer als die „volatile“ Qualifikation, die kleiner ist als die „const volatile“ Qualifikation. Es gibt also zwei Ströme des Qualifikationsrankings. Ein Typ kann mehr Lebenslauf-qualifiziert sein als ein anderer.

Ein CV-qualifizierter Typ mit einem niedrigeren prvalue kann in einen mehr CV-qualifizierten prvalue-Typ umgewandelt werden. Beide Typen sollten Pointer-to-cv . sein.

Fazit

C++-Entitäten können implizit oder explizit von einem Typ in einen verwandten Typ konvertiert werden. Der Programmierer muss jedoch verstehen, was konvertiert werden kann und was nicht und in welche Form. Die Konvertierung kann in den folgenden Domänen erfolgen: Integral-Konvertierungen, Gleitkomma-Konvertierungen, Gleitkomma-Konvertierungen, übliche arithmetische Konvertierungen, Zeiger-Konvertierungen, Funktion-zu-Zeiger-Konvertierungen, Boolesche Konvertierungen, L-Wert-zu-R-Wert-Konvertierungen, Array-zu-Zeiger-Konvertierungen , Funktion-zu-Zeiger-Konvertierungen, temporäre Materialisierungskonvertierungen und Qualifikationskonvertierungen.

So installieren Sie League of Legends auf Ubuntu 14.04
Wenn Sie ein Fan von League of Legends sind, dann ist dies eine Gelegenheit für Sie, League of Legends zu testen. Beachten Sie, dass LOL von PlayOnLin...
Installieren Sie das neueste OpenRA-Strategiespiel auf Ubuntu Linux
OpenRA ist eine Libre/Free Real Time Strategy Game Engine, die die frühen Westwood-Spiele wie den Klassiker Command & Conquer: Red Alert Red nachbilde...
Installieren Sie den neuesten Dolphin Emulator für Gamecube & Wii unter Linux
Mit dem Dolphin Emulator können Sie Ihre ausgewählten Gamecube- und Wii-Spiele auf Linux-Personalcomputern (PC) spielen. Als frei verfügbarer Open-So...