C für PICs: Pointer
        
      
      
    
    zurück
        zu C für PICs , C-Compiler , PIC-Prozessoren , Elektronik , Homepage
    
    C für PICs
      
      Grundlagen von C
      Variablen
          Funktionen
          Operationen
        Programmablaufsteuerung
      Arrays und Strings
      Pointer
      Strukturierte Typen
        PIC-spezifisches
    
    
        zurück zu C für PICs 
    
    
    Pointer
    
    Ein Pointer ist eine Variable, die eine Speicheradresse des
    Prozessors enthält. Das kann eine Adresse des Datenspeichers oder
    eine Adresse des Programmspeichers sein. Pointer verwendet man, um
    auf Variablen (Datenspeicher) oder Funktionen (Programmspeicher)
    flexibel zugreifen zu können.
    
    
Pointer:
      Allgemeines
    
    Ein Pointer ist eine Variable, und wird auch wie eine solche
    Deklariert. Dabei wird angegeben, auf was für einen Typ dieser
    Pointer zukünftig verweisen soll. Um den Pointer als solchen zu
    kennzeichnen, wird seinem Namen bei der Deklaration ein "*"
    vorangestellt:
    
    typ *Pointername;
    
    
    Ich deklariere nun einen Pointer, der auf Interer-Variablen zeigen
    kann.
    
    int *Zeiger;
    
    
    Um nun dem Pointer mit der Adresse einer existierenden Variablen zu
    beschreiben, muss man natürlich die Adresse dieser Variable erst mal
    herausbekommen. Dafür gibt es in C den &-Operator, der einer normalen Variable direkt
    vorangestellt wird, um deren Adresse zu ermitteln.
    
    int *Zeiger;
      int
        EchteVariable;
      Zeiger =
        &EchteVariable;
      
    
    So, nun steht in Zeiger die Adresse von EchteVariable. Was habe ich
    davon? Man kann nun auf den Wert von EchteVariable auch mit Hilfe
    des Pointers Zeiger zugreifen. Dazu muss man C anweisen, auf die
    Integer-Variable zuzugreifen, auf die Zeiger zeigt. Dazu wird dem
    Pointer-Namen ein "*" vorangestellt. Man kann jetzt also anstelle
    von "EchteVariable" auch "*Zeiger" schreiben.
    
    EchteVariable = 5;
      int
        AndereVariable;
      AndereVariable
=
        *Zeiger;
    
    
    
    Mit Pointern lässt sich nur in beschränktem Umfang rechnen. Es gibt
    (außer &, *) nur Addition (+), Subtraktion (-), Increment (++)
    und Decrement (--). Increment und Decrement vergrößern oder
    Verkleiner den Wert eines Pointers jeweils um die Speichergröße des
    Typs, auf den er zeigt. Der integer-Pointer aus dem obigen Beispiel
    würde bei einem Increment (Zeiger++) um den Wert 2 erhöht werden, da
    Integer 2 Byte groß ist.
    
    
    Pointer
