Wie versteht man Zeigerarithmetik??
-
silent_max schrieb:
KasF schrieb:
Max, schaust du dir das mal bitte an:
http://www.c-plusplus.net/forum/p1330752#1330752Den Link kann ich nicht öffnen. Zumindest kommt die Meldung "Seiten-Ladenfehler".
Also bei mir geht er, sonst versuch mal den: http://www.c-plusplus.net/forum/187711
-
Ich glaube, dass ich noch mindestens zwei Denkfehler habe.
Folgendes Beispiel wollte ich in einem Code realisieren:
/* Speicher ( Adresse:Name:Wert) ------------------------ | 1000 | Zahl_1 | 05 | ------------------------ | 1004 | Zahl_2 | 05 | ------------------------ */Auf Basis diesen Beispiels habe ich folgenden Code geschrieben.
#include <iostream> using namespace std; int main() { int Zahl_1, Zahl_2, Zahl_3; int *pZahl_1 = &Zahl_1; int *pZahl_2 = &Zahl_2; int *pZahl_3 = &Zahl_3; cout << "Es werden zwei Zahlen miteinander addiert.\n"; cout << "Geben Sie dazu zwei Zahlen ein!\n"; cin >> Zahl_2 >> Zahl_3; cout << "\n"; Zahl_1 = Zahl_2 + Zahl_3; cout << Zahl_2 << " + " << Zahl_3 << " ergibt " << Zahl_1 <<"\n"; cout << "\n"; cout << "Adresse von " << Zahl_2 << ": " << &Zahl_2 << "\n"; cout << "Bytereservierung von " << Zahl_2 << ": " << sizeof(Zahl_2) << "\n"; cout << "Adresse von " << Zahl_3 << " " << &Zahl_3 << "\n"; cout << "Bytereservierung von " << Zahl_3 << ": " << sizeof(Zahl_3) << "\n"; cout << "Adresse von " << Zahl_1 << ": " << &Zahl_1 << "\n"; cout << "Bytereservierung von " << Zahl_1 << ": " << sizeof(Zahl_1) << "\n"; cout << "\n"; return 0; }Nun wird mir folgendes ausgegeben:
Es werden zwei Zahlen miteinander addiert! Geben Sie dazu zwei Zahlen ein: 5 5 5 + 5 ergibt 10 Adresse von 5: 026F8E0 Bytereservierung von 5: 4 Adresse von 5: 026F8D4 Bytereservierung von 5: 4 Adresse von 10: 026F8EC Bytereservierung von 10: 4Nun zu meinen Fragen.
1.) Ich dachte, wenn ich Zahl_1 und Zahl_2, beides 5, miteinander addiere, also 10, werden für die 10 insgesamt 8 Byte reserviert. Warum werden dann nur 4 Byte als Bytereservierung ausgegeben?
2.) Ich dachte, dass die Adressen von den beiden 5er jeweils um 4 und das Ergebnis um 8 hochzählt, also dass es im Endeffekt so aussieht:
Adresse von 5: 026F8E0 Adresse von 5: 026F8E4 Adresse von 10: 026F8ECWarum werden die Adressen willkürlich ausgewählt?
Im Debugger bekomme ich folgende Werte:
pZahl_1: 0x0019f928 pZahl_2: 0x0019f91c pZahl_3: 0x0019f910Kann man überhaupt die Adressen so sortiern, dass sie jeweils um 4 Byte hochzählen?? Falls ja wie??
Der Algorithmus
sort();sortiert ja nur zwischen den Iteratoren first und last und ist nur für Container mit Random-Acces-Iteratoren geeigntet...
-
siehe
http://de.wikipedia.org/wiki/Byte (kleinste addressierbare Speichereinheit, besteht unter C++ aus mindestens 8 Bits)
http://de.wikipedia.org/wiki/Dualsystemsilent_max schrieb:
1.) Ich dachte, wenn ich Zahl_1 und Zahl_2, beides 5, miteinander addiere, also 10, werden für die 10 insgesamt 8 Byte reserviert. Warum werden dann nur 4 Byte als Bytereservierung ausgegeben?
Zahl_1 ist auch nur eine int-Variable. Und int-Variablen sind immer gleich groß.
silent_max schrieb:
2.) Ich dachte, dass die Adressen von den beiden 5er jeweils um 4 und das Ergebnis um 8 hochzählt, also dass es im Endeffekt so aussieht:
Adresse von 5: 026F8E0 Adresse von 5: 026F8E4 Adresse von 10: 026F8ECWarum werden die Adressen willkürlich ausgewählt?
Warum nicht?
silent_max schrieb:
Kann man überhaupt die Adressen so sortiern, dass sie jeweils um 4 Byte hochzählen?? Falls ja wie??
Ja. Die Elemente eines std::vector<int> Objekts liegen z.B. alle schön hintereinander im Speicher.
-
krümelkacker schrieb:
silent_max schrieb:
Kann man überhaupt die Adressen so sortiern, dass sie jeweils um 4 Byte hochzählen?? Falls ja wie??
Ja. Die Elemente eines std::vector<int> Objekts liegen z.B. alle schön hintereinander im Speicher.
So wie ich Dich verstehe, kann aber man die Adressen von zwei unterschiedlichen Variablen, also nicht im Vektor, aber nicht so sortieren, dass sie hinteraneinder um 4 Byte hochzählen??
-
Du kannst Adressen nicht sortieren. Wozu sollte das auch gut sein?
-
Belli schrieb:
Du kannst Adressen nicht sortieren.
Ich dachte, man kann Adressen sortieren. Jetzt weiß ich, dass man es nicht kann.
Edit:
Ich habe jetzt auf die Schnelle folgenden Code programmiert:#include <iostream> using namespace std; int main() { cout << "\t 5 Adressen um jeweils 4 Byte hochzaehlen lassen.\n"; cout << "\n"; int Zahl[5]; int *pZahl= &Zahl[5]; int a; cout << "Geben Sie fuenf Zahlen ein.\n"; cin >> a; for(int i=0; i<5; i++) { cout << "Zahl[" << i << "]:"; cin >> i; } cout << "Die Adresse der jeweiligen Zahl lautet wie folgt:\n"; for(int i=0; i<5; i++) { cout << "Zahl[" << i << "]: " << &Zahl[i] << "\n"; } return 0; }Wenn ich aber die Zahlen einlesen will, dann wir
Zahl[1]übersprungen, also bekomme ich beim Einlesen der Zahlen folgendes raus:
Zahl[0]: Zahl[2]: Zahl[3]: Zahl[4]:Komischerweise bei der Ausgabe der Adressen wird jedes Element angezeigt.
Selbst im Debugger wird das Element Zahl[1] übersprungen.
Wo liegt mein Fehler??
-
Was soll das überhaupt bewirken?

