Zeiger / Pointer in (µC)-C verstehen

Gast #1442458
Lesenswert?

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
#1442573
Lesenswert?

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
#1442575
Lesenswert?

Aus Prozessorsicht sind Pointervariable Variable, die die Adresse einer 
anderen Variablen enthalten.
1
  int Wert = 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
  char str[] = "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

Hier gibt das printf den Text

   Hallo Welt

aus.
Gast #1442713
Lesenswert?

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
int main(void)
4
  {
5
  int i;              //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 
15
                                  //"pointer_auf_i" gespeicherten Adresse
16
                                  //wird ausgegeben
17
  }
Gast #1442722
Lesenswert?

und hier noch was zum testen, wie geht das wohl?
1
#include <stdio.h>
2

3
int main(void)
4
  {
5
  int i[10]= {1,2,3,4,5,6,7,8,9,10};
6
  int j;
7
  int *pointer_auf_i;
8

9
  pointer_auf_i = &i[0]; //übrigens liefert der name eines Array, also 
10
                         //ohne Klammern auh die adresse zurück
11
                         //also ist dies hier auch so möglich: 
12
                         // pointer_auf_i = i;
13

14
  j = *(i+2) * *(i+8);
15
  
16
  printf("%i * %i = %i\n", *(i+2),*(i+8), j);
17

18
  }
Gast #1442752
Lesenswert?

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
  }
Gast #1442789
Lesenswert?

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.
Gast #1442817
Lesenswert?

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
int idx = 2;
3

4
char c;
5

6
/* 
7
  Die folgenden Zeilen weisen der Variablen c ein 'X' zu
8
  und sind gültiges C:
9
*/
10

11
c = 'X';
12
c = str[2];
13
c = str[idx];
14
c = "abXde"[2];
15
c = "abXde"[idx];
16
c = 2[str];
17
c = idx[str];
18
c = idx["abXde"];
19
c = 2["abXde"];
20
c = *(str + 2);
21
c = *(2 + str);
Gast #1442909
Lesenswert?

>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"
#1443127
Lesenswert?

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.
#1444597
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren