Autor Beitrag
Torsten
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 160



BeitragVerfasst: Di 01.10.02 19:48 
Moinsen Leute!

Mal eine elementare Frage zu Pascal.
Ich habe den ganzen Sommer über keinen Rechner gesehen, also viel vergessen. Besonders, was reines Pascal angeht.

Also, ich will in einem kleinen Programm das Skalar-Produkt im n-dimensionalen Raum berechnen.
Die eigentliche Berechnung ist mir eigentlich klar, nur die Arrays gefallen mir nicht so recht.
Ich kann euch ja mal meinen Entwurf zeigen.

Zu beachten ist noch, dass das Skalarprodukt später mittels "s:=Skal_Prod(n, V, W)" aufgerufen werden soll.
n ist also die Dimension (2,3,4,...) und V bzw. W die Vektoren.

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
program skalar;


function Skal_Prod(n:Integer; x:array of Real; y:array of Real):Real;
 var
        i: Integer;

 begin
        i:=1;
        Skal_Prod:=0.0;

        repeat
         Skal_Prod:=Skal_Prod + (x[i]*y[i]);
         i:=i+1;
        until i > n;
 end;

begin
 // ab hier nun das Hauptprogramm
end.


Nun noch eine Fragen.
In Zeile "Skal_Prod:=Skal_Prod + (x[i]*y[i]);" bekomme ich einen Compiler-Fehler!
Wieso? Geht das so nicht?


Ach ja, hat jemand rein zufällig ein gutes Forum für reines Pascal in Verbindung mit Mathe?

Fragende Grüße

Torsten
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 01.10.02 19:54 
Hi!

Pascal ist bei mir jetzt schon 3 Jahre her, aber mit einer Function darfst Du in Pascal glaube ich keine solche Zuweisung machen. Definiere Dir doch eine lokale Variable vom Typ Real, mit der Du die gleichen Berechnungen machst, die Du aber erst ganz am Ende Skal_Prod zuweist.

Bei Delphi fangen Arrays, wie Du sie verwendest, mit dem Index 0 an, ist das bei Pascal anders?

MfG,
Peter

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Torsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 160



BeitragVerfasst: Di 01.10.02 19:59 
Hallo!

OK, das mit der Variablen habe ich mir auch überlegt. Ich war jedoch der Meinung, dass es auch so geht. aber man lernt ja immer dazu.

Tja, Arrays in Pascal. Ich denke mal auch, dass sie bei 0 beginnen. Also ähnlich C oder Delphi. Sicher bin ich mir jedoch auch nicht, daher die Frage.

Kann man den ganzen Kram nicht ohnehin irgendwie besser machen?

Grüße

Torsten
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 01.10.02 20:07 
Hi!

Ich glaube nicht, dass man das ganze noch verbessern kann. Die Laufzeit ist glaube ich mit einer linearen Abhängigkeit von n ganz in Ordnung. Man kann natürlich jetzt versuchen, herauszufinden, ob Inc(i) schneller ausgeführt wird als i:=i+1; aber ganz ehrlich halte ich das für maßlos übertrieben.

MfG,
Peter

P.S.: Definiere doch alle Winkel als 90°, dann ist das Skalarprodukt ganz einfach Null!

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Klabautermann
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Veteran
Beiträge: 6366
Erhaltene Danke: 60

Windows 7, Ubuntu
Delphi 7 Prof.
BeitragVerfasst: Di 01.10.02 20:33 
Hallo,
Torsten hat folgendes geschrieben:

ausblenden Quelltext
1:
         Skal_Prod:=Skal_Prod + (x[i]*y[i]);					



Skal_Prod ist deine funktion, also ist der erste Teil der Zeile (Skal_Prod:=) Ok. Danch rufst du aber wieder Skal_Prod auf. Das währe generell auch kein Problem, nur müsstest du dann:
1. auch die benötigten Parameter übergeben.
2. Eine abbruchbedingung für die benötigte Rekursion schreiben.

