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
Variabeln (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äktem Umfang rechnen. Es
gibt (außer &, *) nur Addition (+), Subtraktion (-),
Increment (++) und Decrenment (--). 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 erfiolgen.
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.
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 in's 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 mur die Speicheradresse dieser großen
Variable übergibt, dann kann die Funktion diese Variable direkt
verändern. Eine Argumet-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