Autor |
Beitrag |
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Sa 23.02.13 22:06
Guten Tag,
ich denke die Frage ist für erfahrene Programmierer schnell zu beantworten...
folgendes Beipsiel
Delphi-Quelltext 1: 2: 3: 4:
| Procedure Beispielfunktion(Liste: Array of TBeispiel; EineVariable: Integer); begin end; |
Die eigentliche Frage ist: wie kann ich die Procedure so "vorbereiten", dass "EineVariable" > 0 sein muss ?...
sodass, wenn ich
Delphi-Quelltext 1:
| Beispielfunktion(EineListehalt, -5); |
eingebe, eine Fehlermeldung kommt (nicht zur Laufzeit, sondern beim compilierversuch)
2te Frage: Wie kann ich ein beliebig großes Array von einem vorbestimmten Typ als parameter verlangen? (siehe "Liste")
Also, wenn TBeispiel = Integer wäre, dass ich dann die procedure sowohl mit
Delphi-Quelltext 1: 2: 3: 4:
| var EineListehalt: Array[1..100] of Integer; begin Beispielfunktion(EineListehalt, 10); end; |
als auch mit
Delphi-Quelltext 1: 2: 3: 4:
| var EineListehalt: Array[1..15] of Integer; begin Beispielfunktion(EineListehalt, 10); end; |
aufrufen kann/könnte..
bei
Delphi-Quelltext 1: 2: 3: 4:
| var EineListehalt: Array[1..100] of String; begin Beispielfunktion(EineListehalt, 10); end; |
natürlich ein Felher (beim compilieren) kommt...
Ich hoffe es ist verständlich, was ich frage 
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Sa 23.02.13 22:12
Zu 1: ganz so geht es leider nicht, aber nimm doch statt Integer Cardinal, dann kann man zumindest keine Zahlen < 0 übergeben.
Zu 2: das nennt sich Open Array (sofern ich die Frage richtig verstanden habe).
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure SomeProc(IntArr: array of integer);
...
SomeProc([1, 2, 3, 4]);
var Dings: array[1..10] of integer; begin SomeProc(Dings); |
Für diesen Beitrag haben gedankt: IhopeonlyReader
|
|
IhopeonlyReader 
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Sa 23.02.13 22:19
ich kenn das als "dynamisches Array".. oder bring ich da was durcheinander?
könnte ich also die "maxanzahl" des arrays mit length bestimmen etc?
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Sa 23.02.13 22:32
Ein dynamisches Array ist etwas anderes als ein Open Array. Lesestoff dazu (Englisch).
[edit] Nachtrag/Korrektur: Du kannst Dir einen eigenen Zahlentyp definieren, dann kommst Du Deinem Ziel aus Frage 1 zumindest nahe:
Delphi-Quelltext 1: 2:
| type TMyZahl = 1..MAXINT; |
Allerdings bekommt der Compiler falsche Werte nur dann mit, wenn Du Konstanten übergibst wie in Deinem Beispiel.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure Bla(Zahl: TMyZahl);
Bla(0); Blubb := 0; Bla(Blubb); | [/edit]
Für diesen Beitrag haben gedankt: IhopeonlyReader
|
|
IhopeonlyReader 
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Sa 23.02.13 22:41
genau das ist mir auch eingefallen
und ja ich verwende dazu immer konstanten, oder die variable ist vom Typ TMyZahl^^
Und:
könntest du mir die "grundlagen" zu dem openarray liefern?
z.B.
Maximale Größe / Range ( bei var Str: Array[3..16] of integer; wäre die maximale größe 16, die range 13
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Sa 23.02.13 22:55
das mit den Offenen Arrays ist ganz einfach:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure Tuewas(a : Array of double); var Summe : double; i : integer; begin Summe := 0.0; for i := 0 to High(a) do begin Summe := Summe + a[i]; end; end; |
Das mit der EinenVariablen ist - wie schon erwähnt - vom Compiler nur dann zu erkennen, wenn der übergebene Wert eine Konstante ist. Allerdings funktioniert es auch, wenn Du die Variable als var-Paramter übergibst. Denn dann muss der Typ übereinstimmen.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure Tuewas(var w : Word); begin w := w + 123; end;
procedure TForm1.btn1Click(Sender: TObject); var i : Integer; j : Word; begin i := 15; Tuewas(i); j := 15; Tuewas(j); end; |
Allerdings wird dann die Variable EineVariable, die Du übergibst, auch geändert. Das heißt, die übergebene Variable hat dann nach Verlassen der Prozedur u.U. einen anderen Wert. Und um die Eingrenzung auf Werte>0 zu gewährleisten musst Du mindestens Word oder andere Vorzeichenlose Integer-Typen nehmen. Sonst funktioniert das nicht. Und dann darf der Typ der übergebenden Variablen kein anderer sein.
Vielleicht solltest Du besser eine Fehlerbehandlungsroutine in der Prozedur einbinden.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Sa 23.02.13 23:12
Etwas ausführlicher: bei einem Open Array kann man den zu übergebenden Parameter "On the fly" schreiben, bei einem dynamischen nicht.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| type TIntArr = array of integer; function SumInt(Arr: TIntArr): integer; var i: integer; begin Result := 0; for i := Low(Arr) to High(Arr) do inc(Result, Arr[i]); end;
procedure TForm1.btnBlubb(Sender: TObject); begin ShowMessage(IntToStr(SumInt([1, 2, 3, 4]))); end; |
Definiert man den Parameter aber als offenes Array, dann klappt das auch.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| function SumInt(Arr: array of integer): integer; var i: integer; begin Result := 0; for i := Low(Arr) to High(Arr) do inc(Result, Arr[i]); end;
procedure TForm1.btnBlubb(Sender: TObject); begin ShowMessage(IntToStr(SumInt([1, 2, 3, 4]))); end; |
Weitere Beispiele finden sich auch auf der oben verlinkten Seite, wenn man dem dort enthaltenen Link auf "Array" folgt: http://delphibasics.co.uk/RTL.asp?Name=Array
Für diesen Beitrag haben gedankt: IhopeonlyReader
|
|
IhopeonlyReader 
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Sa 23.02.13 23:48
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 24.02.13 00:02
Ich verstehe nicht ganz, worauf Du hinauswillst. Low(Array) gibt Dir den Index des ersten Array-Elements zurück, High(Array) den des letzten, Length(Array) die Länge, unabhängig von Low() und High().
Delphi-Quelltext 1: 2: 3:
| var Testvariable: Array[11..111] of Integer; |
|
|
IhopeonlyReader 
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 24.02.13 00:17
Length(Array) = High(Array) - Low(Array) +1; !
ich frage mich wozu es length(array) gibt, wenn es immer konstant im bezug auf high und low ist.
Worauf ich auf folgendes hinaus:
Dyn Array = OpenArray + SetLength-Function;
also kann ich mehere verschiedenlage arrays zu einem langen hinzufügen
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TGesamtArray = Array of Integer;
Procedure MoreToOne(EinArray: Array of Integer, GesamtArray: TGesamtArray); var C: Integer; begin setlength(GesamtArray, length(GesamtArray) + length(EinArray)); For C := 1 to length(EinArray) do GesamtArray[C + length(GesamtArray) - length(EinArray)] := EinArray[Low(EinArray)+C]; end; |
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 24.02.13 00:25
Prinzipiell sollte das möglich sein, ich persönlich würde es nur etwas anders schreiben:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure AddToArray(Source: array of integer; var Dest: TGesamtArray); var i, OldHigh: integer; begin OldHigh := High(Dest); SetLength(Dest, Length(Dest) + Length(Source)); for i := Low(Source) to High(Source) do Dest[i + Succ(OldHigh)] := Source[i]; end; |
Ungetestet.
|
|
IhopeonlyReader 
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 24.02.13 00:38
WasWeißDennIch hat folgendes geschrieben : |
Delphi-Quelltext 1:
| Dest[i + Succ(OldHigh)] := Source[i]; |
|
mhh..
1. kenn ich succ nicht  aber so wie www.delphibasics.co.uk/RTL.asp?Name=Succ das erklärt, macht succ nichts anders als den wert um 1 zu erhöhen
(wie OldHigh := OldHigh +1)
2. falls dein Array nicht bei 1 beginnt, klappt das mit Dest[i + Succ(OldHigh)] nicht !
Denn dann wäre der Index über dem Max.
logischer wäre:
Dest[i - low(Source) + 1 + OldHigh)];
oder wie du das machen würdest;
Dest[i - low(Source) + Succ(OldHigh)];
Wobei ich bei der 2 Vairante unsicher bin, ob oldhigh PRO durchführung um 1 größer wird oder nur für die prozedure...
Wenn es pro durchführung ist, also
Delphi-Quelltext 1: 2: 3: 4:
| Procedure Succ(Wert: Integer); begin Wert := Wert +1; end; |
dann funktioniert die 2 variante nicht... ist es jedoch nur für den zweck um 1 vergrößert, also
Delphi-Quelltext 1: 2: 3: 4:
| Function Succ(Wert: Integer): Integer; begin Result := Wert +1; end; |
würde es funktionieren.. aber ich glaube es ist so wie die prozedure aufgebaut
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 24.02.13 00:44
Open Arrays und dynamische Arrays beginnen immer mit Index 0, das passt schon. Und Succ() ist eine Funktion, die den übergebenen Wert nicht verändert (sonst könnte man ja auch keine Konstanten übergeben), im Gegensatz zu z.B. Inc().
|
|
IhopeonlyReader 
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 24.02.13 00:51
also ist
Zitat: |
Delphi-Quelltext 1:
| for i := Low(Source) to High(Source) do |
|
ist also nichts anders als
Delphi-Quelltext 1:
| for i := 0 to length(Source) do |
richtig?
P.S: vielen Dank für deine Mühe mir alles genau zu erklären 
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
IhopeonlyReader 
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 24.02.13 00:59
WasWeißDennIch hat folgendes geschrieben : |
Bla(0); //Compilerfehler
Blubb := 0;
Bla(Blubb); //kein Compilerfehler[/delphi][/edit] |
fast
das untere ergibt auch ein CompilerFehler, denn Blubb muss ja integer, extended oder so sein und das ist ungleich mit TMyZahl...
also müsste Blubb vom Typ TMyZahl sein und der Fehler läg dann schon bei
Blubb := 0;
nur so ^^
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 24.02.13 01:08
|
|
IhopeonlyReader 
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: So 24.02.13 01:15
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 24.02.13 01:27
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure DoWork(var Zahl: TZahl); begin ShowMessage(IntToStr(Zahl)); end;
procedure TForm1.Button1Click(Sender: TObject); var Blubb: integer; begin Blubb := -42; DoWork(TZahl(Blubb)); end; |
Ällabätsch  . Wie man so etwas allerdings verhindern soll, weiß ich selbst nicht. Mit dem harten Typecast sagt man ja dem Compiler so "Sledge Hammer"-mäßig
Zitat: | Vertrauen Sie mir, ich weiß, was ich tue. |
Knallt es dann, kann man nur sagen: selber Schuld! Aber dieses Problem lässt sich auf jeden beliebigen Datentyp übertragen.
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Do 28.02.13 05:53
WasWeißDennIch hat folgendes geschrieben : | Prinzipiell sollte das möglich sein, ich persönlich würde es nur etwas anders schreiben:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure AddToArray(Source: array of integer; var Dest: TGesamtArray); var i, OldHigh: integer; begin OldHigh := High(Dest); SetLength(Dest, Length(Dest) + Length(Source)); for i := Low(Source) to High(Source) do Dest[i + Succ(OldHigh)] := Source[i]; end; |
Ungetestet. |
Da ja Source = Array of integer für Low(Source) immer 0 ausgibt, sollte es funktionieren, aber warum nicht folgende Variante:
(*1)
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var i, AktPos, OldHigh: integer; begin OldHigh := High(Dest); SetLength(Dest, Length(Dest) + Length(Source)); AktPos:= OldHigh+1; for i := Low(Source) to High(Source) do begin Dest[AktPos] := Source[i]; Inc(AktPos); end; end; |
(*2)
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var i, AktPos: integer; begin AktPos := High(Dest)+1; SetLength(Dest, Length(Dest) + Length(Source)); for i := Low(Source) to High(Source) do begin Dest[AktPos] := Source[i]; Inc(AktPos); end; end; |
Bemerkung zur Editierung: Variablen im Namen geändert!!!
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
Zuletzt bearbeitet von Tranx am Do 28.02.13 12:05, insgesamt 2-mal bearbeitet
Für diesen Beitrag haben gedankt: WasWeißDennIch
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Do 28.02.13 09:28
Einverstanden, aber dann sollte man vielleicht noch etwas sprechendere Bezeichner wählen.
|
|