Hallo Leute,
als Anfänger in der µC-Programmierung komme ich, mithilfe von diversen
Tutorials, schön zügig voran, leider mit einer Ausnahme:
*Zeiger / Pointer in C.
Tut mir leid, egal an wievielen Orten ich es schon gelesen habe, ich
checke es einfach nicht.
"Mit Zeiger oder Pointer wird eine spezielle Variable bezeichnet, die
auf eine andere Variable oder Funktion verweist."
Soweit, so gut, das kann ich mir noch vorstellen.
Aber schlimmer sind dann die Code-Beispiele. Mir wird schon von den
Klammern, Sternchen und anderen Symbolen schwindlig, und ich werde nicht
schlau, warum es gerade so geschrieben wird.
Könnte mir jemand ein Beispiel von einem MINIMAL-CODE geben, wo jede
Zeile ausführlich kommentiert ist, was und warum sie macht, und wo
vielleicht noch eine einfache Zeichnung die Speicher-Zugriffe erklärt?
Es wird mich wesentlich weiter bringen.
An die hilfsbereiten vielen Dank voraus!
Grüße
Michal
Ich hatte das gleiche Problem in den letzten Tagen, will auch in Zukunft
mit C programmieren, konnte auch kaum was Brauchbares zu dem Thema
finden.
Die Lösung ist ansich ganz einfach:
1. Buffer mit z.B. 40 Zeichen definieren, den dazugehörigen Zeiger
nachfolgend definieren ...hier als *pBuffer bezeichnet ...alles in einer
Zeile.
unsigned char Buffer[40], *pBuffer;
Nächster Schritt:
void Beispiel(void)
{
pBuffer = Buffer;
Nun zeigt der Zeiger auf die Anfangsadresse von Buffer, zwingend
erforderlich ...aber ohne Stern!!!
*pBuffer = 1;
Die Anfangsadresse von Buffer wurde nun mit dem Wert 1 geladen
*pBuffer +1 = 2;
Adresse von Buffer +1, also um 1 erhöhen und eine 2 in den Buffer
schreiben
}
Wichtig ist, wenn man mit dem Zeiger arbeitet und Werte über den Zeiger
in den Buffer schreiben bzw. lesen will das Sternchen vorneweg nicht
vergessen!!!
Ich hoffe, es war auch ohne hochtrabende Verschachtelungen verständlich?
Viel Spass beim Programmieren
Aus Prozessorsicht sind Pointervariable Variable, die die Adresse einer
anderen Variablen enthalten.
1
intWert=5;
2
int*pW=NULL;// Integerpointer definieren und mit NULL-Pointer init.
3
4
pW=&Wert;// Adresse von Wert an pW zuweisen
5
6
printf("%d",*pW);// Inhalt der Variablen ausgeben, auf die pW zeigt
Das printf gibt 5 aus.
Für Arrays hat C eine besondere Regel parad: Der Arrayname ist eine
Pointerkonstante. Deswegen muß man den Adressoperator & bei der
Zuweisung der Adresse eines Strings weglassen.
1
charstr[]="Hallo Welt";
2
char*pS=NULL;// Stringpointer definieren und mit NULL-Pointer init.
3
4
pS=str;// Adresse von str an pS zuweisen
5
6
printf("%s",pS);// Inhalt der Variablen ausgeben, auf die pS zeigt
Servus,
also Variabeln werden im Speicher abgelegt, jeder Speicherstelle hat
eine eigen Adresse. Soweit so klar?
Ein Pointer ist nun eine spezielle Art einer Variable. In dieser
Variable wird die Adresse einer anderen Variable (z.B. int, char, bool
usw.) gespeichert.
Hier ein kleines Bsp:
1
#include<stdio.h>
2
3
intmain(void)
4
{
5
inti;//das ist eine Variable vom typ Integer (ganzzahl)
6
int*pointer_auf_i;//das ist eine Variable vom Typ "pointer auf int
7
8
pointer_auf_i=&i;//der Adressoperator "&" liefert die Speicheradresse
9
//von dr Variable "i" (da wo sie im speicher liegt)
10
11
i=10;//die Variable "i" hat nun den wert 10
12
13
printf("%p\n",pointer_auf_i);//Die adresse von "i" wird ausgegeben
14
printf("%i\n",*pointer_auf_i);//Der Inhalt der Variable der an der in
Hallo zusammen,
super, danke an Euch alle, einige Beispiele sind sehr einleuchtend.
Eine Frage fällt mir jetzt ein:
"printf("%p\n",pointer_auf_i); //Die adresse von "i" wird ausgegeben"
Heisst es, dass ich hier echt die Adresse der Speicherzeile
zurückkriege, so wie sie im Datenblatt durchnummeriert sind, z.B. $FC5?
#include <stdio.h>
int main(void)
{
int i; //das ist eine Variable vom typ Integer (ganzzahl)
int *pointer_auf_i; //das ist eine Variable vom Typ "pointer auf int
pointer_auf_i = &i; //der Adressoperator "&" liefert die
Speicheradresse
//von dr Variable "i" (da wo sie im speicher
liegt)
i = 10; //die Variable "i" hat nun den wert 10
printf("%p\n",pointer_auf_i); //Die adresse von "i" wird ausgegeben
printf("%i\n",*pointer_auf_i); //Der Inhalt der Variable der an der
in
//"pointer_auf_i" gespeicherten
Adresse
//wird ausgegeben
}
Meiner Meinung nach liegt eine Schwierigkeit darin, dass der "*" ein
wenig seine Bedeutung ändert.
Beim Anlegen des Pointers
int *x;
liest man: lege einen Pointer mit dem Namen "x" an, der auf eine Integer
Variable verweisst.
Bei der Benutzung später
int y;
y=*x;
liest man: weise der Variablen "y" den Wert der Speicherzelle zu, auf
die der Pointer "x" zeigt.
Und wo genau soll da jetzt die Änderung der Bedeutung sein?
"*x" ist einfach nur äquivalent zu "das worauf x zeigt".
int *x;
-> "das worauf x zeigt" hat den Typ int.
y=*x;
-> weise y den Wert von "das worauf x zeigt" zu.
Michal schrieb:
> ok, und wenn sich bei einem aufwendigen Programm der Speicherort einer> Variablen ändert, weisst der Pointer das?
Nein, aber Variablen springen auch nicht einfach im Speicher umher. ;-)
Gerd Vg schrieb:
> *pBuffer +1 = 2;
Das vergessen wir dann auch bitte ganz schnell wieder und setzen ein
Klammerpaar.
Ansonsten ist Zeigerrechnung keine Hexerei:
1
a[i] = *(a + i) = *(i + a) = i[a]
1
char*str="abXde";
2
intidx=2;
3
4
charc;
5
6
/*
7
Die folgenden Zeilen weisen der Variablen c ein 'X' zu
>Und wo genau soll da jetzt die Änderung der Bedeutung sein?
"*x" ist einfach nur äquivalent zu "das worauf x zeigt".
>int *x;>-> "das worauf x zeigt" hat den Typ int.>>y=*x;>-> weise y den Wert von "das worauf x zeigt" zu.
Meiner Meinung nach hat der "Stern" in der Deklaration und im Programm
zwei verschiedene Bedeutungen:
int *x; // lege einen Pointer "x" an
Hier ist der Stern eine art erweiterte Typenbezeichnung, nämlich
"Pointer". Der Pointer hat ja den Namen "x" und nicht "*x"
y=*x; // holle das worauf der Pointer "x" zeigt
Hier hat der Stern die Bedeutung "hole den Inhalt"
Sven P. schrieb:
> Ansonsten ist Zeigerrechnung keine Hexerei:>
1
> a[i] = *(a + i) = *(i + a) = i[a]
2
>
Was diese "Gleichung" soll, verstehe ich auch nicht.
Ich würde sowieso behaupten, dass diese falsch ist, denn vor i muss noch
eine Konstante (die Wortgröße).
Christian L. schrieb:
> Ich würde sowieso behaupten, dass diese falsch ist, denn vor i muss noch> eine Konstante (die Wortgröße).
Nein.
Schlage im nächstbesten C-Buch (oder online) "Zeigerarithmetik" nach.
franz schrieb:
>>Und wo genau soll da jetzt die Änderung der Bedeutung sein?> "*x" ist einfach nur äquivalent zu "das worauf x zeigt".>>int *x;>>-> "das worauf x zeigt" hat den Typ int.>>>>y=*x;>>-> weise y den Wert von "das worauf x zeigt" zu.>> Meiner Meinung nach hat der "Stern" in der Deklaration und im Programm> zwei verschiedene Bedeutungen:
Das kann man auf verschiedene Arten sehen.
Kernighan (der Mann der C entwickelt hat), hat die Definition von
Pointer aus genau dem Grunde so gestaltet wie sie heute noch ist, weil
die Definition wiederspiegelt.
int *x;
bedeutet in den Augen des Sprachschöpfers:
an der Stelle x im Speicher findet man einen int.
Die Definition von Pointern spiegelt also die Verwendung wieder. Das war
die ganze ursprüngliche Idee.
Stefan Ernst schrieb:
> Christian L. schrieb:>>> Ich würde sowieso behaupten, dass diese falsch ist, denn vor i muss noch>> eine Konstante (die Wortgröße).>> Nein.> Schlage im nächstbesten C-Buch (oder online) "Zeigerarithmetik" nach.
Ok, ich muss mich verbessern, vor i kommt keine Konstante. Nach etwas
Überlegung habe ich auch verstanden was hakus Gleichung bedeutet.