array-grösse über const

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
malabarista
Beiträge: 321
Registriert: Sa 11. Jun 2016, 12:16
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0
CPU-Target: 64Bit
Wohnort: Konstanz

array-grösse über const

Beitrag von malabarista »

Ich wollte die Größe eines arrays über eine Konstante fest definieren.
Allerdings ist mir dies nicht gelungen.

Code: Alles auswählen

 
const feldanz:integer=11;
 
var
  lab_l:array[0..feldanz] of TLabel;
  edit_t:array[0..feldanz] of Tedit;           
 


Compilerfehler: can't evaluate constant expression

Hab leider im Tutorial nichts Geeignetes gefunden.
Kann ich nicht über eine Konstante die Größe eines Arrays definieren ?

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: array-grösse über const

Beitrag von marcov »

Entferne : integer also


Code: Alles auswählen

const feldanz = 11;


Merke das der Kode eine Array von 12 Elementen (0..11) deklariert.

wp_xyz
Beiträge: 4892
Registriert: Fr 8. Apr 2011, 09:01

Re: array-grösse über const

Beitrag von wp_xyz »

Leider hat da der FPC eine Unsauberkeit von Delphi übernommen:

Code: Alles auswählen

const
  feldanz: Integer = 11;

bezeichnet eine initialisierte Variable, keine Konstante!

Übrigens zur Benennung eines Bezeichners als "Anzahl". Wenn "FeldAnz" 11 ist, erwarte ich auch 11 Elemente. Da du das Array aber als [0..feldAnz] deklarierst, hat es 12 Elemente. Diese Inkonsistenz bereitet dir mit Sicherheit irgendwann einmal schwer findbare Fehler. Deklariere das Array als [0..feldAnz-1], dann stimmt die sprachliche Welt wieder. Oder verwende statt "feldAnz" besser "maxFeldIndex".

Mathias
Beiträge: 6204
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: array-grösse über const

Beitrag von Mathias »

Leider hat da der FPC eine Unsauberkeit von Delphi übernommen:

Das ist irgendwie schon nicht so sauber.

Dies ist ein gutes Beispiel:

Code: Alles auswählen

procedure Test;
const
  i: integer = 123;
begin
  Inc(i);
  WriteLn(i);
end;   


Sowas wäre um einiges übersichtlicher:

Code: Alles auswählen

var i : integer = 123; static;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4892
Registriert: Fr 8. Apr 2011, 09:01

Re: array-grösse über const

Beitrag von wp_xyz »

Zur Ergänzung noch das:
- Mit {$J-} kann man die typisierten Konstanten zu wirklichen Konstanten machen
- Auch einer var-Deklaration kann man einen Initialisierungswert zuweisen

Code: Alles auswählen

program Project1;
{$J-}   // Wenn diese Direktive aktiv ist, scheitert die Veränderung der typisierten Konstanten c in der 1. Zeile
const
  c: Integer = 1;
var
  v: Integer = 1;
begin
  inc(c);
  WriteLn('c: ', c);
  inc(v);
  WriteLn('v: ', v);
end

malabarista
Beiträge: 321
Registriert: Sa 11. Jun 2016, 12:16
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0
CPU-Target: 64Bit
Wohnort: Konstanz

Re: array-grösse über const

Beitrag von malabarista »

Danke für alle Hinweise.

mischi
Beiträge: 206
Registriert: Di 10. Nov 2009, 18:49
OS, Lazarus, FPC: macOS, 10.13, lazarus 1.8.x, fpc 3.0.x
CPU-Target: 32Bit/64bit

Re: array-grösse über const

Beitrag von mischi »

wp_xyz hat geschrieben:Leider hat da der FPC eine Unsauberkeit von Delphi übernommen:

Code: Alles auswählen

const
  feldanz: Integer = 11;

bezeichnet eine initialisierte Variable, keine Konstante!

Übrigens zur Benennung eines Bezeichners als "Anzahl". Wenn "FeldAnz" 11 ist, erwarte ich auch 11 Elemente. Da du das Array aber als [0..feldAnz] deklarierst, hat es 12 Elemente. Diese Inkonsistenz bereitet dir mit Sicherheit irgendwann einmal schwer findbare Fehler. Deklariere das Array als [0..feldAnz-1], dann stimmt die sprachliche Welt wieder. Oder verwende statt "feldAnz" besser "maxFeldIndex".

An vielen Stellen ist es sogar sinnvoller mit 1 anzufangen, also Array[1..feldAnz] of ...
MiSchi macht die fink-Pakete

wp_xyz
Beiträge: 4892
Registriert: Fr 8. Apr 2011, 09:01

Re: array-grösse über const

Beitrag von wp_xyz »

mischi hat geschrieben:An vielen Stellen ist es sogar sinnvoller mit 1 anzufangen, also Array[1..feldAnz] of ...

Das würde ich mir gar nicht angewöhnen, weil (fast) immer die Indices mit 0 anfangen. Und wenn man gegen den Strom schwimmt, kommt man nicht weiter...

mischi
Beiträge: 206
Registriert: Di 10. Nov 2009, 18:49
OS, Lazarus, FPC: macOS, 10.13, lazarus 1.8.x, fpc 3.0.x
CPU-Target: 32Bit/64bit

Re: array-grösse über const

Beitrag von mischi »

wp_xyz hat geschrieben:
mischi hat geschrieben:An vielen Stellen ist es sogar sinnvoller mit 1 anzufangen, also Array[1..feldAnz] of ...

