Call by Reference

Bisher haben wir nur die Werte von Variablen an Funktionen übergeben. Diese Art der Parameterübergabe wird „call by value“ genannt. Sie hat den Nachteil, dass nur ein Wert mit return zurückgegeben werden kann. Soll aber eine oder mehrere Variablen in der Funktion verändert werden, so muss als Parameter die Adresse der Variable übergeben werden. Oder anders gesagt ein Zeiger auf diese Variable („call by reference“). Die Adresse übergibt man bei einfachen Variablen mit dem Adressoperator &.

Beispiel:

#include <stdio.h>
 
int main ()
{
  int x=5;
  int y=7;
 
  swap (&x, &y);
 
  printf ("%d, %d", x, y);
 
  return 0;
}
 
void swap (int *p1, int *p2)
{
  int help;
 
  help=*p1;
  *p1=*p2;
  *p2=help;
}

In diesem Beispiel werden die Variablen x und y in der Funktion swap vertauscht.

swap (&x, &y);

Hier werden die Adressen der Variablen an die Funktion übergeben.

void swap (int *p1, int *p2)

In der Funktion erhalten dann die Pointer p1 und p2 die Adressen von x und y. p1 zeigt auf x und p2 auf y.

help ist eine integer Variable die nur zum Vertauschen der Werte dient.

Mit dem Verweisoperator * können Daten mithilfe des Zeigers bearbeitet werden.

Arrays als Parameter

In C besteht ein sehr enger Zusammenhang zwischen Arrays und Zeigern. Wie im Kapitel Arrays erklärt, ist der Name des Feldes (ohne Indexklammern) nichts anders als ein Zeiger auf das erste Feldelement. Aus diesem Grund ist der Adressoperator bei der Übergabe an die Funktion nicht nötig.

Beispiel:

#include <stdio.h>
 
int main ()
{
  int a[]={5, 4, 3, 2, 1}, i;
 
  sort (a);                           // kein & !!!
 
  for (i=0; i<5; i++)
    printf ("%d\n", a[i]);
 
  return 0;
}
 
void sort (int *p)                    // oder int p[]
{
...
}

a ist ein konstanter Zeiger und kann nicht verändert werden.

*p ist ein Zeiger auf das erste Feldelement.

Um auf die nächsten Zeichen zugreifen zu können, muss der Zeiger inkrementiert werden. Dafür eignet sich eine for-Schleife.

Beispiel:

void print_array (int *p, int size_of_array)            // *p ist ein Zeiger auf das 1. Element eines Arrays und 
                                                        // size_of_array gibt die Länge des Arrays an
{
  int i;
 
  for (i=0; i<size_of_array; i++, p++)
    printf ("%d\n", *p);
}

Dabei muss man aber aufpassen, dass man den Bereich des Arrays nicht überschreitet, da man sonst in einen ungültigen Bereich schreibt. Dies kann bis zum Absturz des Betriebssystems führen.

Zeiger als Rückgabewert einer Funktion

Es ist auch möglich einen Zeiger mittels return an die rufende Funktion zurückzuliefern. Dies muss auch im Funktionskopf beachtet werden.

Die folgende Funktion sucht nach einem bestimmten Zeichen „ch“ im String „string“ und liefert einen Pointer auf dieses Zeichen zurück. Ist das Zeichen nicht vorhanden, wird 0 zurückgeliefert.

#include <stdio.h>
 
char* first_occurance (char *string, char ch);
 
int main ()
{
  char string[]={"Hallo\0"}, ch = 'a';
  char *first;
 
  first = first_occurance (string, ch);
 
  printf ("\n\n");
 
  if (first != NULL)
    printf ("%c\n\n", *first);
  else
    printf ("Zeichen nicht vorhanden\n\n");
 
  return 0;
}
 
 
char* first_occurance (char *string, char ch)      // Rückgabetyp ist ein Pointer vom Typ char, deshalb char* 
{
  char *p;
 
  while (*string != '\0')                          // sucht bis zum Ende des Strings
  {
    if (*string == ch)                             // Zeichen gefunden
    {
      p = string;                                  // p zeigt auf das Zeichen und wird zurückgegeben
      return p;
    }
 
    string++;                                      // nächstes Zeichen wird überprüft
  }
 
  return 0;                                        // Zeichen nicht gefunden
}