Benutzer:PascalHänle/Grundvorstellungen zum Ableitungsbegriff/Die Ableitung als lokale Änderungsrate und Lazarus/Prozeduren, Funktionen und Bibliotheken: Unterschied zwischen den Seiten

Aus ZUM-Unterrichten
Markierung: 2017-Quelltext-Bearbeitung
 
main>Peterdauscher
Keine Bearbeitungszusammenfassung
 
Zeile 1: Zeile 1:
{{Lazarus-Buch}}


==Der Porsche 918 Spyder==
== Prozeduren ==
Die folgende Tabelle zeigt den Beschleunigungsvorgang des Rennautos Porsche 918 Spyder. Die Weg - Zeit - Kurve lässt sich in diesem Intervall annähernd durch die Funktion <math>s(t)=0,2t^2+4,5t^3</math> beschreiben.


[[Datei:Porsche Weg Zeit Kurve.png|mini|alternativtext=|450x450px]]
=== Einfache Prozeduren ===


:{| class="wikitable"
Wenn man Programme schreibt und immer mehr erweitert, so besteht die Gefahr, dass sie nicht nur immer größer sondern auch immer unübersichtlicher werden. Deshalb ist es sinnvoll, bestimmte, immer wiederkehrende Folgen von Befehlen mit einer bestimmten Bedeutung in einer Art selbst gebautem Befehl zusammenzufassen. Solche Befehle heißen auch '''Prozedur''' (engl.: '''procedure'''). Manche Leser werden den Sketch "Dinner for one" [https://de.wikipedia.org/wiki/Dinner_for_One] kennen, bei dem Butler James immer wieder fragt: "Same procedure as last year, Miss Sophie" und Miss Sophie jedes Mal antwortet "Same procedure as ''every'' year, James" . James und Miss Sophie meinen genau dasselbe wie wir: einen fest geregelten Ablauf von Dingen.
!'''Zeit (Sekunden)'''!!Strecke (Meter)
|-
|0||0
|-
|1||4,7
|-
|2||19,6
|-
|3||45,9
|-
|4||84,8
|-
|5||137,5
|-
|6||205,2
|-
|7
|289,1
|-
|8
|390,4
|-
|9
|510,3
|}


==Mittlere Änderungsrate==
==== Beispiel einer einfachen Prozedur ====
Überlegen Sie zunächst welcher physikalischen Größe die [[/mittleren Änderungsraten/]] in diesem Beispiel zuzuordnen ist und wie man diese berechnet. Notieren Sie Ihre Lösung in ihrem Heft.


:
Ein sehr sehr einfaches Beispiel für eine Prozedur könnte ein Hinweis sein, der angezeigt werden soll, begleitet von einem hörbaren Signal. Das Programm benötigt lediglich einen Button mit dem Namen <tt>Button1</tt>.
{{Box|Aufgabe 1|Bestimmen Sie mit welcher Durchschnittsgeschwindigkeit der Porsche in den folgenden Zeitintervallen gefahren ist.


a) zwischen Sekunde 1 und 2 <br /> b) zwischen Sekunde 2 und 3 <br /> c) zwischen Sekunde 3 und 4 <br />  
{{kasten_blau|<source  line highlight="30-34,38" lang="pascal">
Überprüfe deine Ergebnisse in folgendem Applet mit Hilfe des geometrischen Zusammenhangs der mittleren Änderungsrate und der Sekantensteigung.
unit hinweis_geben;


{{Lösung versteckt|[[/Lösungskontrolle/|zum Applet]]<ggb_applet id="ceu9yjy3" width="50%" height="450" border="8888"></ggb_applet>}}|Arbeitsmethode
{$mode objfpc}{$H+}
}}
interface
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;


<br />
type
  { TForm1 }


==Momentane Änderungsrate==
  TForm1 = class(TForm)
{{Box|Aufgabe 2|Bestimmen Sie nun näherungsweise wie schnell der Porsche nach 3 Sekunden gefahren ist. Wählen Sie hierzu ein beliebiges Zeitintervall in dem die dritte Sekunde enthalten ist und verkleinere dieses. Nutzen Sie hierzu die folgende Tabelle. <br /> a) Verkleinern Sie das Intervall mindestens 5 mal und halten Sie die Tabelle schriftlich fest. <br />
    Button1: TButton;
<ggb_applet id="fmzb7fjd" width="90%" height="400" border="888888">Weg - Zeit - Kurve Porsche </ggb_applet>
    procedure Button1Click(Sender: TObject);
b) Führe die Verkleinerung des Zeitintervalls nun erneut in diesem Applet durch.<br /> Beschreibe die Veränderung der Sekante und des Werts der Sekante bei dieser Verkleinerung und halte dies schriftlich fest.<br /> c) Was sind die Eigenschaften dieser neu entstandenen Geraden? <br />
  private
d) Als was lässt sich in diesem Kontext die Steigung dieser Geraden interpretieren?|Arbeitsmethode
    { private declarations }
}}{{Box|Tangente|Die Geraden, die durch den Punkt P(x0{{!}}f(x0)) verläuft und die gleiche Steigung wie der Graph von f an dieser Stelle hat, nennt man Tangente.|Merksatz
  public
}}
    { public declarations }
  end;


==Der Differentialquotient==
var
{{Box|Aufgabe 3|a) Schauen Sie sich die Aufgaben zur Intervallverkleinerungen aus Aufgabe 2 erneut an. Notieren Sie wie man die Verkleinerung des Intervalls Differenzenquotienten ausdrücken könnte. Das Ergebnis des neuen Quotienten soll die Steigung der Tangente sein. Hilfe einbauen!
  Form1: TForm1;
|Arbeitsmethode
 
}}
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure Hinweis;
begin
  Beep;
  ShowMessage('Sie haben den Knopf gedrückt');
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
Hinweis;
end;
 
end.
 
</source>}}
 
 
Man sieht, dass nach der Definition des eigenen Befehls (der Prozedur) "Hinweis" vollkommen genügt, diesen Befehl aufzurufen.
 
=== Prozeduren mit Wertparametern ===
 
Die oben gezeigte Prozedur tut immer genau das gleiche: Sie gibt das akustische Signal und den Hinweis "Sie haben den Knopf gedrückt". Häufig jedoch kommt es vor, das eine Prozedur zwar immer ähnliche, aber eben doch leicht verschiedene Dinge tun soll. So wäre es z.B. praktisch, wenn man den Hinweistext selbst immer wieder neu bestimmen könnte. Das funktioniert auch, wenn man der Prozedur einen so genannten Paramter mit auf den Weg gibt. Wir betrachten wiederum ein Beispiel:
 
 
{{kasten_blau|<source line start="30" highlight="1,11" lang="pascal">
procedure Hinweis(nachricht: string);
begin
  Beep;
  ShowMessage(nachricht);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var alter : integer;
 
begin
Hinweis('Eine frei gewählte Nachricht');
end;
</source>}}
 
Unterscheiden tun sich die gelb markierten Zeilen: Bei der Definition der Prozedur "Hinweis" in Zeile 30 ist hinter dem Namen der Prozedur noch in Klammern eine Variable angegeben, die in diesem Fall den Namen <tt>nachricht </tt> trägt und vom Typ <tt>string</tt> ist.
Wird nun in Zeile 40 der neue Befehl <tt>Hinweis</tt> aufgerufen, und zwar mit der Zeichenkette <tt>'Eine frei gewählte Nachricht'</tt> in Klammern, so wird die Variable <tt>nachricht</tt> mit diesem Wert belegt.
Wird nun innerhalb der Prozedur wiederum der Befehl ShowMessage mit <tt>nachricht</tt> als Parameter aufgerufen, so erscheint tatsächlich die Meldung mit dem richtigen Text auf dem Bildschirm.
 
'''Wichtige Anmerkung:'''
Die Variable <tt>nachricht</tt> ist eine neue, eigenständige Variable. Beim Aufruf der Prozedur Hinweis wird ihr ein entsprechender Zeichenkettenwert zugewiesen. Wird dieser im Lauf der Prozedur verändert, so wirkt sich das auf das aufrufende Programm nicht aus.
 
 
=== Prozeduren mit Referenzparametern ===
 
Nun kann es sein, dass es der Zweck einer Prozedur sein soll, den Wert einer Variable im aufrufenden Programm aber tatsächlich zu ändern. Als Beispiel betrachten wir den (sehr sehr einfachen) Fall, bei dem der Wert einer Integer-Variable verdoppelt werden soll. Das Programm benötigt den Button <tt>Button1</tt> und das Edit-Feld <tt>Edit1</tt>. Der Vorspann mit Variablen usw. ist hier einfach einmal weggelassen.
 
 
{{kasten_blau|<source line start="30" highlight="1,10" lang="pascal">
procedure verdopple (zahl : integer);
begin
zahl:=zahl*2;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var zahlenwert : integer;
begin
zahlenwert:=StrToInt(Edit1.Text);
verdopple(zahlenwert);
Edit1.Text:=IntToStr(zahlenwert);
end;
</source>}}
 
Beim Ausprobieren merkt man: Das Beispiel funktioniert offensichtlich nicht. Der Inhalt des Edit-Feldes bleibt beim Drücken des Knopfes genau gleich.
 
Wir müssen das Programm leicht abändern, damit es funktioniert. Wir fügen in Zeile 30 vor der Variable <tt>zahl</tt>  das Schlüsselwort <tt>var</tt> ein. Das ist eigentlich ein wenig missverständlich, denn es soll bedeuten:
<tt>zahl</tt> ist '''keine''' eigenständige Variable sondern nur noch eine Art Spitzname für die Variable im Funktionsaufruf (man sagt auch: '''Referenz auf die Variable'''), in diesem Fall <tt>zahlenwert</tt>. Mit
<tt>zahl:=zahl*2</tt> wird jetzt in Wirklichkeit die Variable <tt>zahlenwert</tt> verdoppelt.
 
{{kasten_blau|<source line start="30" highlight="1,10" lang="pascal">
procedure verdopple (var zahl : integer);
begin
zahl:=zahl*2;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var zahlenwert : integer;
begin
zahlenwert:=StrToInt(Edit1.Text);
verdopple(zahlenwert);
Edit1.Text:=IntToStr(zahlenwert);
end;
</source>}}
 
Durch diese kleine Änderung funktioniert jetzt das Programm tadellos.
 
 
== Funktionen ==
 
Im Grunde würden Prozeduren mit Wert- und Referenzparametern vollkommen ausreichern, um immer wiederkehrende Abläufe in selbstdefinierte Befehle zu verpacken (Informatiker sprechen gerne auch von "'''verkapseln'''").
 
So könnte man zum Beispiel eine Prozedur zum Berechnen des Quadrats von integer-Zahlen schreiben. Das Beispielprogramm benötigt die Komponenten <tt>Button1, Edit1, Edit2</tt>:
 
 
{{kasten_blau|<source line start="30" highlight="1,11" lang="pascal">
procedure quadrat(zahl : integer; var ergebnis: integer);
begin
ergebnis:=zahl*zahl;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var zahlenwert : integer;
    zahlenwertquadriert : integer;
begin
zahlenwert:=StrToInt(Edit1.Text);
quadrat(zahlenwert,zahlenwertquadriert);
Edit2.Text:=IntToStr(zahlenwertquadriert);
end;                           
</source>}}
 
Aber gerade im mathematischen Bereich ist das eher unüblich: außerdem muss man immer überlegen, welcher der beiden Parameter nun die eigentliche Zahl und welche das spätere Quadrat werden soll. Eleganter ist daher die folgende Schreibweise:
 