Ich glaube aber nicht, das du überhaupt eine Rekursion machen willst.
Wenn du das ganze in Delphi Implementierst, kannst du Result verwenden (ich weis nicht mit welcher Verion das eingeführt wurde, vieleicht gab es das schon in neueren Turbo Pascal Versionen).
Dann sähe deine Funktion so aus:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function Skal_Prod(n:Integer; x:array of Real; y:array of Real):Real;
var
    i: Integer;
begin
    i:=1;
    Result:=0.0;
    repeat
     Result:=Result + (x[i]*y[i]);
     i:=i+1;
    until i > n;
end;


Ansonsten musst du tatsächlich zu einer Hilfsvariable greifen.

Mit freundlichen Grüßen
Klabautermann
Torsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 160



BeitragVerfasst: Di 01.10.02 21:09 
Moinsen!

Besten Dank für die Antworten.

Ja, result kenne ich von Delphi auch. Aber eben nicht unter Pascal. Und da bin ich schon seit bestimmt 10 Jahren raus (habe auch nicht viel mit gearbeitet).

Habe es aber eben getestet.
Ich arbeite mit GnuPascal unter Linux.
result scheint auch hier zu funktionieren.
Um es aber auch für andere Compiler zu schreiben, werde ich eine globale Variable verwenden.

Grüße

Torsten
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 01.10.02 21:35 
Eine globale Variable?

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Torsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 160



BeitragVerfasst: Di 01.10.02 21:43 
Sorry, falsch ausgedrückt.
Gilt natürlich nur für die Funktion.

Ich habe aber wieder ein anderes Problem.
Und zwar mit einem dynamischen Array.

So, mal eben das Programm:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
program skalar;
var
        i: Integer;
        n: Integer;
        v,w: array of Real;


{die eigentliche Funktion}
function Skal_Prod(n:Integer; x:array of Real; y:array of Real):Real;
 var
        i: Integer;
        result: Real;

 begin
        i:=1;
        result:=0.0;

        repeat
         result:=result + (x[i]*y[i]);
         i:=i+1;
        until i > n;
        return result;
 end;

{ eigentliches Hauptprogramm }
begin
 writeln('Das Skalarprodukt:');
// s:=Skal_Prod(......)
end.


Der Compiler meldet in der 5. Zeile bei
"v,w: array of Real;"
einen Fehler (parse error befor 'of')

Hö?
Wieso?
Dynamische Arrays gibt es doch bei Pascal.

Grüße

Torsten
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 01.10.02 22:14 
Hi!

Ich habe jetzt nochmal mein altes TP7 herausgekramt und bei dem Code, den Du verwendest, meckert er. Anscheinend kannst Du Arrays ohne Größenangabe nur als Parameter übergeben. Aber als ich TP programmiert habe, war ich noch nicht so weit, dass ich überhaupt auf die Idee von dynamischen Arrasy gekommen wäre; also kann es sein, dass es da irgendeinen Code gibt, wie man sie doch verwenden kann.

MfG,
Peter

P.S.: Die Fehlermeldung bei mir: "[" oder "(." erwartet

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Torsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 160



BeitragVerfasst: Di 01.10.02 22:20 
Moinsen!

Verdammte Axt.
Anscheinend gibt es doch keine dynamischen Arrays.
Eben doch nur als Parametrübergabe.

Naja, dann muss ich mir was einfallen lassen.

Dumm ist nur, dass ich die dort gebrauchen könnte.
Denn man weiss ja vorher nicht, in welcher Dimension das das Skalarprodukt gebildet werden soll.

Grüße

Torsten
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 01.10.02 22:34 
Hi!

Könntest Du das ganze nicht als Records in temporären Dateien speichern? Die kannst Du beliebig groß machen. Ist zwar ein Algorithmus mit der Brechstange aber es könnte funktionieren!

MfG,
Peter

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
CenBells
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1547

