Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Sa Jul 12, 2025 15:26

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Di Okt 16, 2007 10:08 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
Hallo,
ich habe mich schon länger gefragt, wie ich Arrays fester Länge als Parameter übergeben soll.
Nehmen wir mal an ich habe ein Array [0..2] of Single; also ein einfacher TVektor. Nun will ich einige Funktionen implementieren, z.B.:
Code:
  1. VectorAdd(const v1, v2: TVector): TVector;
  2. Begin
  3.   Result[0] := v1[0] + v2[0];
  4.   Result[1] := v1[1] + v2[1];
  5.   Result[2] := v1[2] + v2[2];
  6. End;


Ist es jetzt so, dass Delphi die Parameter v1 und v2 in die Funktion "kopieren" muss, oder wird dafür intern nur ein Pointer verwendet? Macht es also Sinn in die Funktion manuell Pointer auf die zu addierenden Vektoren zu übergeben, und dann in dieser Funktion die Pointer zu dereferenzieren?

Bei einfachen Typen/Funktionen macht das "kopieren" der Parameter vielleicht keinen spürbaren Einfluss auf die Performance, aber bei Matrizen könnte das schon eher ins Gewicht fallen...

Wäre schön, wenn ihr da ein bisschen Klarheit reinbringen könntet. :wink:

_________________
http://texelviews.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 11:26 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Es gibt in Delphi 2 Arten der Parameterübergabe: CallByValue und CallByReference. Im ersten Fall wird eine Kopie angelegt, im zweiten eine Referenz (sprich der Inhalt der Originalen übergebenen variable ändert sich mit, wenn sich die Variable in der Funktion ändert). Eine Referenz muss aber nicht unbedingt gleich ein Zeiger sein, das löst der Compiler selber.
CallByReference erzwingst Du mit den Aufrufkonventionen var und out, wobei im Falle von out die übergebene Variable explitzit genullt wird, also die Wertübergabe in die Funktion nicht möglich ist.
CallByValue erzwingst Du entweder ohne Konvention oder mit const. Hier werden lokale Änderungen nicht nach aussen gereicht, da die Parameter in Kopie angelegt werden. Const verhindert zudem Änderungen in der Funktion und Constparameter können nicht als var oder out weitergereicht werden.

Einen Pointer als const zu übergeben und in der Funktion zu dereferenzieren ist also Quartsch. Übergib Deine TVektor als var und es werden keine Kopien angelegt.

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 11:32 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Wenn man const Parameter mit records größer als 4 Byte verwendet, wird nur der Zeiger übergeben.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 11:44 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
Danke für die Antworten!
Das mit var übergeben hatte ich auch schon mal überlegt, aber das verwirrt ja den User, wenn dann die Parameter gar nicht geändert werden (müssen)...

LarsMiddendorf hat geschrieben:
Wenn man const Parameter mit records größer als 4 Byte verwendet, wird nur der Zeiger übergeben.

Dann macht das Delphi also intern mit Pointern, und ich kann getrost meine Typen als const-Parameter verwenden.
Ich schätze das mit dem "größer als 4 Byte" gilt auch für einfache bzw. mehrdimensionale Arrays, oder?

_________________
http://texelviews.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 12:51 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Es wird zwar zunächst nur der Zeiger übergeben, aber bei Schribzugriff sollte das Array dann eigentlich in Kopie angelegt werden.
Und wie gesagt: const-Parameter verhindern das verändern innerhalb der Funktion. Der Parameter ist dann sozusagen eine Konstante.

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 14:21 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
Sidorion hat geschrieben:
Es wird zwar zunächst nur der Zeiger übergeben, aber bei Schribzugriff sollte das Array dann eigentlich in Kopie angelegt werden.

Gut, solange ich also nichts reinschreibe (bei const), wird also intern nur ein Pointer verwendet. :P

_________________
http://texelviews.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 14:53 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Wenn du var verwendest, dann wird aus deiner var automatisch nen pointer gemacht.
Die frage sollte sein, willst du den nutzer wirklich pointer antuen oder es ein bischen verstecken(var).

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 15:12 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
@tak: das ist so nicht richtig. es wird kein Pointer daraus gemacht, ein Integer bleibt ein Integer, aber beide Variablen liegen an der gleichen Speicheradresse. Zeiger auf beide hätten sozusagen den gleichen Wert.
Varparameter velangen allerdings Typgleichheit und Du kannst keine Funktionsergebnisse oder Konstanten (true, 1, usw) einsetzen.

