Welche Sprache lernen ?



  • Nimm nen Apfel, mach zwei Schilder mit nem Pfeil drauf die auf den Apfel zeigen.
    Dann sagst Du delete Schild 1, nimmst das Schild weg und isst den Apfeln. Jetzt versuchst Du den Apfel zu Essen auf den Schild zwei zeigt.



  • Artchi schrieb:

    - Du baust ein Kiste, und notierst dir auf einem Zettel, wo du sie hingestellt hast.
    ➡ int *zettel = new int;
    cout << zettel;

    - Du nimmst einen weiteren Zettel und überträgst die Daten des ersten auf diesen.
    ➡ int *zettel2 = zettel;
    cout << zettel2;

    - Irgendwann später nimmst du den ersten Zettel, suchst die Kiste und machst sie kaputt.
    ➡ delete zettel;
    zettel = NULL; //
    cout << zettel;

    - Danach zerreißt du dann den ersten Zettel.
    ➡ out of scope

    - Du hast zwar noch den zweiten Zettel, auf dem steht, wo die Kiste war, aber die Kiste ist trotzdem weg.
    ➡ cout << zettel2; // aha?!

    Hallo,

    ja aber so mach ich das doch gar nicht !
    Das was Du hier erklärt hast habe ich verstanden .

    Aber int *zettel2 = zettel; ?????
    Kannst Du mal Bitte bei dem Kisten Beispiel bleiben?
    Ansonsten bringen mich ja die vielen vershciedenen Beispiele noch zusätzlich durcheineander....danke !

    Also nachmal das was ich mache(n soll) :

    Im groben geht es ja darum eine Kiste ( intArray ) zu vergrößern.
    Also ich hab nen intArray mit 2 Werten und möchte diesen um einen Wert erweitern so das er 3 Werte aufnehmen kann.
    Bsp: Kiste in die 2 IntWerte passen soll so verändert werden das in Kiste 3 intWerte passen.

    Ich hab ne Kiste in die passen 2 int Werte
    --> int * kiste = new int[2]; // Also ne Kiste mit 2 intWerten

    Nun eine TEMPORÄRE Kiste erstellen
    --> int TempKiste = new int[3]; // TempKiste mit 3 intWerten

    Werte aus Kiste in TempKiste kopieren
    --> TempKiste[0] = Kiste[0]; ... [1] = [1];

    Neuen Wert in TempKiste aufnehmen
    --> TempKiste[2] = 3; // Dritter intWert ist in TempKiste.

    Ok, bis hierher alles klar.
    Ich habe zwei Zeiger ( kiste und TempKiste ).
    Zeiger sollen ja unter C++ immer wieder gelöscht werden und das ist ja der knackpunkt. Die TempKiste soll ja nur ein Temporärer Zeiger sein, also müsste der doch wieder gelöscht werden können nach der Methode oder?

    Also ich habe immer noch 2 Kiste, eine Kiste in die 2 intWerte passen und eine TempKiste in der 3 intWerte drin sind, die beiden aus der Kiste und der 3.intWert der dazugekommen ist.
    Soweit so gut.

    Jetzt kann ich doch die Kiste löschen, denn die kann ja nur mit 2 intwerten und deswegen brauche ich die nicht mehr. Ich habe ja alle Werte bereits in der TempKiste zwischengespeichert.
    Also
    --> delete[](kiste);

    Jetzt soll aber meine Kiste ( zeiger ) nicht TempKiste heisßen sondern wie gehabt Kiste, damit meine Arbeiter nicht durcheinander kommen.
    Da es ja keine Kiste mehr gibt mach ich eine neue und die auch wieder mit 3 Werten ( was ja das Ziel des ganzen ist )

    --> int * kiste = new int[3]; // neue Kiste die nun auch mit 3 intWerten kann

    Ok, nun kopieren wir doch alle Werte aus der Temporären Kiste ( TempKiste ) wieder in die niegelnagelneue Kiste:
    --> kiste[0] = TempKiste[0];
    --> kiste[1] = TempKiste[1];
    --> kiste[2] = TempKiste[2];

    So, mein Zeiger ( kiste ) zeigt doch nun auf kist und nicht auf TempKiste oder ?
    Warum kannich dann die blöde TempKiste nicht
    --> delete[](TempKiste);
    löschen ?
    Das verstehe ich nicht ?

    So, könntet Ihr nun bitte bei DIESEM Beispiel bleiben ?
    Danke
    Matthias

    ps.: Danke für die niedlichen Videos !



  • Hast Du dir das Video mal angesehen ?

    Wo ist da jetzt noch das Problem ?



  • Zeiger sollen unter C++ nicht immer wieder gelöscht werden. Wer hat dir denn den Floh ins Ohr gesetzt? Ich sage und kenne das so: Man löscht seine Objekte DANN, wenn man sie nicht mehr benötigt. Hat doch schon eine ganz andere Aussage, oder?

    Weiterhin scheinst du dir meine Richtigstellung mit den Kisten nicht angeschaut zu haben. Warum verharrst du so doll auf DEIN Beispiel? Wir versuchen dir die Pointer einfach anders zu erklären. Wenn du die einfachen Beispiele nicht verstehst, nützt dir DEIN Beispiel nicht viel weiter. Das Pointerfun-Video soll man auch nicht niedlich finden, man soll es sich ansehen, zu hören und versuchen zu verstehen! Notfalls mehrmals das Video anschauen. Das Video zeigt animatorisch, was wir dir versuchen hier zu erklären. Meine Kisten-Anwort auf Rüdigers Beispiel ist ähnlich dem Video.



  • Artchi schrieb:

    1.:::
    Zeiger sollen unter C++ nicht immer wieder gelöscht werden. Wer hat dir denn den Floh ins Ohr gesetzt? Ich sage und kenne das so: Man löscht seine Objekte DANN, wenn man sie nicht mehr benötigt. Hat doch schon eine ganz andere Aussage, oder?

    2.:::
    Weiterhin scheinst du dir meine Richtigstellung mit den Kisten nicht angeschaut zu haben. Warum verharrst du so doll auf DEIN Beispiel?

    3.:::
    Wir versuchen dir die Pointer einfach anders zu erklären. Wenn du die einfachen Beispiele nicht verstehst, nützt dir DEIN Beispiel nicht viel weiter.

    4.:::
    Das Pointerfun-Video soll man auch nicht niedlich finden, man soll es sich ansehen, zu hören und versuchen zu verstehen! Notfalls mehrmals das Video anschauen. Das Video zeigt animatorisch, was wir dir versuchen hier zu erklären. Meine Kisten-Anwort auf Rüdigers Beispiel ist ähnlich dem Video.

    Zu 1.:::
    Genau !! Zeiger die man nicht mehr braucht soll man löschen steht in meinem Buch hier !
    Wenn ich "immer wieder" geschrieben habe tut es mir leid. Ich habe das aber so gemeint das man Zeiger die man nicht mehr benötigt wieder löschen soll, also das es in der Hand des programmierers liegt...sorry !!!

    Zu 2.:::
    Weil ich das Zeigern schon nicht verstehe und wenn ich bei jeder Antwort von Euch erst mal ein neues Beispiel verstehen soll, dann bringt mich genau das nicht weiter.
    Deswegen bitte bei meinem Beispiel bleiben !

    Zu 3.:::
    Gut und schön, aber deswegen ist int * zettel = new int;
    nicht das gleiche wie int * zettel = new int[2];

    Zu 4.:::
    Das Video ist sehr hilfreich und eben auch niedlich,
    Ich habs mir angeschaut und es dreht sich gar nicht um mein problem !

    int * x;
    int * y;

    x = new int;
    *x = 42;

    *y = 13; // Error, logisch weil noch nicht erzeugt, zeigt als ins nirvana
    y = x;

    usw......ist mir klar.
    Hat aber wie gesagt auch absolut nix mit dem zu tun was hier mein Problem ist !
    Trotzdem war es Hilfreich !
    Und eben auch niedlich...sorry

    Nun hab ich aber die Lösung gefunden:

    Könt es ja mal ausprobieren :

    int main()
    {
    
    	int * Kiste = new int[2]; // 2 Werte in Kiste 1
    	// Werte zuweisen
    	Kiste[0] = 0;
    	Kiste[1] = 1;
    
    	// TestAusgabe
    	cout << "Ausgabe der Originalkiste mit den 2 intWerten: " << endl;
    	cout << "Kiste 0: " << Kiste[0] << endl;
    	cout << "Kiste 1: " << Kiste[1] << endl << endl;
    
    	// TempKiste ( 3 Werte ) erstellen
    	int * TempKiste = new int[3];
    
    	// Tempkiste die 2 Werte der Kiste zuweisen
    	TempKiste[0] = Kiste[0];
    	TempKiste[1] = Kiste[1];
    
    	// TestAusgabe
    	cout << "Ausgabe der TempKiste die 3 intWerte aufnehmen kann:" << endl;
    	cout << "TempKiste 0: " << TempKiste[0] << endl;
    	cout << "TempKiste 1: " << TempKiste[1] << endl;
    
    	// Hier wird irgendwas angezeigt ( TempKiste[2] )
    	// Mir klar, da der Wert noch nicht zugewiesen ist
    	cout << "     3.Wert der TempKiste noch undefiniert !:" << endl;
    	cout << "TempKiste 2: "	<< TempKiste[2] << endl << endl;  
    
    	// Den letzten Wert zuweisen
    	TempKiste[2] = 3;
    
    	// TestAusgabe
    	cout << "     dem 3.intWert wurde die Zahl 3 zugewiesen:" << endl;
    	cout << "TempKiste 2: " << TempKiste[2] << endl << endl;
    
    	// Alte Kiste löschen 
    	delete[](Kiste);
    	// und neu ( mit 3 werten ) erstellen:
    	int * kiste = new int[3];	 // Hier war mein Fehler !!!
    
    	// der neuen größeren Kiste die TempWerte zuweisen:
    	kiste[0] = TempKiste[0];
    	kiste[1] = TempKiste[1];
    	kiste[2] = TempKiste[2];
    
    	// Da die kiste jetzt die gleichen Werte wie die TempKiste
    	// enthält kann die TempKiste weg !!!!
    	// *******************************************************
    	// Zeiger die man nicht mehr benötigt soll man löschen !!!
    	// *******************************************************
    	delete[](TempKiste);
    
    	// TestAusgabe
    	cout << "Woila...unsere neue ( alte ) kiste namens kiste kann jetzt mit 3 intWerten :" << endl;
    	cout << "Kiste 0: " << Kiste[0] << endl;
    	cout << "Kiste 1: " << Kiste[1] << endl;
    	cout << "Kiste 2: " << Kiste[2] << endl << endl;
    
    	// TestAusgabe
    	// Nun ist auch logisch das diese Werte hier ndefiniert sind.
    	cout << "TempKiste ist logisch undefiniert, zeigt also auf nix:" << endl;
    	cout << "TempKiste 0: " << TempKiste[0] << endl;
    	cout << "TempKiste 1: " << TempKiste[1] << endl;
    	cout << "TempKiste 2: "	<< TempKiste[2] << endl;
    
    	system("Pause");
    }
    

    Ich habs mühselig kommentiert, was auch noch ein Grund ist warum ich es schön fände wenn Ihr mal meine Beispielcodes verändert zurückposten würdet.

    Matthias



  • Zu 4.:::
    Das Video ist sehr hilfreich und eben auch niedlich,
    Ich habs mir angeschaut und es dreht sich gar nicht um mein problem !

    Doch genau das ist Dein Problem (nebst Deiner Sturheit).

    Was Du jetzt machst ist doppelte Kopierarbeit. Dein Quellcode zeigt, das Du von dem Film das entscheidende nicht verstanden hast. Ich wüsste nicht wie sonst das hier zustande kommt:

    int * kiste = new int[3];     // Hier war mein Fehler !!!
    
        // der neuen größeren Kiste die TempWerte zuweisen:
        kiste[0] = TempKiste[0];
        kiste[1] = TempKiste[1];
        kiste[2] = TempKiste[2];
    

    Ein einfaches kiste = TempKiste OHNE löschen der TempKiste hätte es vollst auf getan. Du erzeugst lieber noch eine Kiste und packst alles noch mal um. Und das nur weil Du unbedingt die Kiste zerstören willst auf die TempKiste zeigt und nicht diese Kiste einfach als kiste zu verwenden.

    👎



  • Hallo,

    ja, damit hast du vielleicht Recht, aber das war ja nicht die AUFGABE !
    Versteht Ihr das nicht ?

    Die Aufagen war es GENAU die KISTE zu vergrößern und eben nicht
    eine TempKiste zu erzeugen und die Kiste dann auf die TempKiste zeigen zu lassen !
    Das ist ja das problem. Ihr wollt mir hier irgendwas erklären was aber gar nicht die Aufgaebenstellung aus meinem Buch hier ist !

    Da steht ausdrücklich drin das man das eben nicht einfach machen soll, sondern so wie ich es nun selber herausgefunden habe !

    Ich denke es ist eher Euer Problem das Ihr die Aufgabenstellung völlig aus dem Auge verliert nur weil Ihr der Meinung seid das das eben so gemacht wird.
    Ist vielleicht auch so üblich, aber wie gesagt, war nicht die Aufgabe geschweige denn die Frage die ich eigentlich beantwortet haben wollte !!

    erstes Posting von mir:

    .
    .
    Also Aufgabe ist es ( und ich soll das als Übung auch so machen ) eine Klasse zu schreiben die ein dynaisches Int Feld verwaltet, also einen Array.
    So weit so gut.
    Konstruktor ist so das man die Größe ( Anzahl der Werte ) übergeben muss.
    Das geht auch , kein Thema.

    Nun kommts...ich soll eine Methode Add( int wert) schreiben die dem verwalteten Array ein Element anhängt.
    .
    .

    Also wenn das nicht alles sagt weiß ich es auch nicht wie genau ich die Frage denn noch formulieren muß ?

    Methode Add( int wert) schreiben die dem verwalteten Array ein Element anhängt

    eine Methode Add die dem verwaltetetn Array ( also genau diesem und keinem anderen !! )

    Matthias



  • Oh mann, da fällt einen doch nichts mehr ein.

    So wie Du die Aufgabe interpretierst, erfüllst Du die Aufgabe nicht, weil Du die Originalkiste nicht vergrößerst sondern löschst und neu anlegst.

    Aber machst ja eh was Du willst.....

    Das was Du herausgefunden hast ist totaler humbuck. Du legst so zwei temporäre Kisten an und lässt den Zeiger auf die 2. Temporäre Kiste zeigen.



  • Also die Aufgabe stellt sich aber einfacher, als du es umsetzen willst. Gehen wir mal davon aus, das du wirklich nur das umsetzen sollst, was du jetzt fett markiert hast, würde ich es so lösen:

    class IntArray
    {
        int feldAnzahl;
        int maxFelder;
        int *kiste;
    
    public:
        IntArray(int felder)
        {
            kiste = new int[felder];
            feldAnzahl = 0;
            maxFelder = felder;
        }
    
        void add(int a)
        {
           if(feldAnzahl < maxFelder) {
               kiste[feldAnzahl] = a;
               feldAnzahl++;
           }
        }
    };
    

    So, ich hoffe ich habe keinen Fehler drin. In deiner Aufgabe steht nichts davon, das die Kiste sich in der Größe ändern soll.

    Wenn du das machen willst (Kiste soll sich auch nachträglich ändern), hast du einen Denkfehler in deinem letzten Beispiel: du kopierst die Pointer einmal zu viel um und du legst dir eine temporäre Kiste unnötig an. Warum? Ich versuche es zu erklären: du hast ein originale Kiste, die zu klein ist. Aber "kiste" ist bei dir nur ein Zeiger! Ein Zettel, es ist nicht DIE physikalische Kiste. So, dann legst du eine temporäre Kiste an, die gleich die richtige Größe hat. Und legst die zwei alten Sachen (ints) in die neue Kiste rein. Gut. Für die zweite Kiste hast du einen neuen Zettel (Zeiger) namens TempKiste. Ok?

    Warum legst du jetzt eine dritte Kiste an? Du bist doch bis jetzt fast fertig. Warum nimmst du nicht den zweiten Zettel, und schreibst den Inhalt (nur ein ZEIGER-Wert, nicht die physikalische zweite Kiste!!!) auf den Zettel der EHEMALIGEN ersten Kiste?

    Mit diesem Schritt wäre alles fetig und du könntest deinen ersten Zettel weiter benutzen. Ohne dritte Kiste und ohne dritten Zettel.

    Um den Inhalt des Zettels 2 auf Zettel 1 zu schreiben, sieht so aus:

    Kiste = TempKiste;

    Kommt dir bestimmt bekannt vor?

    Versuch mal das, was ich dir jetzt erzählt habe, in C++ code umzusetzen. Und lasse das deleten auch erstmal weg. Das kannst du auch danach einbauen... aber nur aus Verständniszwecke später einbauen.

    Übrigens würde ich auch zum besseren Verständnis, Kiste nicht Kiste nennen, sondern z.B. kiste_pointer oder zettel_kiste. Nur für dich als Einsteiger, damit du das visuell besser im Source siehst.



  • Hallo,

    danke für deine Antwort !!
    Ich habe das Kapitel nochmals nachgeschlagen jedoch nichts anderes festgestellt als das was ich hier schon geschrieben habe.

    So poste ich hier jetzt mal den ORIGINAL Quelltext der IntKlasse:

    Die Klasse IntFeld :

    class IntFeld {
      int *feld;
      int groesse;
    
    public:
      IntFeld(int g): groesse(g) {
        feld = new int[groesse];
      }
      ~IntFeld() {
        delete[](feld);
      }
    
      void setWert(int pos, int wert) {
        feld[pos]=wert;
      }
    
      int getWert(int pos) const {
        return(feld[pos]);
      }
    };
    

    dazu die main.cpp :

    int main() {
      cout << "Wie viele Werte:";
      int x;
      cin >> x;
      IntFeld f(x);
      for(int i=0; i<x; ++i) {
        cout << "Wert " << i+1 << ":";
        int w;
        cin >> w;
        f.setWert(i,w);
      }
    }
    

    Das hier ist mir eigentlich klar.
    Also setWert und getWert und das Erstellen des Feldes mit IntFeld f(x);

    So, jetzt kommt die Klasse DynIntFeld :

    class DynIntFeld {
      int *feld;
      int groesse;
      int kapazitaet;
    
    public:
      DynIntFeld(): feld(new int[2]), groesse(0), kapazitaet(2)
      {}
    
      DynIntFeld(int g): groesse(g), kapazitaet(g) {
        feld = new int[groesse];
      }
      ~DynIntFeld() {
        delete[](feld);
      }
    
      void setWert(int pos, int wert) {
        feld[pos]=wert;
      }
    
      int getWert(int pos) const {
        return(feld[pos]);
      }
    
      int size() const {
        return(groesse);
      }
    
      int capacity() const {
        return(kapazitaet);
      }
    
      void add(int wert) {
        if(groesse>=kapazitaet) {
          int* nf=new int[kapazitaet*2];
          for(int i=0; i<groesse; ++i)
            nf=feld[i];
          delete[](feld);
          feld=nf;
          kapazitaet*=2;
        }
        feld[groesse++]=wert;
      }
    };
    

    Hierbei ist mir schonmal unklar was es mit der kapazitaet auf sich hat
    und wie genau der Konstruktor funktioniert ?
    DynIntFeld(): feld(new int[2]), groesse(0), kapazitaet(2)
    {}
    Wieso denn new int[2] ??? und wieso kapazitaet(2) ?????

    dann hier :
    int* nf=new int[kapazitaet2];
    ein neuer Zeiger nf mit der kapazitaet
    2 ???
    Wieso ?
    dann hier:
    delete[](feld); // Zeiger feld löschen ???
    feld=nf; // und hier plötzlich dem eben gelöschten Zeiger etwas zuweisen ?
    Wieso geht das ?

    Hier noch die Aufgabe aus dem Buch abgeschrieben :

    Kapitel 12.6

    Schreiben Sie eine Klasse [i]DynIntFeld

    *, die wie in der Klasse IntFeld aus dem Kapitel ein int-Feld verwaltet. Sie soll zusätzlich zu den Methoden getWert und setWert, die sich auf bereits bestehende Feldelemente beziehen, eine neue Methode Add besitzen, mit der ein neue Element an die bestehenden Elemente angehängt wird. Technisch könnte das so aussehen, das Sie ein neue, größeres Array dynamisch reservieren, die Werte des alten Arrays in das neue kopieren und das alte Array löschen. Sie könnten natürlich auch intern ein vector-Objekt verwenden, davon sollten Sie jedoch wegen des Übungscharakters absehen.

    So, das ist GENAU der Text aus dem Buch.
    Da Ihr alle etwas anderes schreibt denke ich mittlerweile das ich hier irgendwas doch nicht richtig verstanden habe und auf dem Holzweg bin.
    Deswegen habe ich hier mal die komplette Aufgabe gestellt.

    Was ich nicht verstehe habe ich ja geschrieben.
    Noch eins...gehe ich erstmal richtig das

    int * kiste_pointer = new int[2];

    Kiste_pointer ist nur der Zettel auf dem steht WO die Kiste ( im SPeicher ) zu finden ist.
    Das "new int[2]" wäre dann eigentlich die physiche Kiste ??

    Matthias



  • STF-DIR schrieb:

    Wieso denn new int[2] ???

    Weil die anfängliche Kapazität 2 ist,

    und wieso kapazitaet(2) ?????

    Willkür seitens des Entwicklers. Die Klasse hat eine Kapazität, die größer ist als die Menge der Daten. Das hat den Zweck, dass das Datenarray nicht bei jedem Anfügevorgang vergrößert werden muss. Das spart Zeit, verschwendet aber dafür ein wenig Speicher.

    ein neuer Zeiger nf mit der kapazitaet*2 ???
    Wieso ?

    Wiederum Willkür. Wenn das Array schließlich vergrößert werden muss, wird gleich Platz für doppelt soviele Elemente angelegt. Grund siehe oben.

    feld=nf; // und hier plötzlich dem eben gelöschten Zeiger etwas zuweisen ?
    Wieso geht das ?

    Wieso geht das nicht? Delete löscht nicht den Zeiger, sondern das, auf das der Zeiger zeigt. Delete macht die Kiste kaputt, nicht den Zettel. Den Zettel kannst du dann neu beschriften, das macht die Zuweisung an den Zeiger.

    Technisch könnte das so aussehen, das Sie ein neue, größeres Array dynamisch reservieren, die Werte des alten Arrays in das neue kopieren und das alte Array löschen.
    ...
    So, das ist GENAU der Text aus dem Buch.

    Und das ist genau das, was in diesem Code passiert.

    int * kiste_pointer = new int[2];

    Kiste_pointer ist nur der Zettel auf dem steht WO die Kiste ( im SPeicher ) zu finden ist.
    Das "new int[2]" wäre dann eigentlich die physiche Kiste ??

    Fast, new int[2] erzeugt die Kiste und liefert dir einen Zettel.



  • STF-DIR schrieb:

    ...Hierbei ist mir schonmal unklar was es mit der kapazitaet auf sich hat...

    Ich will mich nicht groß einmischen (Du hast hier schon deutlich bessere Ratgeber als mich :D) und vielleicht ist es auch nicht neu, aber Vieles wird leichter, wenn man weiß, dass

    http://de.wikipedia.org/wiki/Kapazität schrieb:

    ... Kapazität (v. lat. capacitas „Fassungsvermögen“ ...

    ist.
    Wenn Du überall mal "Fassungsvermögen" liest, wo "Kapazität" steht, wird vielleicht einiges klarer.
    Wenn Du das schon wusstest: Vergiss mein Post und entschuldige Deine vergeudete Lebenszeit... 🙂

    Gruß,

    Simon2.



  • Hallo,

    erst mal dank an MFK und Simon2 für die Antworten.
    MFK ganz besonders für die große Mühe die sich aber wirklich gelohnt hat, denn
    da haben wir den Fehler :

    Wieso geht das nicht? Delete löscht nicht den Zeiger, sondern das, auf das der Zeiger zeigt. Delete macht die Kiste kaputt, nicht den Zettel. Den Zettel kannst du dann neu beschriften, das macht die Zuweisung an den Zeiger.

    Das ist es, ich hatte das so verstanden das ein delete[]() den Zeiger samt der Kiste löscht und danach gar nix mehr da ist.

    Ok,dann hab ich das jetzt auch endlich kapiert wieso
    feld = tempFeld; geht und das TempFeld dann icht gelöscht werden kann...klar.
    Danke...endlich...

    Das mit der kapazität .. naja, warum er das gemacht hat und einen so durcheinander bringt wird wohl sein Geheimnis bleiben 🙂

    Ok, dann danke ich euch allen nochmals !!

    Matthias



  • STF-DIR schrieb:

    ..
    Das mit der kapazität .. naja, warum er das gemacht hat und einen so durcheinander bringt wird wohl sein Geheimnis bleiben :-)...

    Nicht ganz. Immerhin muß man einmal festlegen, wie groß die Kiste am Anfang sein soll .... und um wieviel sie jeweils vergrößert werden soll.

    Gruß,

    Simon2.



  • Hallo,

    laut diesem Konstruktor :

    public: 
      DynIntFeld(): feld(new int[2]), groesse(0), kapazitaet(2) 
      {}
    

    welcher mit

    DynIntFeld f;
    

    ausferufen wird erstellt er einen IntArray mit 2 Elementen, IntArray[0] und IntArray[1] ja.

    Aber warum am Anfang gleich 2 ?

    Matthias



  • Du liest schon was hier geschrieben wird oder müssen es einfach 5 Leute stehts wiederholen ?!

    und wieso kapazitaet(2) ?????

    Willkür seitens des Entwicklers. Die Klasse hat eine Kapazität, die größer ist als die Menge der Daten. Das hat den Zweck, dass das Datenarray nicht bei jedem Anfügevorgang vergrößert werden muss. Das spart Zeit, verschwendet aber dafür ein wenig Speicher.



  • STF-DIR schrieb:

    ...
    Aber warum am Anfang gleich 2 ?

    Matthias

    Simon2 schrieb:

    ...Immerhin muß man einmal festlegen, wie groß die Kiste am Anfang sein soll ...

    ... und da er sich vermutlich gedacht hat "naja, 2 kommen meistens sowieso irgendwann rein", hat er wohl "auf Vorrat" geplant.
    So kann er sich beim ersten Add diesen Teil (also das Neuanlegen, Kopieren und Löschen) sparen:

    if(groesse>=kapazitaet) {
          int* nf=new int[kapazitaet*2];
          for(int i=0; i<groesse; ++i)
            nf[i]=feld[i];
          delete[](feld);
          feld=nf;
          kapazitaet*=2;
        }
    

    Im letzten Statement kommt die Strategie zum Ausdruck: "Je öfter ich vergrößern muß, umso mehr hole ich mir jedesmal auf Vorrat !" (beim ersten Mal 4, dann 8, dann 16 ....)
    Ist halt der Versuch,

    • weder einen Haufen überflüssigen Speichers zu reservieren (zu hohe Kapazität)
    • noch zu oft neu reservieren zu müssen (zu kleine Kapazität)

    Gruß,

    Simon2.



  • Simon2 schrieb:

    STF-DIR schrieb:

    ...
    Aber warum am Anfang gleich 2 ?

    Matthias

    Simon2 schrieb:

    ...Immerhin muß man einmal festlegen, wie groß die Kiste am Anfang sein soll ...

    ... und da er sich vermutlich gedacht hat "naja, 2 kommen meistens sowieso irgendwann rein", hat er wohl "auf Vorrat" geplant.
    So kann er sich beim ersten Add diesen Teil (also das Neuanlegen, Kopieren und Löschen) sparen:

    if(groesse>=kapazitaet) {
          int* nf=new int[kapazitaet*2];
          for(int i=0; i<groesse; ++i)
            nf[i]=feld[i];
          delete[](feld);
          feld=nf;
          kapazitaet*=2;
        }
    

    Im letzten Statement kommt die Strategie zum Ausdruck: "Je öfter ich vergrößern muß, umso mehr hole ich mir jedesmal auf Vorrat !" (beim ersten Mal 4, dann 8, dann 16 ....)
    Ist halt der Versuch,

    • weder einen Haufen überflüssigen Speichers zu reservieren (zu hohe Kapazität)
    • noch zu oft neu reservieren zu müssen (zu kleine Kapazität)

    Gruß,

    Simon2.

    Hallo,

    ja siehste, so schnell kanns gehen und man bekommt einfach mal ne erschöpfende Antwort...danke Simon2 !

    Anscheinend gibts hier ja doch Leute die verstehen das hier auch mal jemand schreibt der nicht alles gleich auf Anhieb versteht und mit anchen Sachen eben seine Probleme hat.

    Wenn ich die mal mit in meinen Flieger nehme dann verstehen sie sicher auch nicht alles auf Anhieb.

    Also danke nochmals !!

    Matthias



  • STF-DIR schrieb:

    ...danke Simon2 !...

    Gern geschehen.

    Gruß,

    Simon2.



  • STF-DIR schrieb:

    Anscheinend gibts hier ja doch Leute die verstehen das hier auch mal jemand schreibt der nicht alles gleich auf Anhieb versteht und mit anchen Sachen eben seine Probleme hat.

    Wenn das der Fall ist, dann sollte der Fragende aber schon sagen, was er an der Erklärung nicht verstanden hat, und nicht immer wieder dieselbe Frage stellen, als ob er die Antwort gar nicht mitbekommen hätte.


Anmelden zum Antworten