Zeiger < C/C++ < Programmiersprachen < Praxis < Informatik < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 10:20 Fr 27.06.2014 | Autor: | LPark |
Hallo, ich habe ein Verständnisproblem bei Zeigern.
Nehmen wir an, es sei:
int i, j = 25;
int *pi, *pj = &j;
...
*pj = j + 5;
i = *pj + 5;
pi = pj;
*pi = i + j;
Ich möchte den Wert von pi bzw pj wissen.
Und da haperts mit meiner Vorstellung von Zeigern.
Meines Wissens nach, steht *pi für die Adresse von i, d.h., wenn man *pi verändert, verändert sich auch i.
Und pi (ohne den * ), wäre eine normale Variable.
Was hat diese jetzt mit *pi, bzw i zu tun?
Danke im Voraus! =)
|
|
|
|
Hallo,
die Werte von pi und pj sind Speicheradressen, die Variablen *pi und *pj haben am Ende des Codes die Werte
*pi=60 bzw. *pj=30
> Meines Wissens nach, steht *pi für die Adresse von i,
> d.h., wenn man *pi verändert, verändert sich auch i.
Es ist anders herum. Bei der Deklaration int *a wird eine Variable a erzeugt, die auf eine Speicheradresse zeigt. Mit *a bekommt man den Wert, der an dieser Adresse gespeichert ist.
Hilft das weiter?
Gruß, Diophant
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 14:22 Fr 27.06.2014 | Autor: | LPark |
Hallo.
Ja, das hilft soweit weiter.
Allerdings weiß ich nicht, bzw. kann mir nicht denken, was für Werte pi und pj haben.
Die Zeiger haben, wie du schon sagtest, einfach zu ermittelnde Werte.
Wenn ich den Code in meinen Compiler eingebe, kommen für pj und pi utopische Werte raus, die keinen Sinn ergeben.
Es müssten doch "normale" Variablen sein, die in dem Code nicht näher deklariert wurden, oder?
|
|
|
|
|
Hallo,
> Hallo.
> Ja, das hilft soweit weiter.
> Allerdings weiß ich nicht, bzw. kann mir nicht denken,
> was für Werte pi und pj haben.
> Die Zeiger haben, wie du schon sagtest, einfach zu
> ermittelnde Werte.
> Wenn ich den Code in meinen Compiler eingebe, kommen für
> pj und pi utopische Werte raus, die keinen Sinn ergeben.
> Es müssten doch "normale" Variablen sein, die in dem Code
> nicht näher deklariert wurden, oder?
wie gesagt: Zeiger sind Speicher-Adressen. Das sind schon bei einem 16-bit-Compiler 'utopische Werte', wie du es nennst.
Gruß, Diophant
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 14:39 Fr 27.06.2014 | Autor: | LPark |
Das Zeiger auf Speicheradressen verweisen, weiß ich.
Nur verstehe ich den Zusammenhang von pj und *pj nicht.
*pj zeigt ja auf die Adresse von j. Aber was ist pj?
Ist das eine normale Variable?
|
|
|
|
|
Hallo!
Da gibt es etwas Verwirrung
Erstmal ist
int *pj;
das gleiche wie
int* pj;
wobei letzteres besser zu verstehen ist. Es deklariert eine Variable pj, und diese ist vom Typ int*, oder verständlicher vom Typ "Adresse eines INTs".
Nun ist pj eine Variable, deren Wert eine Speicheradresse ist. Und an dieser Speicheradresse soll ein INT-Wert liegen.
Möchtest du nun den Wert wissen, der an der Speicheradresse liegt, kannst du den mit *pj bekommen.
Noch was wichtiges: Wenn du eine Variable anlegst, wird erst dann, wenn du das Programm laufen lässt, auch Speicher im Computer dafür reserviert. Die Adresse des Speichers ist dabei mehr oder weniger zufällig, und du kannst da keinen festen Wert für angeben.
Beispiel: Ein simples Programm mit folgenden Zeilen:
int i=25;
int* pi;
pi=&i;
printf("Zeiger pi: [mm] %p\n", [/mm] pi);
printf("Wert i: [mm] %d\n", [/mm] i);
Wenn ich das drei mal hintereinander ausführe, bekomme ich das:
Zeiger pi: 0x7fff377fd2c4
Wert i: 25
Zeiger pi: 0x7fffb8cad2a4
Wert i: 25
Zeiger pi: 0x7fff6ee1f844
Wert i: 25
Der Integer-Wert i hat natürlich immer den Wert 25, aber seine Adresse ist jedesmal anders.
Noch eine Warnung: Für den Computer ist eines klar: An der Adresse, die in pi steht, stehen Bytes, welche er als INT interpretiert. Wenn du die Adresse nun nicht z.B. per &i ermittelst, sondern dir selber eine Adresse ausdenkst (alsp pi=1000; z.B.) kannst du möglicherweise *pi lesen, aber wenn du *pi=25 versuchst, also versuchst, einen Wert an die Adresse zu schreiben, wird das Programm vermutlich abstürzen. Du kannst ja nicht einfach in wildfremde Speicherbereiche schreiben!
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 20:24 Fr 27.06.2014 | Autor: | LPark |
Du sagtest ja, ich könnte pi (also die Adresse) selbst verändern.
Aber davon ist laut deinem Beispiel wohl abzuraten.
Also gibt pi (ohne *) lediglich die Speicheradresse aus und mit*pi greift man auf die Variable zu.
Du hast am Anfang geschrieben :
Int* pi;
pi = &i;
Müsste es nicht heißen *pi = &i ?
Un wenn nein, warum?
|
|
|
|
|
Hallo!
Wenn du
int i=25;
schreibst, wird z.B. an der Adresse 0x10000000 ein vier Byte langer Speicherbereich reserviert, und der Wert 25 hinein geschrieben. Mit i meinst du fortan immer denInhalt dieser vier Byte. Willst du die Adresse wissen, schreibst du &i.
Schreibst du nun
int* pi;
werden wieder vier Byte reserviert, sagen wir bei 0x20000000.
An dise Stelle kann man eine Adresse abspeichern, und zwar so:
pi=&i;
Jetzt liegt an der Adresse 0x20000000 der Wert 0x10000000. Oder anders: pi hat nun den Wert 0x20000000 0x10000000. (Das ist nun verrückt, daß man an irgendeiner Adresse im Speicher eine Speicheradresse ablegt...)
Jedenfalls, das ist so völlig OK. Du besorgst dir die Adresse von i, und steckst sie in den Zeiger. Du solltest NICHT schreiben
pi=0x30000000;
Das ist zwar erstal korrekt, aber wenn du anschließend irgendwas damit anstellst, kann dein Programm wie gesagt abstürzen.
Schreibst du jetzt
*pi
Meinst du damit:: Der Wert, (25) der im Speicher an der Adresse steht, welche in pi steht (0x10000000).
Das heißt, *pi ist gleichbedeutend mit i.
Ach ja, **pi ist wieder pi selbst.
Und um an die 0x20000000 zu kommen, schreibst du &pi.
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 13:37 Sa 28.06.2014 | Autor: | LPark |
Das ist alles furchtbar verwirrend, aber ich denke, nachdem ich mir deinen Text ein paar mal durchgelesen habe, verstehe ich das schon. :)
Danke für die Mühen!
Grüße,
LPark
|
|
|
|