und
      Arrays
    
    Pointer und Arrays haben mehr gemeinsam, als man zunächst einmal
    denken mag. Während die Array-Variable mit einem Index ein
    bestimmtes Element des Arrays darstellt, ist die Array-Variable ohne
    Index nur ein Pointer auf das erste Element des Arrays. Das folgende
    Beispiel mag das verdeutlichen.
    
    int Feld[10];
      Feld[3] = 5;
      int
        *Zeiger;
      Zeiger =
      Feld;
      int
        Ergebnis;
      Ergebnis = Zeiger[3];
    
    
    Ich deklariere das Array "Feld" und belege dessen Element Nr 3 mit
    dem Wert 5. Die anderen Elemente sind mir mal egal. Dann deklariere
    ich einen Pointer mit dem Namen "Zeiger". Anschließend weise ich
    diesem Pointer Feld zu. Da ich Feld ohne einen Index verwende,
    stellt Feld einen Pointer auf das erste Element des Arrays da. Damit
    zeigt Zeiger nun auf den Anfang von Feld.
    
    Ich hätte natürlich auch einen Zeiger auf das erste Element von Feld
    verwenden können. Das wäre Feld[0] gewesen. Da Feld[0] aber kein
    Zeiger ist (sondern eine Integer-Variable) hätte ich schreiben
    müssen:
    Zeiger = &Feld[0];
    
    
    Da ist es dann doch einfacher direkt Feld zu verwenden. Abschließend
    sieht man, wie ich nun Zeiger wie ein Array verwende, um auf ein
    einzelnes Element von Feld zuzugreifen. Es handelt sich um das
    Element Nr 3, in dem vorab ja der Wert 5 gespeichert wurde. 
    
    Das hier beschriebene erklärt auch, warum man nicht einfach ein
    Array in ein anderes Array kopieren kann. Das Kopieren muss stets
    elementweise erfolgen.
    
    int a[100], b[100];
        ...
      a
        = b;          
                   
                   // FALSCH
      char i;
      for (i=0;
        i<100; i++) a[i] = b[i];      // RICHTIG
    
    
    
    
    Pointer
      und Funktionen
    
    Schon vorher wurde beschrieben, wie Argumente an Funktionen übergeben werden
    können, und wie man ein Argument von einer Funktion zurückerhalten
    kann. 
    Eine dritte Alternative besteht darin, dass man der Funktion als
    Argument den Pointer auf eine Variable übergibt.
    
    Was bringt das?
    Wenn ich möchte, dass eine Funktion einen Variablenwert verändert,
    dann muss ich diesen Wert zunächst an die Funktion als Argument
    übergeben, und das zurückgegebene Argument der ursprünglichen
    Variablen wieder zuweisen. Dazu muss die Variable zwei mal kopiert
    werden, was Zeit kostet.
    
    int Doppel (int a)
      {
         
return
        (a << 1);
      }
      
      void main
        (void)
      {
         
int
        b;
         
b
        = 1;
         
b
        = Doppel(b);   // <-- hier wird 2 mal kopiert
      }
    
    
    Bei einer einzelnen integer-Variable fällt das kaum ins Gewicht.
    Oftmals werden aber umfangreiche strukturierte
      Variablen übergeben. Diese je zwei mal zu kopieren kostet
    nicht nur Zeit, sondern auch Speicherplatz. Es muss ja eine lokale
    Kopie dieser großen Variablen angelegt werden. Im begrenzten
    PIC-Arbeitsspeicher kann es da schnell eng werden.
    
    Wenn man aber der Funktion nur die Speicheradresse dieser großen
    Variable übergibt, dann kann die Funktion diese Variable direkt
    verändern. Eine Argument-Rückgabe ist überflüssig.
    
    void Doppel (int *a)
      {
         
*a
        << 1;
      }
      
      void main
        (void)
      {
         
int
        b;
         
b
        = 1;
         
        Doppel(&b);
      }
    
    
    Anstelle von einzelnen Variablen wird man Arrays, Strings oder
    strukturierte Variablen übergeben. Die werden in C ohnehin als
    Pointer verwaltet, so dass sich hier sogar das vorgestellt & bei
    der Parameterübergabe erübrigt.
    
    void Loesche (int *a)
      {
            char c;
            for (c=0; c<10; c++)
            {
               *a = 0;
               a++;
            }
      }
      
      void main
        (void)
      {
         
int
        b[10];
         
      Loesche(b);
      }
    
    
    
    
    
    
    
-->
weiter
        zu strukturierten Typen
    
    
    
      zurück
          zu C für PICs , C-Compiler , PIC-Prozessoren , Elektronik , Homepage
    
     
    
    Autor: sprut 
    erstellt: 01.10.2007
    letzte Änderung: 01.10.2007