Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

1

31.12.2012, 03:43

Zeiger, Arrays und Funktionsparameter ;)

Heyho,

Ich bin heute beim Programmieren auf ein Verständnisproblem gestossen.
Hier mal ein Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
int main()
{
    myClass *Array = new myClass[size];
    
    Function(Array);
}

void Function(myClass *array)
{}


Wie man erkennt, will ich ein Array an eine Funktion übergeben.

Also meiner Meinung nach, erhält die Funktion nur einen Pointer auf das Array und das ist somit die Speicherfreundlichste Methode.

Meine Frage ist nun ziemlich simpel, stimmt meine Annahme oder nicht und wenn nein, wie es dann am besten geht.


Zusatzfrage: Man kann ja auch einen Zeiger auf ein Array erstellen, welches aus Zeigern auf integer besteht. Aber ich habe es noch nie benutzt und auch noch nie so wirklich verstanden, warum nicht ein zeiger auf ein Array aus integern reicht?

mfg ERROR


PS.: Dass der Code so wie oben angegeben nicht funktioniert ist mir klar, aber als Beispiel genügt er(hoffentlich) vollkommen ;)

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »ERROR« (31.12.2012, 04:15)


Tobiking

1x Rätselkönig

  • Private Nachricht senden

2

31.12.2012, 05:26

Also meiner Meinung nach, erhält die Funktion nur einen Pointer auf das Array und das ist somit die Speicherfreundlichste Methode.

Meine Frage ist nun ziemlich simpel, stimmt meine Annahme oder nicht und wenn nein, wie es dann am besten geht.

Genauer gesagt erhält die Funktion einen Zeiger auf das erste Element in dem Array. Wegen dem Speicherbedarf weiß ich nicht welche anderen Methoden du jetzt meinst. Die Verwendung von myClass[] als Parameter ist mit myClass* identisch. In beiden Varianten musst du übrigens beachten, dass du in der Funktion nicht mehr die größe des Arrays kennst und diese separat übergeben musst.

Besser ist es einen ordentlichen Container wie z.B. std::vector oder falls vorhanden std::array zu verwenden und diese dann wie üblich als Referenz oder Zeiger zu übergeben. Diese bringen dann auch direkt ihre Größe mit.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

3

31.12.2012, 10:12

Genau, Finger weg von Arrays und stattdessen einen Container benutzen!
In deiner Funktion hast du keine Möglichkeit herauszufinden, wie groß das Array ist.
Du kriegst ja nur einen Zeiger auf das erste Element (keinen Zeiger auf das Array!).

Horni

Frischling

Beiträge: 21

Beruf: Student MB

  • Private Nachricht senden

4

31.12.2012, 13:10

Bei der Verwendung von Containern aus der STL kannst du ja ihre konstanten Referenzen (also Referenz auf const) als Paramter übergeben. Das müsste genauso sparsam bzw. schnell sein wie mit Zeigern, ist aber etwas sicherer.
Vorteil ist, dass die Referenz im Gegensatz zum Zeiger an das Objekt gebunden ist, auf das sie verweist.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

5

31.12.2012, 14:28

Ein Problem zu finden in dem ein Array mit Zeigern auf Integer sinnvoll ist, ist mir leider nicht gelungen.
Allerdings fällt mir eins für ein Array mit Zeigern auf eine Personenobjekte ein.

Du könntest die Personen in einem normalen Array speichern. Wenn du eine Sortierung nach Namen anbieten möchtest könntest du ein Array mit Zeigern erstellen und die Zeiger auf die Personen einsortieren. Wenn du dann noch nach Alter sortieren möchtest kannst du das selbe tun. So existiert jede Person nur ein mal im Speicher und du kannst sie beliebig oft sortieren.

Ich hoffe ich hab mich verständlich ausgedrückt :D
Das ist auch nur Beispiel und keine Empfehlung.^^
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

31.12.2012, 14:42

Abgesehen davon kannst du diese Zeiger natürlich auch in einen std::vector packen... ;)

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

7

31.12.2012, 14:58

Als erstes vielen Dank für die ganzen Rückmeldungen und danke Nachoman, für das Bsp.

