Autor Beitrag
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Sa 23.02.13 22:06 
Guten Tag,
ich denke die Frage ist für erfahrene Programmierer schnell zu beantworten...

folgendes Beipsiel
ausblenden 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
ausblenden 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
ausblenden Delphi-Quelltext
1:
2:
3:
4:
var EineListehalt: Array[1..100of Integer; 
begin
Beispielfunktion(EineListehalt, 10);
end;

als auch mit
ausblenden Delphi-Quelltext
1:
2:
3:
4:
var EineListehalt: Array[1..15of Integer; 
begin
Beispielfunktion(EineListehalt, 10);
end;

aufrufen kann/könnte..

bei
ausblenden Delphi-Quelltext
1:
2:
3:
4:
var EineListehalt: Array[1..100of String
begin
Beispielfunktion(EineListehalt, 10);
end;

natürlich ein Felher (beim compilieren) kommt...

Ich hoffe es ist verständlich, was ich frage :D

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: 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).
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure SomeProc(IntArr: array of integer);

...
(* Möglicher Aufruf: *)
SomeProc([1234]);

(* Oder auch *)
var
  Dings: array[1..10of integer;
begin
  SomeProc(Dings);

Für diesen Beitrag haben gedankt: IhopeonlyReader
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: 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:
ausblenden 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.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure Bla(Zahl: TMyZahl);

Bla(0); //Compilerfehler

Blubb := 0;
Bla(Blubb); //kein Compilerfehler
[/edit]

Für diesen Beitrag haben gedankt: IhopeonlyReader
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Sa 23.02.13 22:41 
user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:

type
TMyZahl = 1..MAXINT;


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

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Sa 23.02.13 22:55 
das mit den Offenen Arrays ist ganz einfach:

ausblenden 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.

ausblenden 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);  // hier Compilerfehler!!
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: 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.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
type
  TIntArr = array of integer; //dynamischer Arraytyp

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([1234]))); //Compilerfehler
end;

Definiert man den Parameter aber als offenes Array, dann klappt das auch.
ausblenden 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([1234]))); //kein Compilerfehler
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Sa 23.02.13 23:48 
vielen Dank :)
also bei
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
Testvariable: Array[11..111of Integer;
begin
SumInt(Testvariable);
end;


ausblenden 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
//Maximale Größe des Arrays = High(Arr); (111)
//Startwert des Arrays = Low(Arr); (11)
//Range des Arrays = High(Arr)-Low(Arr); (100)
SetLength(DynArr, High(Arr)-Low(Arr));

Result := 0;
For C:=0 to High(DynArr) do
Result := Result + DynArr[C];  //= inc(Result, DynArr[C]);
end;



richtig? und sind High und low auch verwendbar, wenn man in einer procedure die eigentliche Variable (statisches Array) hat?
also
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
Testvariable: Array[11..111of Integer;
begin
// High = High(Testvariable) ...
oder muss man das ganze abstrakt sehen?
// High= High(^Testvariable) ... ?
end;

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: 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().
ausblenden Delphi-Quelltext
1:
2:
3:
var
  Testvariable: Array[11..111of Integer;
(* Low = 11, High = 111, Length = 101 *)
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: 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

ausblenden 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 00:25 
Prinzipiell sollte das möglich sein, ich persönlich würde es nur etwas anders schreiben:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 24.02.13 00:38 
user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden Delphi-Quelltext
1:
Dest[i + Succ(OldHigh)] := Source[i];					


mhh..
1. kenn ich succ nicht :D 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
ausblenden 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
ausblenden 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 24.02.13 00:51 
also ist

Zitat:

ausblenden Delphi-Quelltext
1:
for i := Low(Source) to High(Source) do					


ist also nichts anders als
ausblenden 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
IhopeonlyReader Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 24.02.13 00:59 
user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:

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 ^^

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 01:08 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
also ist

Zitat:

ausblenden Delphi-Quelltext
1:
for i := Low(Source) to High(Source) do					


ist also nichts anders als
ausblenden 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
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 24.02.13 01:15 
user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden 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
ausblenden Delphi-Quelltext
1:
procedure DoWork(var Zahl: TZahl);					

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 24.02.13 01:27 
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Do 28.02.13 05:53 
user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
Prinzipiell sollte das möglich sein, ich persönlich würde es nur etwas anders schreiben:
ausblenden 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)
ausblenden 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)
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Do 28.02.13 09:28 
Einverstanden, aber dann sollte man vielleicht noch etwas sprechendere Bezeichner wählen.