30.06.2013 Aufrufe

Softwareentwicklung in C++ - ASC

Softwareentwicklung in C++ - ASC

Softwareentwicklung in C++ - ASC

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

6.2 Po<strong>in</strong>ter 133<br />

Auf e<strong>in</strong>er Sun würde die Reihenfolge der Bytes genau umgekehrt se<strong>in</strong>. Dies<br />

hängt mit den <strong>in</strong>ternen Architekturen dieser Rechner zusammen, denn e<strong>in</strong>em<br />

Intel liegt e<strong>in</strong>e little Endian und e<strong>in</strong>er Sun e<strong>in</strong>e big Endian Byte Order<br />

zugrunde.<br />

Ich möchte mich hier nicht näher über little- und big Endian auslassen, wohl<br />

aber möchte ich erwähnen, dass dieses Wissen sehr wichtig se<strong>in</strong> kann! Leser,<br />

die mit diesen Begriffen nichts anfangen können, möchte ich auf Kapitel 13<br />

von <strong>Softwareentwicklung</strong> <strong>in</strong> C verweisen, wo e<strong>in</strong> sehr ähnliches Beispiel mit<br />

genauerer Erklärung gebracht wird.<br />

Nach diesem kle<strong>in</strong>en Exkurs <strong>in</strong> die Prozessorarchitekturen zurück zum eigentlichen<br />

Thema, nämlich dem Erzw<strong>in</strong>gen e<strong>in</strong>er anderen Interpretation e<strong>in</strong>es<br />

Datums als der, die der Typ eigentlich vorgeben würde. Wir haben bereits<br />

den re<strong>in</strong>terpret_cast kennen gelernt und dabei erfahren, dass durch diesen<br />

e<strong>in</strong>e Neu<strong>in</strong>terpretation “ohne Rücksicht auf Verluste” und ohne jeglichen<br />

Umwandlungsversuch von Seiten des Compilers stattf<strong>in</strong>det. Das machen wir<br />

uns <strong>in</strong> den Zeilen 13–14 zunutze, denn dort erzw<strong>in</strong>gen wir e<strong>in</strong>e Neu<strong>in</strong>terpretation<br />

e<strong>in</strong>es <strong>in</strong>t32* als u<strong>in</strong>t8*. Dies bedeutet <strong>in</strong>tern, dass die Adresse,<br />

die die Variable <strong>in</strong>t32_iterator hält auf num_for_extraction zeigt. Allerd<strong>in</strong>gs<br />

wird der Inhalt dieser Speicherstelle nicht als <strong>in</strong>t32 <strong>in</strong>terpretiert,<br />

sondern als u<strong>in</strong>t8. Das bedeutet, dass nur e<strong>in</strong> e<strong>in</strong>ziges Byte genommen und<br />

als u<strong>in</strong>t8 <strong>in</strong>terpretiert wird anstatt aller 4 Bytes, die geme<strong>in</strong>sam die Variable<br />

num_for_extraction ausmachen.<br />

Wenn man nun also <strong>in</strong> e<strong>in</strong>er Schleife, wie <strong>in</strong> den Zeilen 15–18 gezeigt, die<br />

4 Bytes des <strong>in</strong>t32 h<strong>in</strong>tere<strong>in</strong>ander ausliest, dann hat man genau das erreicht,<br />

was man wollte. Natürlich ist <strong>in</strong> Zeile 17 wieder e<strong>in</strong> static_cast des u<strong>in</strong>t8<br />

auf u<strong>in</strong>t32 notwendig, denn ansonsten würde ke<strong>in</strong>e Zahl, sondern irgende<strong>in</strong><br />

kryptischer Character am Bildschirm dargestellt werden.<br />

Es gibt genügend Fälle, bei denen zur Compiletime noch gar nicht bekannt<br />

ist, welcher Po<strong>in</strong>tertyp dann zur Laufzeit als Parameter an e<strong>in</strong>e Funktion<br />

übergeben wird. Im OO-Teil werden uns solche mehrfach begegnen.<br />

Jetzt wissen wir aber, dass der Compiler beim impliziten Umwandeln recht<br />

restriktiv ist und uns damit das Leben schwer machen kann, welchen Parametertyp<br />

wir denn jetzt eigentlich für unsere Funktion deklarieren. Dafür gibt<br />

es <strong>in</strong> C ++ e<strong>in</strong>en ganz besonderen untypisierten Po<strong>in</strong>ter, nämlich den void *.<br />

Dieser Po<strong>in</strong>tertyp ist so def<strong>in</strong>iert, dass jeder beliebige Po<strong>in</strong>ter vom Compiler<br />

ohne Fehlermeldung oder Warn<strong>in</strong>g implizit <strong>in</strong> ihn umgewandelt werden kann.<br />

In unserer Funktion können wir dann zur Laufzeit (sofern wir wissen, womit<br />

wir zu tun haben :-)) mittels e<strong>in</strong>es re<strong>in</strong>terpret_cast wieder die gewünschte<br />

Interpretation herstellen.<br />

Dass ohne expliziten Cast bei e<strong>in</strong>em void * ke<strong>in</strong>e Index-Operationen und<br />

auch ke<strong>in</strong>e Po<strong>in</strong>terarithmetik möglich s<strong>in</strong>d, versteht sich von selbst. Diese<br />

Operationen s<strong>in</strong>d ja so def<strong>in</strong>iert, dass sie immer auf Elementbasis und nicht<br />

auf Bytebasis rechnen. Wenn man aber nicht weiß, welches Element sich

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!