Funktionen, Felder und Parameter- übergabe. Funktionsaufruf mit Feld als Parameter: Parameter = Name des Feldes.

Slides:



Advertisements
Ähnliche Präsentationen
Programme in C++.
Advertisements

Funktionen, Felder und Parameter-übergabe
Funktionen.
Forschungszentrum caesar
(kleine!) Java Einführung Mittwoch, Heute Ziel: erstes Java-Programm erstellen Von der Aufgabenstellung bis zur Lösung Grundlagen Einfache.
Java: Dynamische Datentypen
Indirekte Adressierung
SWITCH - Anweisung.
SWITCH - Anweisung.
Abstrakte Klassen.
Datentyp- umwandlung. Literale sind: Bezeichner mit einem festen Wert wie z.B:
REKURSION + ITERATION. Bemerkung: Die in den folgenden Folien angegebenen "Herleitungen" sind keine exakten Beweise, sondern Plausibilitätsbetrachtungen.
Strukturen. In einer Struktur kann eine beliebige Anzahl von Komponenten (Daten) mit unterschiedlichen Datentypen (im Gegensatz zu Feldern) zusammengefaßt.
ARRAY oder FELD oder VEKTOR
Dynamischer Speicher. Ein Vergleich aus dem täglichen Leben...
Ein Beispiel in Java.
Dynamisches Array als "verkettete Liste". Ein Vergleich.
Dynamischer Speicher und Struktur
Klassenvariable. Da man für jede Kuh bzw. jede Henne auf dem Markt den gleichen Preis für ein Liter Milch, bzw. den gleichen Preis für ein Ei bekommt,
Konstruktoren.
Objekte werden als Adressen (Referenzen) übergeben. Dies führt manchmal zu unerwarteten Ergebnissen...
Parameterübergabe von zweidimensionalen Feldern in Funktionen.
Polymorphie (Vielgestaltigkeit)
Polymorphie (Vielgestaltigkeit)
Objekte und Arbeitsspeicher
V AdresseWert public static void main(...){ int[] v; v=new int[2]; } Was veranlasst diese Anweisung im Arbeitsspeicher ? Es wird im Arbeitsspeicher.
Der Präprozessor. Bevor der Compiler das Programm in Maschinencode übersetzt (nur dieser kann von der CPU, dem Herz des Computers, bearbeitet werden)
Dynamischer Speicher. In einer Funktion wird z.B. mit der Deklaration int i; Speicher auf dem sogenannten Stack reserviert. Wenn die Funktion verlassen.
ARRAY oder FELD oder VEKTOR
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 7 Claudio Moraga, Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 5 Claudio Moraga; Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
Imperative Programmierung Funktionen und Parameter
Einführung in Visual C++
Arrays,Strings&Pointer in C/C++
Wir müssen also überlegen: Implementierung der Knoten, Implementierung der Kanten, daraus: Implementierung des Graphen insgesamt. Annahme: die Knoteninhalte.
Einführung in die Programmiersprache C 1
Java programmieren mit JavaKara
Einführung in die Programmiersprache C 3.Tag Institut für Mathematische Optimierung - Technische Universität Braunschweig.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung
Einführung in die Programmiersprache C 4
Vom Umgang mit Daten. public void myProgram() { int[] saeulenWerte = new int[world.getSizeX()]; for (int i = 0; i < saeulenWerte.length; i++) { saeulenWerte[i]
Variablenkonzept Klassisch, in Java Basistyp
Arrays / Felder Themen: Arrays / Felder / Vektoren Was soll das eigentlich? Erstellen von Arrays Arrays auslesen. Wie sie verwaltet werden.
Agenda für heute, 12. Mai, 2005 ProzedurenProzeduren Funktionsprozeduren Prozedurparameter Lokale und globale Variablen Datentypen: Ordinaltypen.
Programmieren in C Grundlagen C 2
early binding (frühe Bindung) late binding (späte Bindung)
Erweiterte Zuweisungskompatibilität. Wie kann man Objekte verschiedener Klassen einer Klassenhierarchie einander zuweisen ?
Variablen und Datentypen
Funktionen. Aufgabe : Eingabe zweier Zahlen ---> Minimum bestimmen Dann nochmals Eingabe zweier Zahlen ---> Minimum bestimmen.
Dynamisches Array als "verkettete Liste". Ein Vergleich.
Verzweigung oder bedingte Anweisung. Aufgabe: Ein Autofahrer tankt sein Auto voll und schreibt den Kilometerstand auf (drei- stelliger Tageszähler).Wenn.
Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet.
Namensräume (namespaces). verwendet man umfangreiche eigene und fremde Bibliotheken (Sammlungen von Funktionen) so ist die Wahrscheinlichkeit groß, daß.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
FOR Anweisung. Aufgabe : Ausgabe aller ganzen Zahlen von 0 bis 100 auf dem Bildschirm.
Funktionen (Zweck und Eigenschaften) Funktionen sind Unterprogramme, die einen bestimmten Zweck erfüllen Sie zerlegen Probleme in kleine, abgeschlossene.
Strukturen (Eigenschaften) Strukturen dienen zur Zusammenfassung mehrerer Komponenten verschiedener Typen zu einer Einheit, die dann mit gemeinsamen Namen.
Pointer. * und &  Bei der Definition int var1; ○ // „normale“ Variable int *var2; ○ // Zeiger auf einen Integer int *var2 = NULL; ○ // … incl. Initialisierung.
Konstruktoren.
Programmieren in C Wie speichert C
Arrays in C Ein Array ist eine Variable, die aus einer Anzahl von Elementen des gleichen Datentyps besteht, die aufeinanderfolgend im Speicher liegen.
REKURSION + ITERATION.
 Präsentation transkript:

Funktionen, Felder und Parameter- übergabe

Funktionsaufruf mit Feld als Parameter: Parameter = Name des Feldes

Beispiel:... int main(){ int v[3] = {10,20,30}; f(v);... }

Intern bedeutet dies: Die Adresse des nullten Elements (Komponente) des Feldes wird an die Funktion übergeben.

Beispiel:... int main(){ int v[3] = {10,20,30}; f(v); // gleichbedeutend mit: f(&v[0]);... } Dies ist eine ADRESSE

Wie muss also der formale Parameter in der Definition der Funktion deklariert werden ?

int main(){ int v[3] = {10,20,30}; f(v); } void f( ){ *p = 111; *(p+1) = 222; } int *p Dies ist ein POINTER auf einen integer Für Leute, die Pointer nicht mögen, gibt es eine alternative Syntax, in der mehr der Charakter des Feldes betont wird //void f(int p[]){

void f(int v[]){ *p = 111; *(p+1) = 222; } Die beiden Schreibweisen sind gleichwertig... int main(){ int v[3] = {10,20,30}; f(v); } Und in der nächsten Folie gehen wir wieder zurück zur Pointerschreibweise...

int main(){ int v[3] = {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; }

Was geschieht beim Ablauf des Programms ?

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2] ( *4) =

int main(){ int v[3]= {10,20,30}; f(v); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2] ( *4) = Welche Art von Parameter ist p ? (i), (o), (i/o) Ein Input-Output- Parameter, also (i/o)

Frage: Wie ist der Programmablauf beim Aufruf von f(&v[0])

Antwort: Wie beim Aufruf von f(v)

Frage: Wie ist der Programmablauf beim Aufruf von f(&v[1])

int main(){ int v[3] = {10,20,30}; f(&v[1]); } void f( ){ *p = 111; *(p+1) = 222; } int *p

Was geschieht beim Ablauf des Programms ?

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2]

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2] ( *4) =

int main(){ int v[3]= {10,20,30}; f(&v[1]); } void f(int *p){ *p = 111; *(p+1) = 222; } v[0] v[1] v[2] ( *4) =

Aufgabe:

Erstellen Sie die Funktion reset, die eine bestimmte Anzahl sich hintereinander befindlicher Elemente eines Integer-Feldes auf 0 setzt. Testen Sie danach die Funktion in einem Programm.

// includes vorher einfügen const int len = 10; void reset1(int *p, int von, int bis); int main(){ int zahlen[len]; int i; // Feld irgendwie füllen for(i=0;i<len;i++){ zahlen[i] = 10+2*i; }

Geben Sie die einzelnen Elemente des Feldes an:

// Feld ausdrucken for(i=0;i<len;i++){ printf("%d ",zahlen[i]); } printf("\n"); reset1(zahlen, 3, 7); // Feld ausdrucken for(i=0;i<len;i++){ printf("%d ",zahlen[i]); } }

void reset1(int *p, int von, int bis){ int i; for(i=von; i<=bis; i++){ *(p+i)=0; } }

Geben Sie die einzelnen Elemente des Feldes an:

Weitere mögliche Lösung:

void reset2(int *p, int anz){ int i; for(i=0; i<anz; i++){ *(p+i)=0; } }

int main(){ //... // statt // reset1(zahlen, 3, 7); // alternativ: reset2( ); //... } &zahlen[3], 5

Weitere mögliche Lösung:

void reset3(int *von, int *bis){ while(von <= bis){ *von=0; von=von+1; } }

int main(){ //... // statt // reset1(zahlen, 3, 7); // alternativ: reset3( } &zahlen[3], &zahlen[7] );

Wie müssen die Adressen der Feldelemente organisiert sein, damit diese Lösung funktioniert? void reset3(int *von, int *bis){ while(von <= bis){ *von=0; von=von+1; } } Adresse Feldelement 0 < Adresse Feldelement 1 < Adresse Feldelement 2 < …

Aufgabe:

V erändern Sie die Funktion reset1 so, dass der Programmierer, der sie verwendet, bestimmen kann, auf welchen Wert (nicht nur 0), die Elemente gesetzt werden sollen. Die veränderte Funktion soll reset1a heissen.

void reset1a(int *p, int von, int bis, int wert){ int i; for(i=von; i<=bis; i++){ *(p+i)=wert; } }

Alternative Syntax bei der Definition einer Funktion mit einem Feld als Parameter

int main(){ int v[3] = {10,20,30}; f(v); } void f(int p[]){ p[0]= 111; // *p=111 p[1] = 222; // *(p+1)=222 } p[1]*(p+1) z.B. ist gleichbedeutend mit Dies gilt NUR innerhalb der Definition (Implementierung) der Funktion (unten).

Funktionsaufruf mit Feld als reinem Input-Parameter.

Aufgabe: Erzeugen Sie eine Funktion mit einem Feld als Parameter. Das Feld soll nur daraufhin überprüft werden, ob seine Elemente positive Werte haben.

int istPositiv(int v[], int anz){ int i=0; while(i<anz){ if(v[i]<0) return(-1); i=i+1; } return(0); } Welche Art von Parameter ist das Feld v ? (i), (o), (i/o) Ein reiner Input- Parameter, also (i) Ein unkonzentrierter Programmierer könnte z.B. folgendes machen: v[i] = v[i+1]; Welche Art von Parameter ist dann das Feld v ? v ist dann ein (i/o)- Parameter.

// Hier ist noch das // Hauptprogramm int main(){ int erg; int w[4]={11,12,-6,9}; erg=istPositiv(w,4); printf("erg=%d\n",erg); return(0); } Welchen Wert hat erg ? erg hat den Wert –1, da mindestens ein Element einen negativen Wert hat.

Um ein Feld als reinen Input-Parameter (read-only- Speicher) zu benutzen, d.h. es (schreibgeschützt) gegen Veränderungen durch den Programmierer zu schützen, kann man den Parameter mit const als eine Konstante deklarieren.

int istPositiv(const int v[], int anz){ int i=0; while(i<anz){ if(v[i]<0) return(-1); i=i+1; } return(0); } Was würde mit einem unkonzentrierten Programmierer passieren, wenn er folgendes macht: v[i] = v[i+1]; Er bekommt eine Fehlermeldung des Compilers.

int istPositiv(const int v[], int anz){ int i=0; while(i<anz){ if(v[i]<0) return(-1); i=i+1; } return(0); } Welchen Parameter könnte man auch noch schreibschützen? while(anz>1) anz=anz+1; Was müsste man dazu tun? Diesen Input-Parameter const Ist dies sinnvoll? Da anz kein Pointer, kann sein Wert doch nach außen nicht geändert werden. Endlosschleife, deswegen sinnvoll

Aufgabe: Erzeugen Sie eine Funktion, die ein Integer-Feld der Länge 2 der Größe nach aufsteigend sortiert. 2 Lösungsvarianten machen

1. Lösung

void my1Sort2(const int vI[], int vO[]){ if(vI[0]<vI[1]){ vO[0]=vI[0]; vO[1]=vI[1]; } else{ vO[0]=vI[1]; vO[1]=vI[0]; } } Welche Art von Parameter ist das Feld vI und vO ? (i), (o), (i/o) vI : (i), also reiner Input-Parameter vO : (o), also reiner Output-Parameter

2. Lösung

void my2Sort2(int v[]){ int temp0, temp1; temp0=v[0]; temp1=v[1]; if(v[0]>v[1]){ v[0]=temp1; v[1]=temp0; } } Welche Art von Parameter ist das Feld v ? (i), (o), (i/o) v : (i/o), also Input- und Output-Parameter

void my2Sort2(int v[]){ int temp0, temp1; temp0=v[0]; temp1=v[1]; if(v[0]>v[1]){ v[0]=temp1; v[1]=temp0; } } Die Werte von v[0] und v[1] werden vertauscht. Was veranlassen die 2 Anweisungen der if Anweisug? Könnte man dies auch wie folgt realisieren?

void my2Sort2(int v[]){ int temp0, temp1; temp0=v[0]; temp1=v[1]; if(v[0]>v[1]){ v[0]=v[1]; v[1]=v[0]; } } Angenommen, vor diesen 2 Anweisungen wäre v[0] und v[1] wie folgt belegt: v[0] : 10 und v[1] : 20 Wie wäre dann v[0] und v[1] danach belegt? v[0] : 20 v[1] : 20

Welche Zusicherung muss an die Input-Parameter gemacht werden:

Sie müssen die Länge 2 haben.

Zeichenkette als Parameter beim Aufruf einer Funktion.

Frage: Wie wird in C eine Zeichenkette realisiert?

Als Folge von Zeichen (char), die durch Anführungszeichen getrennt werden, wie z.B: "Hallo Welt" oder...

als ein Feld (Array) vom Datentyp char.

Was macht folgende Funktion?

void ausgabe(char feld[]){ int i; for(i=0;feld[i]!='\0';i++){ printf("%c",feld[i]); } printf("\n"); } gibt alle Zellen des Feldes auf dem Bildschirm aus. Wie könnten mögliche Aufrufe dieser Funktion in main() aussehen?

int main(){ char name[5]="MESK"; ausgabe(name); // auch moeglich ausgabe("Hallo"); } Die Zeichenfolge "Hallo" kann "hart kodiert" werden, muß also nicht über eine Variable (wie z.B. name passieren).