Da ich Zeiger immernoch nicht ganz verstehe möchte ich mal ein paar kleine Fragen stellen. Grundsätzlich vertehe ich natürlich was ein Zeiger an sich ist und was er bewirkt, aber z.B. das inkrementieren (ich glaube so heißt das [ z.B.: *zeiger++; ] ) macht mir schwierigkeiten. Jetzt kam mir aber der Gedanke, dass inkrementieren (falls es denn wirklich so heißt) nur bei zeigern auf arrays funktioniert. Dann gäbe das auch sinn und es wäre für mich definiert welches der nächste integer (o.ä.) ist auf welchen der Zeiger zeigt. Ich könnte dann also einen Zeiger auf das erste Element eines Arrays setzen und dann schritt für schritt verschieben und so ein array einfach element für element auslesen. Alternativ führt hoffentlich auch array[i] mit i++ zu dem gleichen ergebnis beim auslesen einer Variable. Richtig so???? Zur Behandlung von Zeigern wollte ich nochmal sicherstellen, dass mein wissen korrekt ist. Demnach steigert "zeiger++;" den Wert der Varibale auf die der Zeiger zeigt und "*zeiger++;" verschiebt den Zeiger. Richtig?? ______________________________ Eine weiter Frage zum Array an sich wäre dann noch, ob ich z.B. das 10 Element in einem Array mit array[9] definieren bzw. auch auslesen kann. Oder ob dies nur mit Zeigern geht, die man erst an diese Stelle setzen muss, wie auch immer das dann schnell und einfach gehen soll.
Probier es doch erstmal aus...
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | |
4 | struct test_struct_s |
5 | {
|
6 | int a,b,c,d; |
7 | };
|
8 | |
9 | int main() |
10 | {
|
11 | struct test_struct_s x; |
12 | struct test_struct_s *p; |
13 | |
14 | p = &x; |
15 | |
16 | printf("%p\r\n", p); |
17 | p++; |
18 | printf("%p", p); |
19 | |
20 | return 0; |
21 | }
|
Was zeigt dir das kleine Progrämmchen den an? ;)
> Eine weiter Frage zum Array an sich wäre dann noch, ob ich z.B. das 10 > Element in einem Array mit array[9] definieren bzw. auch auslesen kann. Ja, kannst du. Was dann drin steht ist eine ander Geschichte. > Oder ob dies nur mit Zeigern geht, die man erst an diese Stelle setzen > muss, wie auch immer das dann schnell und einfach gehen soll. Das geht mit Zeigern oder auch per indiziertem Zugriff "array[i]". Der Zugriff bleibt trotzdem undefiniert, da der Speicher dort nicht mehr zum Array gehört.
1 | *zeiger++; |
Inkrementiert das, worauf der Zeiger gerade zeigt.
1 | zeiger++; |
Inkrementiert den Zeiger selbst, d.h. der Zeiger an sich wird um die Größe (sizeof) des Elements, auf das er zeigt, erhöht. Dabei ist es zunächst mal völlig egal, ob das ein Zeiger auf ein Array ist oder nicht (eine Variable ist ja auch nichts anderes als ein Array aus einem einzigen Element). Einen "Zeiger auf Array" gibt es in C gar nicht. Ein Zeiger zeigt immer auf einen bestimmten Variablentyp. Wenn zeiger bei einer AVR-Plattform auf ein Objekt vom Typ long zeigt, dann wird das, was in zeiger steht, als 32-Bit-Adresse interpretiert. Auf einer 8-Bit-Plattform führt ein Inkrementieren also dazu, dass der Zeiger danach schlicht und ergreifend auf die Speicherstelle 4 Bytes weiter zeigt. Ein mit
1 | unsigned int var[10]; |
2 | unsigned int *ptr; |
3 | ptr = var; |
definierter Zeiger weiß nicht, dass er auf ein Array zeigen soll, sondern nur, dass er auf eine Variable vom Typ unsigned int zeigen soll. Wenn der Zeiger mit
1 | ptr++; |
inkrementiert wird, dann wird sein Wert um /sizeof(int)/ erhöht, auch dann, wenn er vorher mit
1 | ptr = &array[9]; |
auf das letzte Element des Arrays initialisiert wurde. Es gibt dabei weder eine Warn- noch eine Fehlermeldung! Das ist einerseits nicht ganz ungefährlich, eröffnet aber andererseits auch zusätzliche Möglichkeiten, Speicher zu verwalten. Übrigens: Der * ist der sog. Dereferenzierungsoperator, d.h. er dereferenziert den Zeiger und liefert das Objekt zurück, auf das der Zeiger gerade zeigt. Das & ist in diesem Zusammenhang der Adressoperator. Er interpretiert den Operanden, der dahinter steht, als Adresse.
Johannes M. wrote:
>
1 | *zeiger++; |
> Inkrementiert das, worauf der Zeiger gerade zeigt.
Nein, dafür müsstest du Klammern setzen. Es inkrementiert den Zeiger.
Johannes M. wrote:
1 | *zeiger++; |
Hier wird an der Speicherstelle, auf die der zeiger zeigt, implizit nichts gemacht. In zwei Zeilen aufgeteilt ist das dann:
1 | *zeiger; // zeiger wird nur dereferenziert, aber nichts damit gemacht |
2 | zeiger++; // zeiger wird auf das nächste Element gesetzt |
D.h. hier fehlt z.B.
1 | *zeiger++=inhalt; // Schreiben auf zeiger, anschliessend incementieren |
oder
1 | inhalt=*zeiger++; // Lesen von zeiger, anschliessend incementieren |
Ausführlich sieht das dann so aus:
1 | *zeiger=inhalt; // Schreiben |
2 | zeiger++; // increment |
bzw.
1 | inhalt=*zeiger; // Lesen |
2 | zeiger++; // increment |
Gewünscht war (wie Stefan Ernst geschrieben hat) vermutlich:
1 | (*zeiger)++; |
Jetzt wird erst die Adresse berechnet, auf die zeiger zeigt, und der Inhalt dort dann incrementiert.
Johannes M. wrote: >Das & ist in diesem Zusammenhang der Adressoperator. Er interpretiert >den Operanden, der dahinter steht, als Adresse. Ist das so? Ich dachte immer, der &-Operator sorgt dafür, dass nicht Wert der Variablen dahinter genommen wird, sondern dessen Adresse....?
Johannes M. wrote: [...]
1 | zeiger++; |
> Inkrementiert den Zeiger selbst, d.h. der Zeiger an sich wird um die > Größe (sizeof) des Elements, auf das er zeigt, erhöht. [...] Das ist falsch. Der Zeiger wird um die bei der Definition des Zeigers angegebene Größe erhöht und nicht um die Größe des Elements auf das er zeigt. In den allermeisten Fällen sind diese beiden Größen jedoch identisch. liebe Grüße frank
Für alle, die es noch gewohnt sind, mit Papier zu arbeiten und gerne mal in Antiquariaten stöbern: ***************************************************************** K.Schröder: C Das Pointer-Buch, Oldenbourg Verlag 1992, ISBN3-486-22247-3 Broschur, ca 190 Seiten ***************************************************************** Büschen hakelig geschrieben, aber beleuchtet Zeiger und ihre Handhabung von wirklich fast allen Seiten(die Definition von Zeigern bzw deren Interpretation nach der 12-Uhr-Regel hat mir besonders gut gefallen). mfg
Hui Viele gute antworten. Danke, da hab ich wieder stoff zum nachforschen. Vielen Dank an alle schreiber!
Huuups, ich glaube, ich sollte nicht mehr unter Alkoholeinfluss schreiben (Hmmm, so viel hatte ich doch gar nicht intus?!?). Da habe ich ja einiges ganz schön durcheinandergebracht... Sorry. Da habe ich echt wider besseren Wissens geschreibselt. Also: Nach Biergenuss keine Postings mehr (versprochen!). Vielleicht ist auch in dem Ami-Bier irgendwas drin, was bestimmte Hirnbereiche selektiv lahmlegt...
Johannes M. wrote: > Vielleicht ist > auch in dem Ami-Bier irgendwas drin, was bestimmte Hirnbereiche selektiv > lahmlegt... Und zwar alle Hirnbereiche!
Simon K. wrote: > Johannes M. wrote: >> Vielleicht ist >> auch in dem Ami-Bier irgendwas drin, was bestimmte Hirnbereiche selektiv >> lahmlegt... > > Und zwar alle Hirnbereiche! Na, so schlimm war es auch wieder nicht. Immerhin war ich noch in der Lage, einen Computer zu bedienen...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.