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