{{kasten_blau|<source line start="30" highlight="1,11" lang="pascal">
function quadrat(zahl : integer) : integer;
begin
quadrat:=zahl*zahl;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var zahlenwert : integer;
    zahlenwertquadriert : integer;
begin
zahlenwert:=StrToInt(Edit1.Text);
zahlenwertquadriert:=quadrat(zahlenwert);
Edit2.Text:=IntToStr(zahlenwertquadriert);
end;                           
</source>}}
 
 
== Bibliotheken ==
Das Ausgliedern von immer gleichen Routinen in Prozeduren und Funktionen als eigene Befehle macht auch größere Programme übersichtlicher. Allerdings hilft bei sehr großen Programmen (mit mehreren Tausenden Zeilen) das auch nicht mehr so sonderlich viel. Deshalb kann man in diesem Fall Teile der Prozeduren und Funktionen in eigene Dateien ausladen, so genannte Bibliotheken, die in der Sprache Pascal auch als <tt>Units</tt> bezeichnet werden. 
 
Ein weiterer Vorteil von Bibliotheken ist, dass mehrere andere Programme die darin definierten Befehle benutzten Befehle verwenden können, ohne dass man die entsprechenden Funktionen und Prozeduren in das eigene Programm hineinkopieren muss. Vielmehr genügt es, in der Zeile <tt>uses ...</tt> den Namen der benutzten Unit anzugeben.
Eine solche Bibliothek haben wir im Kapitel [[../Computer-Mathematik/]] bereits kennen gelernt: die <tt>Unit Math</tt>, in der viele praktische mathematische Befehle definiert sind.
 
Eine weitere Unit soll uns das Leben in den nächsten Kapiteln erleichtern: <tt>LazIOStuff</tt> Diese ist allerdings nicht Bestandteil der derzeitigen Lazarus-Programme, sondern kann kostenlos aus dem Internet heruntergeladen werden:
 