@MatReno: Du musst nicht const davorschreiben (als Gegensatz zu var). Const und nix ist für den Aufrufer identisch, der Unterschied zeigt sich nur innerhalb der Funktion.

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 18:31 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Gut zu wissen, denn unter FPC ist procedure myproc(var bla); das gleiche wie procedure myproc(bla:pointer);
Man muss allerdings dann selber ^ setzen :\ und deswegen favorisiere ich auch var.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 19:54 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
var+out und pointer ist afaik in delphi auch das selbe (vom generierten code her).
const ist pointer oder kopie je nach Größe
Ohne Angabe ist byvalue also kopie

Bei strings kann man durch const viel Zeit sparen, insbesondere wenn man keine lokalen stringvariablen/dynarrays hat. Denn dann kann der compilter das implizite try finally end; für den lokalen string(der auch bei call-by-value angelegt wird) weglassen.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 16, 2007 20:16 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Also da muss ich gerade mal etwas wiedersprechen. VAR auf ein Integer ist ein Pointer. Als Beweis hier mal der Assemblercode aus der CPU Ansicht.
Code:
  1. procedure Blah(var A: Integer);
  2. begin
  3.   A := 10;
  4. end;
  5.  
  6. var
  7.   C: Integer;
  8.  
  9. begin
  10.   C := 12;
  11.   Blah(C);


Code:
  1. mov [$00422428], $0000000c
  2. mov eax,$00422428
  3. call Blah

Mit anderen Worten es wird die gleiche Adresse übergeben (steckt in AEX) in die auch die 10 ($C) geschrieben wird.

Und const und nichts macht durchaus einen Unterschied denn bei nichts wird explizit eine Kopie in der Funktion erstellst. Nur gültig innerhalb der Funktion. Allerdings war es mit nicht möglich auf den Pointer von der Konstante etwas zu schreiben. Keine Ahnung wieso aber kam irgendwie nicht so richtig. Zu mindest nicht alles. Aber der zweite Wert schon.

Das was du da wohl eher meinst sind Strings. Dort wird ständig nur der Pointer übergeben und im Falle einer Änderung wird bei nichts eine Kopie erstellt.

FPC: Bei FPC ist es bei Records so, dass wenn man nichts angibt das Record komplett auf dem Stack übergeben wird. Bei Delphi ist es die Adresse von dessen Daten anschließend eine Kopie gemacht werden. Da gabs bei glu mal so ein Problem im Header.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 17, 2007 08:48 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
- Im resultierenden Assemblercode isses natürlich ein Zeiger, muss aber im Quelltext nicht als solcher behandelt werden.
- Dass Strings und Arrays in Delphi als Pointer übergeben werden liegt daran, dass in Delphi grundsätzlich bei solchen Konstrukten nur ein zweiter Zeiger beim Kopieren erstellt wird. Erst wenn eins der beiden tatsächlich verändert wird, wird die Kopie erstellt. Das ist unabhängig von Funktionsaufrufen.
- Bei Const wird auch eine Kopie erstellt, ist aber nicht beschreibbar.
- var und out sind nicht das selbe. Outparameter dienen ausschließlich der Rückgabe und der übergebene Wert ist in der Funktion nicht verfügbar. Steht in der OH.
- dass man bei Strings durch const Zeit sparen kann liegt daher, dass eben die Kopie erst bei Änderung eines der beiden angelegt wird (und ewnn der String nicht geändert werden kann (const) wird auch keine Kopie erstellt). Ein String als Varparameter spart noch mehr Zeit, da hier garnix kopiert werden muss.

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 17, 2007 09:25 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
const erzeugt bei kleinen parametern (<=4Byte) eine kopie. Ist also dann effektiv das selbe wie by-value. Wenn die Variable >4Byte ist, wird nur ein zeiger übergeben, dessen ziel der kompiler vor schreibzugriffen schüzt. Bei var wird immer ein pointer übergeben.
Strings und dynamische arrays müssen wegen der referenzzählung anders behandelt werden. Bei by-value wird eine kopie des Strings(also des zeigers auf die daten) angelegt und die referenz entsprechend erhöht. Bei const wird der String(also zeiger) direkt übergeben. Bei var wird ein zeiger auf den string übergeben (zeiger auf zeiger).
Wenn lokale Stringvariablen vorhanden sind (also bei by-value) muss außerdem noch ein finally schutzblock erstellt werden um die freigabe abzusichern.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 19 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 16 Queries | GZIP : On ]