Welche Sprache lernen ?



  • Ich würde zu C# raten.

    Hier kannst Du (sofern Du reinschaust) die Beispiele in der MSDN leichter nutzen und kannst wesentlich mehr Informationen verarbeiten die bei Problemen angeboten werden. (Mehr Copy & Paste).

    C++ empfiehlt sich nur, wenn man sich auch die nötige Zeit für die Grundlagen nehmen möchte.

    Du kannst Dir auch durchaus mal VB.NET ansehen, man kann ja später die Objekte zwischen den .Net sprachen tauschen.

    Der Voteil von VB wären sehr umfangreiche Dokumentation und weniger komplexe Regeln. (ALso eher was in richtung: Im Buch so abgebildet, da und da draufklicken und fertig).



  • Hallo,

    danke für die Antwort.
    Ich hab mich entschlossen in aller Ruhe erst mal C++ ( nach neuen Buch ) zu lernen und dann ( wie du schon sagtest ) erst auf C# umsteigen. Später lerne ich dann .NET mit C#.

    Trotzdem Danke nochmal für die Antwort.

    Ich stell dir mal eben gleich hier noch ne kleine Frage ( hoffe das is ok ? )
    Ich bin gerade bei Dynamischer Speicherverwaltung und soll hier ein kleines Beispiel schreiben. Geht auch so weit, nur ich versteh hier was nicht so ganz.

    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 Elemeent anhängt.

    Ich hab das versucht so zu lösen:

    void CIntFeld::Add(int wert)
    {
    	_g+=1;   // Anzahl der Werte um 1 erhöhen
    	int *temp = new int[_g+1];  // Temporäres IntFeld der neuen Größe
    	temp = feld;  // Werte aus altem intFeld dem TempIntFeld zuweisen
    	temp[_g] = wert;  // Neuer Wert im letzten Feld speichern
             delete[](feld); // Altes Feld löschen
             int *feld = new int[_g]; // Feld wieder neu anlegen
             feld = temp; // Feld wird Temp zugewiesen
             delete[](temp); // Hier ist der Fehler ????
    }
    

    Ich weiß das das umständlich ist und einfacher geht, aber ich soll das hier laut der Übung eben mal so machen.
    Problem ist nur das delete[](temp); einen Fehler verursacht ??

    Ich glaub der Fehler liegt hier

    temp = feld;

    bin mir aber noch nicht sicher.

    Matthias



  • int *temp = new int[_g+1];  // Zeiger auf ein array von int speichern    
    temp = feld;  // Den Zeiger wegwerfen und den von feld nehmen
    temp[_g] = wert;  // In Feld[_g] ein Wert schreiben
    delete[](feld); // Altes Feld löschen 
             int *feld = new int[_g]; // Zeiger auf array von int 
             feld = temp; // Zeiger wegwerfen und den von temp verwenden (bereits gelöschtes altes feld)
             delete[](temp); // Noch mal gelöschten Speicher löschen
    

    Was Du jetzt mit dem Code bezweckst weiß ich nicht.
    Du kannst native Arrays nicht mit = zuweisen, du weisst so die Zeiger zu.



  • Hallo,

    was das bezwecken soll ?
    Frag mal Andr'e Willms, steht in dem Buch hier.
    Das mit den Zeigern zuweisen hab ich jetzt nachgelsen. Ghet nicht. OK.

    Aber ein Feld das mit

    int * f = new int[5];
    

    erzeugt wurde muss ich doch mit

    delete[](f);
    

    löschen können oder ?

    Matthias



  • Ja, aber lies doch mal die Kommentare die da stehen
    bzw. schau mal in Deinem Buch nach was beim Zuweisen
    der Zeiger passiert.

    Hier mal die Kurzversion:

    temp = feld;  // Werte aus altem intFeld dem TempIntFeld zuweisen
        delete[](feld); // Altes Feld löschen
        feld = temp; // Feld wird Temp zugewiesen
        delete[](temp); // Hier ist der
    

    Du löschst den gleichen Zeiger zweimal.

    In dem kurzen Codestück hast Du
    2 x Memoryleaks
    1 x Speicherzugriffsfehler
    1 x Speicher doppelt löschen

    eventuell komme noch 1 logischer Fehler hinzu:

    _g+=1;
    int *temp = new int[_g+1];



  • Hallo,

    ja, ich bin ja am lernen .. entschuldige das ich es noch nicht geschnallt habe

    Hier ist der orginal code aus dem Buch :

    *.h

    #pragma once
    
    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[i]=feld[i];
          delete[](feld);
          feld=nf;
          kapazitaet*=2;
        }
        feld[groesse++]=wert;
      }
    
    };
    

    und

    *.cpp

    #include <iostream>
    #include <vector>
    #include "DynIntFeld.h"
    
    using namespace std;
    
    int main() {
      cout << "Wie viele Werte:";
      int x;
      cin >> x;
      DynIntFeld f;
      for(int i=0; i<x; ++i) {
        cout << "Wert " << i+1 << ":";
        int w;
        cin >> w;
        f.add(w);
      }
    
      for(int i=0; i<f.size(); ++i)
        cout << "Wert " << i+1 << ": " << f.getWert(i) << endl;
    
      cout << "Feldkapazitaet: " << f.capacity() << endl;
    
      system("pause");
    
    }
    

    Ich weiß auch nicht wirklich was er da mit der kapazität macht ??
    Was ich nicht verstehe ist das laut deiner Aussage ( glaube ich ) das hier nicht richtig ist ?

    feld=nf;

    Ich denke das geht nicht ?

    Sorry aber ich habs noch nicht verstanden.
    Bei mir is es jetzt so :

    void CIntFeld::Add(int wert)
    {
    	_g++;
    	std::cout << "_g: " << _g << std::endl;
    
    	int *temp = new int[_g];
    
    	for(int x=0; x<=_g; x++)
    		temp[x] = feld[x];
    
    	feld[_g-1] = wert;
    
    	//delete[](temp);
    }
    

    Das delete[](temp); verursacht aber einen Fehler und ich weiß nicht warum ?

    Matthias



  • Erkläre mal bei jeder Zeile Deine Gedanken warum Du es so gemacht hast und erläutere was Deiner Meinung nach passieren sollte.



  • Habs gefunden ...sorry !!!

    void CIntFeld::Add(int wert)
    {
    	_g++;
    	std::cout << "_g: " << _g << std::endl;
    
    	int *temp = new int[_g];
    
    	for(int x=0; x<_g; x++)  // x<_g nicht x<=_g
    		temp[x] = feld[x];
    
    	feld[_g-1] = wert;
    
    	delete[](temp);
    }
    

    Eben ein Denkfehler.

    Trotzdem steht die frage was der da mit

    feld=nf;

    macht ?

    Matthias



  • Eine Zuweisung ?

    Ich frag mich eher was Du mit temp machst, wenn Du es eh weg wirfst



  • Hallo,

    ich glaube ich habs jetzt kapiert.
    Hab mal Kommentare geschrieben.
    Könntest Du mich nochmal berichtiogen falls ich da was falsch verstanden habe ( immernoch )

    main.cpp ( so wird das Objekt erzeugt, sind also 2 Elemente .. nur zur info )

    CIntFeld *f = new CIntFeld(2);
    
    	f->setWert(0,0);
    	f->setWert(1,1);
    
    void CIntFeld::Add(int wert)
    {
    	// Größe des Feldes um 1 erhöhen weil ein wert dazu kommt
    	_g++;
    	// Einen neuen Zeiger auf einen IntArray erstellen
    	// Größe = _g ( also 3 nach dem ersten Aufruf von Add()
    	int *temp = new int[_g];
    
    	// Jedem Wert von Temp[x] wird der gleiche wert wie Feld zugewiesen
    	// Schleife geht bis 2 !!
    	for(int x=0; x<_g; x++)
    		temp[x] = feld[x];
    
    	// Hier wird der originale Zeiger auf Feld verworfen
    	delete[](feld);
    	// ..und hier haben wir wieder einen Zeiger namens Feld der
    	// hier die Adresse von temp zugewiesen bekommt oder ?
    	feld = temp;
    
    	// Hier wird nur noch dem letzten Element der neue 
    	// Wert zugewiesen
    	feld[_g-1] = wert;
    }
    

    Ich hoffe das stimmt jetzt so ?

    Matthias



  • Ja, Du schreibst aber den neuen Wert in das vorletzte Feld des Arrays.

    Unterstriche als Anfang einer Variable solltest Du vermeiden, wirf häufig von Implmentierungen des Compilers verwendet (lasst die Goldwaage stecken ;o) .



  • Hallo,

    ok, die mit Unterstrichen sind bei mir die als private deklarierten. War so ein Einfall 🙂

    Trotzdem ( sorry sorry ) habe ich etwas nioch nicht ganz kapiert.
    Warum kann ich denn am ende der procedure den temp Zeiger nicht löschen ?
    Ich habe doch mit
    feld = temp;
    die Adresse von temp an feld zugewiesen oder versteh ich das falsch ?
    feld und temp sind doch Zeiger und Zeiger speichern Adressen.
    Dann müsste doch eigentlich temp nach der Methode unnütz sein oder ?
    Warum kann ich den nicht löschen ?

    delete[](temp);

    geht zwar ohne Fehler aber dann sind die Werte von feld leer ??
    Also in der main.cpp gibt

    for(int x=0; x<=f->getSize()-1; x++)
    	{
    		cout << "nachher " << x << " : " << f->getWert(x) << endl;
    	}
    

    blödsinnige werte aus.

    Sorry aber ich muss das genau verstehen sonst brauch ich nicht weiterlesen. Das bringt nix.

    Danke für Dein Verständnis !!
    Matthias



  • Was heißt weiterlesen ? Mal vorne Anfangen meinst.

    temp benötigst Du weil für das Vergrößern eines Arrays neuer speicher angelegt sein muss.

    temp wird in Deinem geposteten Code nicht gelöscht.

    Ohne aktuellen Code kann man Dir nix sagen.



  • Hallo,

    nein, ich meine schon WEITERLESEN, denn das ist ja das erste Kapitel wo es sich um sowas dreht.
    Sorry, aber wenn Du auch mal lesen würdest :

    .
    .
    Dann müsste doch eigentlich temp nach der Methode unnütz sein oder ?
    Warum kann ich den nicht löschen ?

    delete[](temp);

    geht zwar ohne Fehler aber dann sind die Werte von feld leer ??
    Also in der main.cpp gibt
    .
    .

    Dann würden es nicht immer soooo viele Postings werden.
    Meckern kann jeder, erklären leider nicht 😞

    Matthias



  • temp wird in Deinem geposteten Code nicht gelöscht.

    Ohne aktuellen Code kann man Dir nix sagen.

    Wenn Du lesen würdest, müsste man nich so viel mosern ;o)



  • So, hier nochmal der code wie er nicht funktioniert :

    void CIntFeld::Add(int wert) 
    { 
        // Größe des Feldes um 1 erhöhen weil ein wert dazu kommt 
        _g++; 
        // Einen neuen Zeiger auf einen IntArray erstellen 
        // Größe = _g ( also 3 nach dem ersten Aufruf von Add() 
        int *temp = new int[_g]; 
    
        // Jedem Wert von Temp[x] wird der gleiche wert wie Feld zugewiesen 
        // Schleife geht bis 2 !! 
        for(int x=0; x<_g; x++) 
            temp[x] = feld[x]; 
    
        // Hier wird der originale Zeiger auf Feld verworfen 
        delete[](feld); 
        // ..und hier haben wir wieder einen Zeiger namens Feld der 
        // hier die Adresse von temp zugewiesen bekommt oder ? 
        feld = temp; 
    
        // Hier wird nur noch dem letzten Element der neue 
        // Wert zugewiesen 
        feld[_g-1] = wert; 
    
        // HIER IST DAS WAS ICH NICHT GANZ VERSTEHE BEGIN !!!
        delete[](temp);
        // HIER IST DAS WAS ICH NICHT VERSTEHE ENDE !!!
    
    }
    


  • Auch wenn es sich jetzt hart anhört:

    Denk doch mal nach 🤡

    Hier mal die Kurzform von dem was Du machst:

    void CIntFeld::Add(int wert) 
    { 
        int *temp = new int[_g]; 
        feld = temp; 
        delete[] temp ;
    
    }
    

    Wir besorgen und speicher, kopieren die Adresse nach feld und löschen dann den angeforderten Speicher über temp.



  • Knuddlbaer schrieb:

    Auch wenn es sich jetzt hart anhört:

    Denk doch mal nach 🤡

    Hier mal die Kurzform von dem was Du machst:

    void CIntFeld::Add(int wert) 
    { 
        int *temp = new int[_g]; 
        feld = temp; 
        delete[] temp ;
    
    }
    

    Wir besorgen und speicher, kopieren die Adresse nach feld und löschen dann den angeforderten Speicher über temp.

    Das hört sich nicht hart an, hilft mir nur nicht weiter.

    Der Satz von Dir ist völlig unverständlich. Was soll ich denn damit anfangen.
    Kannst Du es nicht einfach mal ERKLÄREN oder willst Du nicht ?
    Wenn ich es durch überlegen und grübeln selber wissen würde, dann würd ich doch nicht frage ! Versthst du das nicht ?
    Wenn du das nicht versthst, das ich hier Frage um eine Antwort bzw. ERKLÄRUNG zu erhalten, dann antworte bitte nicht mehr auf meine Fragen da so die Postings immer ewig lang werden undander, die vielleicht in der Lage sind mir wirklich zu helfen hier nicht mehr reinschauen.

    Matthias



  • Na, Du willst einfach keine Energie investieren wenn es um das Programmieren geht. Du willst einfach nicht mal drüber nachdenken...

    Aber gut.

    Du legst ein neues Feld an, kopierst die Werte rein und löschst es am Ende wieder. Jeder Zugriff auf diesen Speicher ist völlig undefiniert, da darf passieren was auch immer passieren will.

    Nimm einfach mal ein Blatt Papier und spiele mal Computer, führe Deinen Quellcode aus. Male dabei ein Kasten mit dem Inhalt, fülle ihn und schau mal was passiert wenn Du den Kasten dann wegwirfst.

    Ich kann doch von hier aus nicht beurteilen was Du da im Detail nicht verstehst bzw. welche Lücken Du hast.

    void CIntFeld::Add(int wert) 
    { 
        int *temp = new int[_g]; 
        feld = temp; 
        delete[] temp ;
    
    }
    

    Zeigt deutlich, das Du den Speicher den Du besorgst einfach wegwirfst. Das Du jetzt so viele Lücken hast, das Dir das nichts sagt, kann hier keiner wissen.

    Ich könnte jetzt raten das Du nicht verstehst, was die Zuweisung von Zeigern bedeutet, aber in dem Du Dich hinstellst und heulst macht es nicht verständlicher was genau Du nicht verstehst.



  • Hallo,

    genau das scheint es aber zu sein was ich nicht so ganz verstehe.
    Das hab ich aber schon geschrieben ! ( eine Seite zuvor )

    Ich weiß auch nicht wirklich was er da mit der kapazität macht ??
    Was ich nicht verstehe ist das laut deiner Aussage ( glaube ich ) das hier nicht richtig ist ?

    feld=nf;

    Ich denke das geht nicht ?

    Sorry aber ich habs noch nicht verstanden.
    Bei mir is es jetzt so :

    void CIntFeld::Add(int wert) 
    { 
        int *temp = new int[_g]; 
        feld = temp; 
        delete[] temp ;
    
    }
    

    --> int *feld = new int[2];
    Also ich habe einen Kasten_1 mit 2 beschrifteten Kugeln drin, das soll jetzt mal feld sein. ok?

    --> int *temp = new int[3];
    Nun habe ich einen Temporären Kasten_2 mit 3 unbeschrifteten Kugeln drin ok ?

    --> temp[0] = feld[0];
    --> temp[1] = feld[1];
    ( in ner schleife ) Jetzt sind aber die 2 Kugeln in Kasten_1 ( temp ) also auch beschriftet ( mit werten gefüllt ) Ok ?

    ???? ist das jetzt das gleiche wie temp = feld; ????

    Wo hab ich denn da jetzt den Denkfehler ?

    Ich kapier das nich , sorry

    Grundlagen ---> Das sind doch die Grundlagen, ich hab doch ganz vorne angefangen, bzw bin ich ja noch ganz am Anfang des Buches.

    Der geht aber gerade auf das nicht weiter ein.

    Matthias


Anmelden zum Antworten