Win 7
Delphi XE5 Pro
BeitragVerfasst: Di 01.10.02 22:39 
Zitat:
Ich glaube nicht, dass man das ganze noch verbessern kann. Die Laufzeit ist glaube ich mit einer linearen Abhängigkeit von n ganz in Ordnung. Man kann natürlich jetzt versuchen, herauszufinden, ob Inc(i) schneller ausgeführt wird als i:=i+1; aber ganz ehrlich halte ich das für maßlos übertrieben.


Inc(i) wird schneller ausgeführt, als i := i+1;

Gruß
Ken
Torsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 160



BeitragVerfasst: Di 01.10.02 22:40 
Hui, das wäre mir dann doch zu viel.

Es war eigentlich nur ein Test.
Ich habe nämlich gerade in einem alten Pascal-Buch gestöbert.
Dort stand die Aufgabe, dass man eine Funktion entwickeln soll, die das Skalarprodukt errechnet.
Diese Funktion sollte dann mit Wertübergabe aufgerufen werden. Aber das drumherum war weniger interessant.
Ich wollte es dennoch gerne probieren (ohne Erfolg).

Grüße

Torsten
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 01.10.02 22:52 
Ireniceus hat folgendes geschrieben:

Inc(i) wird schneller ausgeführt, als i := i+1;


Hatte ich schon vermutet, ansonsten würde es kaum Sinn machen, eine solche Funktion zu implementieren.

MfG,
Peter

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Torsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 160



BeitragVerfasst: Di 01.10.02 23:00 
Moinsen!

Nochmal zum dynamischen Array.
In C wüsste ich, wie zu implementieren (malloc).

Auch in Delphi.
Nur eben nicht in Pascal.

Aber: Man kann das auch als verkette Liste ausführen.
Doch ich will mal nicht übertreiben.

Außer jemand hat einen einfachen, genialen Vorschlag. ;)

Grüße

Torsten
Klabautermann
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Veteran
Beiträge: 6366
Erhaltene Danke: 60

Windows 7, Ubuntu
Delphi 7 Prof.
BeitragVerfasst: Di 01.10.02 23:11 
Hallo!

Was ist an der Verketteten liste so schlim?
Torsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 160



BeitragVerfasst: Di 01.10.02 23:46 
Moinsen!

Och naja, irgendwie sträube ich mich immer etwas dagegen.

Hast Du etwa eine Lösung für meine Aufgabe?

Grüße

Torsten
Klabautermann
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Veteran
Beiträge: 6366
Erhaltene Danke: 60

Windows 7, Ubuntu
Delphi 7 Prof.
BeitragVerfasst: Mi 02.10.02 01:00 
Hallo,

da verlangst du was zu dieser späten Stunde. Aber gut, dann werde ich mal schnell was hintippen.
Aber eins vorweg: Aufgrund der vortgeschrittenden Zeit habe ich das nicht getestet oder nochmal genauer überprüft. Wenn es ein Problem gibt können wir Morgen nochmal drüber reden:

Also hier die Datentypen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
TYPE
    pRealList = ^tRealList;
    tRealList = PACKED RECORD
      Value : Real;
      Next : pRealList;
    END// tRealList


Die Variablendeklaration:
ausblenden Delphi-Quelltext
1:
2:
VAR
    v, w : pRealList;


Vergiss die Initialisierung nicht:
ausblenden Delphi-Quelltext
1:
2:
  v := NIL;
  w := NIL;


