Früher gab es keine Referenzen, sondern nur Zeiger. Da Zeiger aber recht kompliziert zu handhaben sind und auch viele Tücken haben, wurden Referenzen eingeführt. Referenzen sind vereinfachte Zeiger. Ein Zeiger an sich verhält sich ähnlich wie eine Referenz, allerdings mit 2 wesentlichen Unterschieden
1. ein Zeiger kann ungültig sein. Eine Referenz ist immer an einen Wert gebunden. Zeiger sind das nicht. Zeiger können undefiniert sein, zB int* p; - hier zeigt p irgendwo hin. Wenn wir ihn jetzt ansprechen *p=3; erzeugen wir undefiniertes Verhalten (also meistens einen Absturz. Es gibt auch NULL Zeiger, diese zeigen auf 0 und somit als ungültig gekennzeichnet. int* p=0;.
2. ein Zeiger kann 'wandern'. Mann kann einen Zeiger ganz oft auf verschiedene Sachen zeigen lassen. zB wenn man 10 int Variablen hintereinander hat (Array), kann man ganz einfach in einer Schleife mit einem Zeiger alle 10 int Variablen ansprechen.
#include<iostream>
using namespace std;
int main()
{
int array[10];
int i;
int* zeiger;
zeiger=&array[0]; //alternative syntax: zeiger=array;
for(i=0;i<10;++i)
{
*zeiger=i;
++zeiger;
}
for(i=0;i<10;++i)
{
cout<<array[i]<<"\n";
}
cin.get();
}int* ist ein Zeiger auf int. Wir sehen hier ein neues Vorkommen von &. Es liefert die Adresse von array[0]. Während Referenzen lediglich einen Aliasnamen darstellen, zeigen Zeiger direkt in den Speicher, dh natürlich, dass wir wissen müssen, wo im Speicher das erste Element von array zu finden ist. und & liefert uns diese Information.
Nun haben wir zeiger auf array 'hingebogen'. In der Schleife sehen wir eine 'Indirektion': Zeiger an sich ist die Speicheradresse. Was aber wenn wir wissen wollen was an dieser Adresse steht? Wir schreiben *zeiger. Dies schimpft sich Indirektion. Naja, wichtig ist, dass wir durch den Stern den Inhalt ansprechen und somit das ändern auf das der Zeiger zeigt.

In C ist jede Zeichenkette ("Hallo") ein char*. Um das Ende zu kennzeichnen verwendet man die Zahl 0 bzw. das Zeichen '\0'.
#include <iostream>
using namespace std;
void print(char* p)
{
while(*p) //kurform von *p!=0 oder *p!='\0'
{
cout<<*p;
++p;
}
}
int main()
{
print("Hello World\n");
}
Wie bei Variablen und Referenzen gibt es auch bei Zeigern ein const:
char* p; //p ist ein Zeiger auf char
char const* p; //p ist ein Zeiger auf const char
const char* p; //wie bei int const und const int, kann man char und const tauschen
//p ist ein Zeiger auf const char
char* const p; //p ist ein const Zeiger auf char
char const* const p; //p ist ein const Zeiger auf const char
const char* const p; //wie duerfen tauschen
//p ist ein const Zeiger auf const char
Wenn der Zeiger konstant ist, dann dürfen wir den Zeiger nicht verändern (++p; ist verboten, *p='x'; ist erlaubt). Also den Zeiger nicht woanders hinzeigen lassen. Wenn allerdings char konstant ist, dann dürfen wir den Speicher auf den der Zeiger zeigt, nicht verändern (++p; ist erlaubt, *p='x'; ist verboten).
Zeiger sind ein sehr komplexes Thema welches ich hier nur angerissen habe. Aber du kannst froh sein, als C++ Programmierer verwendet man fast nur Referenzen und kaum Zeiger! Für weiterführende Informationen sei auf A Tutorial on Pointers and Arrays in C verwiesen.
Erinnerst du dich an die Funktion tausche()? Deine Aufgabe ist es, diese Funktion mit Zeigern statt Referenzen zu schreiben und zu überlegen, ob man hierführ besser Zeiger oder besser Referenzen verwendet!