Das würde ich mir gar nicht angewöhnen, weil (fast) immer die Indices mit 0 anfangen. Und wenn man gegen den Strom schwimmt, kommt man nicht weiter...

Kommt auf den Strom an. Bei manchen Problemen ist es natürlich, mit 1 und nicht mit 0 anzufangen. Der Zwang alles mit 0 zu beginnen ist eine Unsitte aus C. Fortran macht genau das andere. Dort fängt alles mit 1 an und mit 0 anzufangen, wäre gegen den Strom. Ich finde, dass es gerade ein Vorteil von Pascal ist, dass man nicht von vorne herein zu einer Variante gezwungen wird, sondern es tatsächlich von der Problemstellung abhängig machen kann. In der Chemie fängt man zum Beispiel beim Abzählen der Kohlenstoffe in einem Molekül und der Nummerierung der Atome immer mit 1 und nicht mit 0 an.
MiSchi macht die fink-Pakete

wp_xyz
Beiträge: 4892
Registriert: Fr 8. Apr 2011, 09:01

Re: array-grösse über const

Beitrag von wp_xyz »

Das ist alles klar. Nur hast du bei den wichtigen dynamischen Arrays keine Wahl mehr, die beginnen halt mal bei 0. Und wenn du in deinen Programmen permanent zwischen 0- und 1-basierten Arrays hinundherwechselst, wirst du irgendwann einmal durcheinander kommen und den Speicherplatz des letzten Arrayelements überschreiben. Ich erinnere mich an die Probleme eines Users im englischen Forum, der partout mit 1 beginnen wollte...

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: array-grösse über const

Beitrag von Michl »

Umdenken muss man zwar bei Strings, ansonsten halte ich das zu über 90% auch so, dass meine statischen Arrays mit 0 anfangen (analog zu dynamischen Arrays). Wenn ich keine For-In Schleife nutze, gehe ich das Array von 0 bis High(MyArray) durch. Wobei eine Empfehlung lautet, immer Low(MyArray) bis High(MyArray) zu nutzen. Dadurch benötige ich keine Konstanten, die ein Array beschreiben. Ausnahme sind Konstanten, die globale Randbedingungen setzen und zum besseren Verständnis dienen (zumeist schmeiße ich alle globalen Konstanten in eine Unit "Definitions").

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Mathias
Beiträge: 6204
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: array-grösse über const

Beitrag von Mathias »

Ich habe mir auch angewöhnt, immer bei 0 zu beginnen.
Meistens verwende ich sowieso dynamische Arrays und dabei bleibt sowieso wie oben beschrieben nichts anderes übrig.
Und wen man zwischendurch C oder Java schreibt, dann hat man es einfacher.
In einer for Schleife verwende ich immer Length(a) - 1.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: array-grösse über const

Beitrag von Socke »

Michl hat geschrieben:Umdenken muss man zwar bei Strings, ansonsten halte ich das zu über 90% auch so, dass meine statischen Arrays mit 0 anfangen (analog zu dynamischen Arrays). Wenn ich keine For-In Schleife nutze, gehe ich das Array von 0 bis High(MyArray) durch. Wobei eine Empfehlung lautet, immer Low(MyArray) bis High(MyArray) zu nutzen. Dadurch benötige ich keine Konstanten, die ein Array beschreiben. Ausnahme sind Konstanten, die globale Randbedingungen setzen und zum besseren Verständnis dienen (zumeist schmeiße ich alle globalen Konstanten in eine Unit "Definitions").

Sehe ich ähnlich.

Aufgrund der binären Verarbeitung der Zahlen in einem Prozessor ist die 0 als Basisindex näher an der physikalischen Verarbeitung. Damit kann man auch den Zahlenraum des Index-Datentyps (Integer) voll ausnutzen.
Diesen "datenlogischen" Hintergrund sollte man meines Erachtens immer anwenden, wenn sich keine Gründe aus dem logischen Inhalt des Arrays erschließen.
Das heißt: zur reinen Datenhaltung ist Index 0 angesagt, wie es für dynamische Arrays fest gelegt ist, um die Konsitenz zu wahren. Diese Konsistenz hilft, fehler zu vermeiden. Beispielsweise erlaubt es Visual Basic für jedes Modul den Basis-Index selbst festzulegen bzw. durch das Programm vorzugeben. Damit sind alle schnell verwirrt, wenn jeder die Indizes ein wenig anders gestaltet.

Hat der Index selbst eine Bedeutung, kann der Index dementsprechend entsprechend seiner Bedeutung gewählt werden - zum Beispiel ordnet man den Wochentagen üblicherweise die Zahlen 1 bis 7 zu oder die Monate werden von 1 bis 12 nummeriert. Hier wäre eine Abweichung dem Verständnis abträglich.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Albin
Beiträge: 20
Registriert: Fr 15. Jul 2016, 13:24

Re: array-grösse über const

Beitrag von Albin »

Verstehe ich das richtig?

Hier ist c eine Konstante:

Code: Alles auswählen

program Project1;
{$J-}
const
  c: Integer = 1;
 
[/quote]

Aber hier ist es eine initialisierte Variable:

Code: Alles auswählen

program Project1;
const
  c: Integer = 1;
 
[/quote]

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2640
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: array-grösse über const

Beitrag von m.fuchs »

Genau.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Antworten