Und das Werkzeug:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
  procedure Appent2RealList(Value : Real; aList : pRealList);
    VAR
      Runner, NewEle : pRealList;
  BEGIN
    NEW(NewEle);
    NewEle^.Value := Value;
    NewEle.Next := NIL;
    Runner := aList;
    IF (Runner = NILTHEN // Sonderfall Liste ist leer
      aList := NewEle
    ELSE BEGIN // Eintrag anhängen
      WHILE (Runner^.Next <> NILDO
        Runner := Runner^.Next;
      Runner^.Next := NewEle;
    END// Eintrag anhängen
  END// Appent To RealList

  function RealListLength(aList : pRealList) : LongInt;
    VAR
      Runner : pRealList;
  BEGIN
    Result := 0;
    Runner := aList;
    WHILE (Runner <> NILDO BEGIN
      INC(Result);
      Runner := Runner^.Next;
    END;
  END// RealListLength

  function GetRealValue(aIndex : LongInt; aList : pRealList) : Real;
    VAR
      Runner : pRealList;
      i : LongInt;
  BEGIN
    Result := 0;
    IF (aIndex < RealListLength(aList)) THEN BEGIN // Legitimer Index
      Runner := aList;
      FOR i := 1 TO aIndex DO
        Runner := Runner^.Next;
      Result := Runner^.Value;
    END// LEgitimer Index
  END// Get Real Value

  procedure RemoveRealValue(aIndex : LongInt; aList : pRealList);
    VAR
      Runner, tmp : pRealList;
      i : LongInt;
  BEGIN
    IF (aIndex < RealListLength(aList)) THEN BEGIN // Legitimer Index
      Runner := aList;
      IF (aIndex = 1THEN BEGIN // Sonderfall das erste Element löschen
        tmp := Runner;
        aList := aList^.Next;
      END // Sonderfall das erste Element löschen
      ELSE BEGIN // anderes Element löschen
        FOR i := 1 TO aIndex - 1 DO
          Runner := Runner^.Next;
        tmp := Runner^.Next;
        Runner^.Next := Runner^.Next^.Next;
      END// Belibiges Element außer das erste löschen
      Dispose(tmp);
    END// Legitimer Index
  END// Remove Value

  procedure ClearRealList(aList : pRealList);
    VAR
      tmp : pRealList;
  BEGIN
    WHILE (aList <> NILDO BEGIN
      tmp := aList;
      aList := aList.Next;
      Dispose(tmp);
    END// Mit allen Einträgen
  END// ClearRealList


Und jetzt mach' was draus ;).

Gruß
Klabautermann


Zuletzt bearbeitet von Klabautermann am Di 17.06.03 10:38, insgesamt 1-mal bearbeitet
Torsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 160



BeitragVerfasst: Mi 02.10.02 09:12 
Moinsen!

Na hossa, das schaut ja wirklich gut aus.
Dennoch mag ich keine Listen, geschweige denn verkette Listen.
Aber bei Deinem Code sehe ich gut durch. Ist auch alles wunderbar enthalten (insert, remove, Länge,..)

Eigentlich wollte ich ja nicht so weit mit meinem Problem gehen, doch eventuell findet sich etwas Zeit.

Besten Dank dafür.

Grüße

Torsten
Klabautermann
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Veteran
Beiträge: 6366
Erhaltene Danke: 60

Windows 7, Ubuntu
Delphi 7 Prof.
BeitragVerfasst: Mi 02.10.02 16:00 
Hallo,
Torsten hat folgendes geschrieben:
Dennoch mag ich keine Listen, geschweige denn verkette Listen.

das ist schade, sie sind sehr Praktisch und im Klassischen Pascal der Standard-Weg für Dynamische Speicherverwaltung. Mann muss sich nur einmal richtig damit auseinander setzen, dann verlieren sie ihren Schrecken. :mahn:

Torsten hat folgendes geschrieben:
Aber bei Deinem Code sehe ich gut durch. Ist auch alles wunderbar enthalten (insert, remove, Länge,..)

Ja, wenn man sich am Anfang ein wenig Arbeit macht, kann man später sehr konfortabel Arbeiten und hat auch keine sorgen mehr mit den Verketteten listen ;).

Torsten hat folgendes geschrieben:
Eigentlich wollte ich ja nicht so weit mit meinem Problem gehen, doch eventuell findet sich etwas Zeit.

Ich zwinge dich ja nicht. Wie gesagt, wenn es dir hilft, dann viel Spass damit. Wenn nicht, vieleicht lernt ein mitleser was draus :think:.

Torsten hat folgendes geschrieben:
Besten Dank dafür.

Bitteschön, ich hatte Spaß dabei, denn heutzutage kommt man ja nicht mehr so oft dazu (denn Dynamische Arrays oder tList finde ich auch schnuckelig und verwende sie daher).

Gruß
Klabautermann