Ich habe das ganze jetzt so gelöst:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
std::vector<myClass> Vector;

int main()
{
    Vector.reserve(size);
    
    function(Vector);
}

function(&vector)
{}


Und wieder stelle ich die Behauptung auf, dass diese Methode möglichst wenig Speicher frisst. Und wieder die Frage, stimmt meine Behauptung oder habe ich etwas falsch gemacht?

In der Funktion kann man dann ja ganz normal vector[10] = ... machen?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

31.12.2012, 15:08

Was genau verstehst du unter "möglichst wenig Speicher"? Abgesehen davon ist der Code da oben syntaktisch nicht ganz lupenrein, ich bezweifle dass das so kompilieren wird... ;)

9

31.12.2012, 15:08

Reserve ändert die Vektorgröße nicht, es beschleunigt nur das zukünftige vergrößern des Arrays (weil Speicher eben schon reserviert ist). Evtl. (kann man nicht so genau sagen) möchtest du eigentlich resize benutzen.

Wenn du eine Referenz auf den Vektor übergibst, wird nichts kopiert. Das ist dann prinzipiell "speicherschonend", vor allen Dingen aber etwas schneller, da das Kopien anlegen Zeit kostet (der Speicherplatz ist nicht das Problem, jedenfalls normalerweise nicht, da das Objekt ja nach verlassen der Funktion wieder gelöscht wird).

Und ja, in der Funktion kannst du jetzt den Vektor ganz normal benutzen und arbeitest dann auf dem original Vektor, du kannst also den Vektor verändern.
Lieber dumm fragen, als dumm bleiben!

Horni

Frischling

Beiträge: 21

Beruf: Student MB

  • Private Nachricht senden

10

31.12.2012, 15:21

Als erstes vielen Dank für die ganzen Rückmeldungen und danke Nachoman, für das Bsp.

Ich habe das ganze jetzt so gelöst:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
std::vector Vector;

int main()
{
    Vector.reserve(size);
    
    function(Vector);
}

function(&vector)
{}


Und wieder stelle ich die Behauptung auf, dass diese Methode möglichst wenig Speicher frisst. Und wieder die Frage, stimmt meine Behauptung oder habe ich etwas falsch gemacht?

In der Funktion kann man dann ja ganz normal vector[10] = ... machen?

Also am besten liest du dir mal die Dokumentation zur Benutzung von Vector durch.
Erstens ist Vector ist ja ein Klassentemplate. Du musst also den Typen angeben, den der Vector speichern soll.

Quellcode

1
std::vector<int> intVector;


Dann müssen die Elemente angelegt sein, um über den Indexoperatur [] auf sie zugreifen zu können.
Eine Möglichkeit ist:

Quellcode

1
intVector.push_back(Zahl); //Zahl ist vom Typ int


push_back() hängt immer an das letzte Element deines Vectors ein Element an.
Es gibt auch Methoden um mehrere Elemente auf einmal anzulegen, aber dazu gehört reserve nicht.

Der Vector legt selbständig Speicher an, darum brauchst du dich nicht zu kümmern. Er reserviert für eine bestimmte Anzahl von Elementen Speicher. Wenn du jetzt immer weiter Elemente anlegst und der Vector merkt, dass ihm Speicher ausgeht, dann wird er irgendwann neuen Speicher für eine bestimmte Anzahl von Elementen anlegen. Das ganze kann man natürlich Steuern, wenn man genau weiß, wie viele Elemente man braucht. Aber ich glaube das ist in den seltensten Fällen nötig. Dies kann man dann mit den Methode reserve und capacity festlegen.

Außerdem empfiehlt es sich Iteratoren zum Zugriff auf die Elemente von Vectoren zu verwenden. Genaueres findest du in der Dokumentation. Wobei du jetzt auch nicht die Übersicht verlieren sollst. Vielleicht wartest du mit der Anwendung von STL Containern, bis du alles betreffend der Arrays und Zeiger begriffen hast. Wisse einfach, dass man statt Arrays fast immer STL Container verwendet.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Horni« (31.12.2012, 15:39)


Werbeanzeige