Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - mindestgröße eines Integer-Parameters
IhopeonlyReader - Sa 23.02.13 22:06
Titel: mindestgröße eines Integer-Parameters
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 :D
WasWeißDennIch - 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); |
IhopeonlyReader - 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?
WasWeißDennIch - Sa 23.02.13 22:32
Ein dynamisches Array ist etwas anderes als ein Open Array.
Lesestoff dazu [
http://delphibasics.co.uk/Article.asp?Name=Arrays] (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]
IhopeonlyReader - Sa 23.02.13 22:41
genau das ist mir auch eingefallen :D
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
Tranx - 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.
WasWeißDennIch - 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 [
http://delphibasics.co.uk/RTL.asp?Name=Array]
IhopeonlyReader - Sa 23.02.13 23:48
vielen Dank :)
also bei
Delphi-Quelltext
1: 2: 3: 4: 5:
| var Testvariable: Array[11..111] of Integer; begin SumInt(Testvariable); end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function SumInt(Arr: array of integer): integer; var DynArr: Array of Integer; C: Integer; begin SetLength(DynArr, High(Arr)-Low(Arr));
Result := 0; For C:=0 to High(DynArr) do Result := Result + DynArr[C]; end; |
richtig? und sind High und low auch verwendbar, wenn man in einer procedure die eigentliche Variable (statisches Array) hat?
also
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| var Testvariable: Array[11..111] of Integer; begin oder muss man das ganze abstrakt sehen? end; |
WasWeißDennIch - 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 - 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; |
WasWeißDennIch - 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 - 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 :D aber so wie
http://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
WasWeißDennIch - 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 - 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 :)
IhopeonlyReader - So 24.02.13 00:59
WasWeißDennIch hat folgendes geschrieben : |
Bla(0); //Compilerfehler
Blubb := 0;
Bla(Blubb); //kein Compilerfehler[/delphi][/edit] |
fast :D
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 ^^
WasWeißDennIch - So 24.02.13 01:08
IhopeonlyReader hat folgendes geschrieben : |
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? |
Nicht ganz. Von 0 bis Length(Source) - 1 ;) Dass ich grundsätzlich von Low() bis High() über Arrays iteriere hat einen ganz einfachen Grund: es passt immer! Ich weiß zwar, dass dynamische Arrays immer mit Index 0 beginnen und mit Index Length - 1 enden, aber daran muss ich bei dieser Vorgehensweise keinen Gedanken verschwenden. Zum eigenen Datentyp: versuch doch mal das hier
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| type TZahl = 1..MAXINT;
procedure DoWork(Zahl: TZahl); begin ShowMessage(IntToStr(Zahl)); end;
procedure TForm1.Button1Click(Sender: TObject); var Blubb: integer; begin Blubb := -42; DoWork(Blubb); end; |
Ergibt zumindest in Delphi 7 weder zur Entwurfs- noch zur Laufzeit einen Fehler.
IhopeonlyReader - So 24.02.13 01:15
WasWeißDennIch hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| type TZahl = 1..MAXINT;
procedure DoWork(Zahl: TZahl); begin ShowMessage(IntToStr(Zahl)); end;
procedure TForm1.Button1Click(Sender: TObject); var Blubb: integer; begin Blubb := -42; DoWork(Blubb); end; |
Ergibt zumindest in Delphi 7 weder zur Entwurfs- noch zur Laufzeit einen Fehler. |
stimmt.. um solche "Fehler" zu beheben schreiben wird die procedure ein ganz klein wenig anders :D
Delphi-Quelltext
1:
| procedure DoWork(var Zahl: TZahl); |
WasWeißDennIch - 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 :P . 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 - 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!!!
WasWeißDennIch - Do 28.02.13 09:28
Einverstanden, aber dann sollte man vielleicht noch etwas sprechendere Bezeichner wählen.
Tranx - Do 28.02.13 12:05
Kein Thema, s. Änderung
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!