[http://sourceforge.net/projects/laziostuff/files/laziostuff.pas/download laziostuff.pas]
 
 
{{Lazarus-Buch}}

Version vom 13. Januar 2013, 20:25 Uhr


Prozeduren

Einfache Prozeduren

Wenn man Programme schreibt und immer mehr erweitert, so besteht die Gefahr, dass sie nicht nur immer größer sondern auch immer unübersichtlicher werden. Deshalb ist es sinnvoll, bestimmte, immer wiederkehrende Folgen von Befehlen mit einer bestimmten Bedeutung in einer Art selbst gebautem Befehl zusammenzufassen. Solche Befehle heißen auch Prozedur (engl.: procedure). Manche Leser werden den Sketch "Dinner for one" [1] kennen, bei dem Butler James immer wieder fragt: "Same procedure as last year, Miss Sophie" und Miss Sophie jedes Mal antwortet "Same procedure as every year, James" . James und Miss Sophie meinen genau dasselbe wie wir: einen fest geregelten Ablauf von Dingen.

Beispiel einer einfachen Prozedur

Ein sehr sehr einfaches Beispiel für eine Prozedur könnte ein Hinweis sein, der angezeigt werden soll, begleitet von einem hörbaren Signal. Das Programm benötigt lediglich einen Button mit dem Namen Button1.

Vorlage:Kasten blau


Man sieht, dass nach der Definition des eigenen Befehls (der Prozedur) "Hinweis" vollkommen genügt, diesen Befehl aufzurufen.

Prozeduren mit Wertparametern

Die oben gezeigte Prozedur tut immer genau das gleiche: Sie gibt das akustische Signal und den Hinweis "Sie haben den Knopf gedrückt". Häufig jedoch kommt es vor, das eine Prozedur zwar immer ähnliche, aber eben doch leicht verschiedene Dinge tun soll. So wäre es z.B. praktisch, wenn man den Hinweistext selbst immer wieder neu bestimmen könnte. Das funktioniert auch, wenn man der Prozedur einen so genannten Paramter mit auf den Weg gibt. Wir betrachten wiederum ein Beispiel:


Vorlage:Kasten blau

Unterscheiden tun sich die gelb markierten Zeilen: Bei der Definition der Prozedur "Hinweis" in Zeile 30 ist hinter dem Namen der Prozedur noch in Klammern eine Variable angegeben, die in diesem Fall den Namen nachricht trägt und vom Typ string ist. Wird nun in Zeile 40 der neue Befehl Hinweis aufgerufen, und zwar mit der Zeichenkette 'Eine frei gewählte Nachricht' in Klammern, so wird die Variable nachricht mit diesem Wert belegt. Wird nun innerhalb der Prozedur wiederum der Befehl ShowMessage mit nachricht als Parameter aufgerufen, so erscheint tatsächlich die Meldung mit dem richtigen Text auf dem Bildschirm.

Wichtige Anmerkung: Die Variable nachricht ist eine neue, eigenständige Variable. Beim Aufruf der Prozedur Hinweis wird ihr ein entsprechender Zeichenkettenwert zugewiesen. Wird dieser im Lauf der Prozedur verändert, so wirkt sich das auf das aufrufende Programm nicht aus.


Prozeduren mit Referenzparametern

Nun kann es sein, dass es der Zweck einer Prozedur sein soll, den Wert einer Variable im aufrufenden Programm aber tatsächlich zu ändern. Als Beispiel betrachten wir den (sehr sehr einfachen) Fall, bei dem der Wert einer Integer-Variable verdoppelt werden soll. Das Programm benötigt den Button Button1 und das Edit-Feld Edit1. Der Vorspann mit Variablen usw. ist hier einfach einmal weggelassen.


Vorlage:Kasten blau

Beim Ausprobieren merkt man: Das Beispiel funktioniert offensichtlich nicht. Der Inhalt des Edit-Feldes bleibt beim Drücken des Knopfes genau gleich.

Wir müssen das Programm leicht abändern, damit es funktioniert. Wir fügen in Zeile 30 vor der Variable zahl das Schlüsselwort var ein. Das ist eigentlich ein wenig missverständlich, denn es soll bedeuten: zahl ist keine eigenständige Variable sondern nur noch eine Art Spitzname für die Variable im Funktionsaufruf (man sagt auch: Referenz auf die Variable), in diesem Fall zahlenwert. Mit zahl:=zahl*2 wird jetzt in Wirklichkeit die Variable zahlenwert verdoppelt.

Vorlage:Kasten blau

Durch diese kleine Änderung funktioniert jetzt das Programm tadellos.


Funktionen

Im Grunde würden Prozeduren mit Wert- und Referenzparametern vollkommen ausreichern, um immer wiederkehrende Abläufe in selbstdefinierte Befehle zu verpacken (Informatiker sprechen gerne auch von "verkapseln").

So könnte man zum Beispiel eine Prozedur zum Berechnen des Quadrats von integer-Zahlen schreiben. Das Beispielprogramm benötigt die Komponenten Button1, Edit1, Edit2:


Vorlage:Kasten blau

Aber gerade im mathematischen Bereich ist das eher unüblich: außerdem muss man immer überlegen, welcher der beiden Parameter nun die eigentliche Zahl und welche das spätere Quadrat werden soll. Eleganter ist daher die folgende Schreibweise:

Vorlage:Kasten blau


Bibliotheken

Das Ausgliedern von immer gleichen Routinen in Prozeduren und Funktionen als eigene Befehle macht auch größere Programme übersichtlicher. Allerdings hilft bei sehr großen Programmen (mit mehreren Tausenden Zeilen) das auch nicht mehr so sonderlich viel. Deshalb kann man in diesem Fall Teile der Prozeduren und Funktionen in eigene Dateien ausladen, so genannte Bibliotheken, die in der Sprache Pascal auch als Units bezeichnet werden.

Ein weiterer Vorteil von Bibliotheken ist, dass mehrere andere Programme die darin definierten Befehle benutzten Befehle verwenden können, ohne dass man die entsprechenden Funktionen und Prozeduren in das eigene Programm hineinkopieren muss. Vielmehr genügt es, in der Zeile uses ... den Namen der benutzten Unit anzugeben. Eine solche Bibliothek haben wir im Kapitel Computer-Mathematik bereits kennen gelernt: die Unit Math, in der viele praktische mathematische Befehle definiert sind.

Eine weitere Unit soll uns das Leben in den nächsten Kapiteln erleichtern: LazIOStuff Diese ist allerdings nicht Bestandteil der derzeitigen Lazarus-Programme, sondern kann kostenlos aus dem Internet heruntergeladen werden:

laziostuff.pas