Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
|
c:func:callbyreference [2008/11/08 22:05] dani93 |
c:func:callbyreference [2022/11/21 22:34] (aktuell) nufan |
||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | [noch in Arbeit - dani93] | + | ====== 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. | |
| - | ====== call by reference ====== | + | 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 &. |
| - | Bisher haben wir nur die Werte von Variablen an Funktionen übergeben. Diese Art der Parameterübergabe wird "call by value" genannt. Dies hat den Nachteil, dass nur ein Wert über 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. Die Adresse übergibt man bei einfachen Variablen mit dem Adressoperator &. Oder anders gesagt ein Zeiger auf diese Variable ("call by reference"). | + | |
| Beispiel: | Beispiel: | ||
| Zeile 12: | Zeile 10: | ||
| int main () | int main () | ||
| { | { | ||
| - | |||
| int x=5; | int x=5; | ||
| int y=7; | int y=7; | ||
| Zeile 21: | Zeile 18: | ||
| return 0; | return 0; | ||
| - | |||
| } | } | ||
| void swap (int *p1, int *p2) | void swap (int *p1, int *p2) | ||
| { | { | ||
| - | |||
| int help; | int help; | ||
| Zeile 32: | Zeile 27: | ||
| *p1=*p2; | *p1=*p2; | ||
| *p2=help; | *p2=help; | ||
| - | |||
| }</code> | }</code> | ||
| Zeile 48: | Zeile 42: | ||
| Mit dem Verweisoperator * können Daten mithilfe des Zeigers bearbeitet werden. | Mit dem Verweisoperator * können Daten mithilfe des Zeigers bearbeitet werden. | ||
| - | ===== Zeiger und Arrays ===== | + | |
| + | ===== Arrays als Parameter ===== | ||
| In C besteht ein sehr enger Zusammenhang zwischen Arrays und Zeigern. | In C besteht ein sehr enger Zusammenhang zwischen Arrays und Zeigern. | ||
| - | Wie im Kapitel [[c:array|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. | + | Wie im Kapitel [[c:type:array|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: | Beispiel: | ||
| Zeile 59: | Zeile 54: | ||
| int main () | int main () | ||
| { | { | ||
| + | int a[]={5, 4, 3, 2, 1}, i; | ||
| - | int a[5]={5, 4, 3, 2, 1}, i; | + | sort (a); // kein & !!! |
| - | + | ||
| - | sort (a); | + | |
| for (i=0; i<5; i++) | for (i=0; i<5; i++) | ||
| Zeile 68: | Zeile 62: | ||
| return 0; | return 0; | ||
| - | |||
| } | } | ||
| - | void sort (int *p) // oder int p[] | + | void sort (int *p) // oder int p[] |
| { | { | ||
| - | |||
| ... | ... | ||
| - | |||
| }</code> | }</code> | ||
| Zeile 86: | Zeile 77: | ||
| Beispiel: | Beispiel: | ||
| <code cpp> | <code cpp> | ||
| - | 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 | + | 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; | int i; | ||
| for (i=0; i<size_of_array; i++, p++) | for (i=0; i<size_of_array; i++, p++) | ||
| printf ("%d\n", *p); | printf ("%d\n", *p); | ||
| - | |||
| }</code> | }</code> | ||
| - | Dabei muss man aber aufpassen, dass man den Bereich des Arrays nicht überschreitet, da man sonst in einen ungültigen Bereich schreibt. Das bis zum Absturz des Computers führen kann. | + | 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. | ||
| + | |||
| + | <code cpp> | ||
| + | #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 | ||
| + | }</code> | ||