-
Schau bitte meinen Edit an.
-
&Zahl[5] ist die Adresse des 6. Elements in Zahl. Leider hat Zahl kein 6. Element. Etwas in i einzulesen macht wohl wenig Sinn.
-
silent_max schrieb:
Ich habe jetzt auf die Schnelle folgenden Code programmiert:
blablabla... liest irgendwann den Laufindex von cin ein... blablabla...Evtl. solltest Du das mit dem "auf die Schnelle" lassen, bzw. jedenfalls niemanden damit behelligen, sondern erstmal im stillen Kämmerlein schauen, was Phase ist...
-
Der Denkfehler liegt ganz woanders.
Im Anhang der korrigiert Code.
@cooky451: Vergleiche mal beide Codes.
@FurbleWurble: Du bist mir zuvor gekommen mit Deinem Posting.
Edit: Jetzt müsste es aber laufen.
#include<iostream> using namespace std; int main() { cout << "\t 5 Adressen um jeweils 4 Byte hochzaehlen lassen."; cout << "\n"; int Zahl[5]; int *pZahl = Zahl[5]; int a; cout << "Geben Sie fuenf Zahlen ein.\n"; cin >> a; for (int i=0; i<5; i++) { cout << "Zahl[" << i << "]:"; cin >> a; } cout << "Die Adresse der jeweiligen Zahlen lautet wie folgt: \n"; for(int i=0; i<5; i++) { cout << "Zahl[" << i << "]:" << &Zahl[i] << "\n"; } return 0; }
-
Was soll man dazu sagen? Nichts davon macht auch nur im entferntesten Sinn, das kompiliert nicht mal.

-
cooky451 schrieb:
Was soll man dazu sagen? Nichts davon macht auch nur im entferntesten Sinn, das kompiliert nicht mal.

Weil ich in Zeile 6 ein ; vergessen habe.
Jetzt müsste es kompilieren.
-
silent_max schrieb:
Jetzt müsste es kompilieren.
Noe. Und Sinn ergibt es auch nicht.
-
Aber jetzt müsste es komplierbar sein.
Über den Sinn und Unsinn kann man streiten.
Ich wollte "nur" ein Programm schreiben, dass die Speicheradressen um 4 Byte hochzählt, nicht mehr und auch nicht weniger.
-
silent_max schrieb:
Aber jetzt müsste es komplierbar sein.
Noe.
silent_max schrieb:
Ich wollte "nur" ein Programm schreiben, dass die Speicheradressen um 4 Byte hochzählt, nicht mehr und auch nicht weniger.
In diesem Fall ergibt das Programm auch objektiv keinen Sinn

-
Dann wenden wir halt mal "copy and paste" an:
#include<iostream> using namespace std; int main() { cout << "\t 5 Adressen um jeweils 4 Byte hochzaehlen lassen.\n"; cout << "\n"; int Zahl[5]; int *pZahl = &Zahl[5]; int a; cout << "Geben Sie fuenf Zahlen ein.\n"; for(int i=0; i<5; i++) { cout << "Zahl[" << i <<"]: "; cin >> a; } cout << "Die Adresse der jeweiligen Zahl lautet wie folgt:\n"; for(int i=0; i<5; i++) { cout << "Zahl[" << i << "]: " << &Zahl[i] << "\n"; } return 0; }Müsste eigentlich jetzt laufen. Zumindest sind bei mir weder Warnings noch Errors.
@ noehoe: Warum ergibt das Programm für Dich objektiv keinen Sinn? Wenn Du einen besseren Vorschlag hast, wie man die Speicheradressen auslesen kann, dann gebe mir bitte einen konstruktiven Vorschalg. Ich bin für vieles offen.
-
Sag mal raffst du es nicht? Zahl[5] existiert nicht. Hab ich doch schon mal geschrieben.
Geh mal durch dein Programm und kommentiere jede Zeile mit dem was sie macht, und wozu sie im Programm steht. (Also jede Zeile in der sich Code befindet. Kein { oder }.)
-
Auch auf die Gefahr hin, Dir Dinge zu erzählen, die Dir glasklar sind:
Die Adresse, die Größe und noch die eine oder andere Eigenschaft von Datentypen ist unabhängig von deren Wert.
Einintist einintist einint!
D.h. um Dir anzusehen, wie einint[5]aussieht musst Du nur eins anlegen und anschauen:#include<iostream> int main(){ int arr[5]; for(const int* p=arr; p!=arr+5; ++p) // sogar mit Zeigerarithmetik... std::cout << "int@"<<p << '\n'; }
-
Naja ... aber die Adresse &Zahl[5] gibt es schon ... ich glaube, er hat es jetzt endlich verstanden ...