Anfängerfragen zu C++

Gossi

Bekanntes Mitglied
Moin, hab dazu leider bei Google nichts gefunden was mich großartig weitergebracht hätte:

Wozu sind in C++:
  1. * (bedeutet glaub ich Pointer, richtig?)
  2. & (Wenn ich richtig gesehen habe eine Referenz auf den Specherblock?)
  3. ^ (Dazu hab ich garnichts gefunden)
  4. Wann benutze ich var.method() und wann var->method()?

Danke schonmal für die Hilfe
Gossi
 

kama

Top Contributor
Hi,

  1. * (bedeutet glaub ich Pointer, richtig?)
  2. & (Wenn ich richtig gesehen habe eine Referenz auf den Specherblock?)
  3. ^ (Dazu hab ich garnichts gefunden)
  4. Wann benutze ich var.method() und wann var->method()?
so jetzt muss ich mal im Gedächtnis kramen...

* ist bei der Deklaration für einen Pointer richtig, aber kann auch zu dereferenzieren eines Pointer verwendet werden, was in C++ nicht so häufig vorkommen sollte...
Code:
DasIstEineKlasse *zeiger;
zeiger = new DasIstEineKlasse; //Default Konstruktor

(*zeiger).methode(22); //Dereferenzieren (sollte man nicht!)
zeiger->methode(22); //Besser..

DasIstEineKlasse instanz; //Ruft Default Konstruktor

instanz.methode(22);
& Ist die Referenz...wird üblicherweise für Referenzen auf Instanzen bzw. Variablen benutzt.
Code:
int anton = 12;
int egon = &anton;


So und dann noch zu "^" ist eine Bit-Wise XOR Operator (Operators - C++ Documentation)

PS.: Hoffe habe keine Fehler reingeschrieben..C++ ist schon ein paar Jahre her...

Gruß
Karl Heinz Marbaise
 
G

Gast2

Gast
Moin, hab dazu leider bei Google nichts gefunden was mich großartig weitergebracht hätte:

Wozu sind in C++:
  1. * (bedeutet glaub ich Pointer, richtig?)
  2. & (Wenn ich richtig gesehen habe eine Referenz auf den Specherblock?)
  3. ^ (Dazu hab ich garnichts gefunden)
  4. Wann benutze ich var.method() und wann var->method()?

Danke schonmal für die Hilfe
Gossi

int *x deklariert einen pointer auf int
int *y = &i weist dem pointer auf integer die Adresse eines INteger namens i zu
^ sollte Bitweise XOR sein
var.method = var ist eine Instanz
var->method() Kurform von (*var).method() ==> var ist ein pointer
 
G

Gast2

Gast
Um die Verwirrung komplett zu machen:

Code:
int i = 1;
int *j = $i;
int **x = &j;

- i ist ein Integer mit Wert 1
- j ist ein pointer auf i
- x ist ein pointer auf j und somit ein Pointer auf einen Pointer auf einen Integer = int **x
 

Gossi

Bekanntes Mitglied
Ok, sehe ich das nun also richtig (was * und & angeht) =

Code:
int i = 5;
int *p = i;
int r = &i;

i++;

nun ist i = 6, p = 5 und r = 6?

und wenn ja, ist nach:

Code:
p++;
r++;

i = 7, p = 6 und r = 7?

Um die Verwirrung komplett zu machen:

Code:
int i = 1;
int *j = $i;
int **x = &j;

- i ist ein Integer mit Wert 1
- j ist ein pointer auf i
- x ist ein pointer auf j und somit ein Pointer auf einen Pointer auf einen Integer = int **x

Danke, kappesf, jez weiß ich wieder was ich an C++ nicht mochte ^^

PS:


Also wenn ich den Beitrag lese bedeutet das, dass * und ^ mehr oder weniger das gleiche sind, nur das ich mich bei * um die Speicherverwaltung kümmern muss und bei ^ nicht?
 
Zuletzt bearbeitet:
T

Tomate_Salat

Gast
Ok, sehe ich das nun also richtig (was * und & angeht) =

Code:
int i = 5;
int *p = i;
int r = &i;

i++;

nun ist i = 6, p = 5 und r = 6?


Nein. Wenn dann müsste es heißen:
Code:
int i=5;
int *p=&i; // du willst ja die Pointeradresse übergeben, deswegen das &
int r=i; 

i++;
i ist jetzt 6. Da *p auf die Adresse von i zeigt, ist das logischerweise auch 6, also das gleiche. r bleibt 5, weil du hier nur den Wert zugewießen hast.

------
mit p++ aufpassen. Damit incrementierst du nicht den Wert, sondern den Pointer . Genauer, die adresse:
Code:
int i=5;
int *p=&i;
std::cout << p << std::endl;
p++;
std::cout << p << std::endl;
ergibt z.B.:
Code:
0028FCC0
0028FCC4

----

[EDIT]
Also wenn ich den Beitrag lese bedeutet das, dass * und ^ mehr oder weniger das gleiche sind, nur das ich mich bei * um die Speicherverwaltung kümmern muss und bei ^ nicht?
Ja kann sein. Da ich nicht mit CLI arbeite, kann ich das aber nicht wirklich beurteilen.
[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
G

Gast2

Gast
Ok, sehe ich das nun also richtig (was * und & angeht) =

Code:
int i = 5;
int *p = i;
int r = &i;

i++;

nun ist i = 6, p = 5 und r = 6?

Um Gottes Willen NEIN!!!!

p zeigt so auf Adresse 5!
Ein Pointer ist intern nichts weiter als eine Zahl. Wenn du einem Pointer einn INteger zuweist (ja das geht in C++ wegen Zeiger Arithmetik!) dann zeigt der Pointer p auf die Adresse 5 wie gesagt.

Möchtest du, dass der Pointer auf i zeigt musst du den Pointer mit der Adresse von i (&i) initialisieren!

Wenn du dann im übrigen p ausgibst ist das nicht die Zahl von i sondern die Adresse! Willst du die Zahl des Integer auf die p zeigt musst du (*p) ausgeben!
 

Gossi

Bekanntes Mitglied
Nein. Wenn dann müsste es heißen:
Code:
int i=5;
int *p=&i; // du willst ja die Pointeradresse übergeben, deswegen das &
int r=i; 

i++;
i ist jetzt 6. Da *p auf die Adresse von i zeigt, ist das logischerweise auch 6, also das gleiche. r bleibt 5, weil du hier nur den Wert zugewießen hast.

Meine Güte...danke ersmtmal für die Hilfe, und ich dachte das Klassen schreiben wäre hier so beschissen (im vergleich zu Java), freue mich schon auf Morgen oder Donnerstag, da wollte ich mir Speicherverwaltung anschauen :eek:

PS:

mit p++ aufpassen. Damit incrementierst du nicht den Wert, sondern den Pointer . Genauer, die adresse:
Code:
int i=5;
int *p=&i;
std::cout << p << std::endl;
p++;
std::cout << p << std::endl;
ergibt z.B.:
Code:
0028FCC0
0028FCC4

Könnte gefährlich werden ^^

Um Gottes Willen NEIN!!!!

p zeigt so auf Adresse 5!
Ein Pointer ist intern nichts weiter als eine Zahl. Wenn du einem Pointer einn INteger zuweist (ja das geht in C++ wegen Zeiger Arithmetik!) dann zeigt der Pointer p auf die Adresse 5 wie gesagt.

Dann hätte schreiben müssen [c]int *p = &i[/c], wie Tomtae_Salat meinte, richtig?
 
Zuletzt bearbeitet:
G

Gast2

Gast
Denk auch dran, dass es keinen Garbage COllector gibt! Du musst an jeden free denken und solltest auch höllisch auf saubere Destruktoren aufpassen!

Mach am besten ein Tutorial zu Pointer Referencen und Variablen! Das ist nicht so ohne ...

Deswegen ja auch p = 5 und r = 6, aber dafür hätte ich dann schreiben müssen int *r = &i oder?

p bzw. r wäre dann immer noch der Wert der Adresse! Willst du den Pointer dereferenzieren geht das nur mit (*p) bzw (*r)

Beispiel:
Java:
int i = 5; // Imaginäre Adresse von i = 0xFF365489
int *p = &i;

Dann ist i=5
p = 0xFF365489
und (*P) = 5

[OT]Was denkst du wieso ich Java so toll finde? ^^ In c++ gibts auch keine so schöne API. Und da ich viel Platformunabhängiges Zeug schreibe durften wir erst mal selber Bibliotheken zum abstrahieren des OS schreiben.[/OT]
 
Zuletzt bearbeitet von einem Moderator:
G

Gast2

Gast
Java:
Dann hätte schreiben müssen int *p = &i , wie Tomtae_Salat meinte, richtig?

Ja, denn sonst verpasst du dem Pointer als Adresse den Wert des int. Das wird NICHT abgefangen da es wie gesagt zulässig ist einen pointer zu inkrementieren.

int *p = &i;

p z.B. 0xFF354758

nach p++; ist p dann 0xFF354759. Das gibt dann schöne Runtime Exceptions im besten Fall. Im schlimmsten ist der Speicherplatz zulässig und du zerschießt dir was auch immer da lag!
 

Gossi

Bekanntes Mitglied
Das würde auch den Bluescreen erklären den ich vor rund 5 minuten hatte, wobei, bei dem Code, dürfte er dann doch nichts verändern, oder?

Code:
int i = 23;
int *p = i;
p++;
delete p;

Oder hat er in dem Fall den Speicherblock 24 gelöscht?
 
G

Gast2

Gast
Das würde auch den Bluescreen erklären den ich vor rund 5 minuten hatte, wobei, bei dem Code, dürfte er dann doch nichts verändern, oder?

Code:
int i = 23;
int *p = i;
p++;
delete p;

Oder hat er in dem Fall den Speicherblock 24 gelöscht?

Er würde den Speicherblock 24 löschen. Das geht aber nicht, da deine Applikation da sicher keine Schreib/Leserechte hat. Dann fliegt eine Runtime Exception und die Software schmiert weg.

Schlimm ist es allerdigs wenn die falsche Adresse im Adressbereich der Applikation liegt. Dann zerschießt du dir Daten. Das passiert z.B. wenn du einen Pointer auf ein Objekt a legst. a wird woanders freigegeben und an anderer Stelle derefenzierst du a nochmal und schreibst an die Speicherstelle als gäbe es a noch. Wenn der Bereich inzwischen anderweitig genutzt wurde fliegt kein Fehler und du hast das neue Objekt korrumpiert. So Fehler zu finden ist ein Alptraum!
 

Gossi

Bekanntes Mitglied
Der komplette Code wäre gewesen:


Code:
int *p = 0;
bool proceed = true;
while(proceed) {
     int i = userEingabe();
     if(i > 123) {
          proceed = false;
          *p = i;
     }
}
cout << "Eingabe: " << p << endl;
delete p;

Wollte da mal rumtesten, auch wenn der Code und der Test idiotisch sind xD

PS: Grade nochmal ausgeführt, diesmal gabs nur ne Runtime...
 
G

Gast2

Gast
So wäre richtig:

Code:
int *p = null;
bool proceed = true;
while(proceed) {
     int i = userEingabe();
     if(i > 123) {
          proceed = false;
          *p = &i;
     }
}
if (p) {
     cout << "Eingabe: " << (*p) << endl;
    delete p;
}
 
T

Tomate_Salat

Gast
Muss man so einen Pointer:
Code:
int a=5;
int *p=&a;

wirklich mit delete freigeben? Der Speicher sollte doch nach verlassen des Scopes von [c]a[/c] wieder freigegeben werden. Afaik enstehen doch die berüchtigten Speicherlöcher, wenn man vergisst Pointer aufzuräumen, die mit
Code:
new
erstellt worden sind.
 
G

Gast2

Gast
Muss man so einen Pointer:
Code:
int a=5;
int *p=&a;

wirklich mit delete freigeben? Der Speicher sollte doch nach verlassen des Scopes von [c]a[/c] wieder freigegeben werden. Afaik enstehen doch die berüchtigten Speicherlöcher, wenn man vergisst Pointer aufzuräumen, die mit
Code:
new
erstellt worden sind.

Hast natürlich Recht. Da hab ich mich selber reingelegt ^^
Klar der Speicher wurde ja nicht durch ein new sondern durch deklaration eines Integer allokiert.
 

Gossi

Bekanntes Mitglied
Muss man so einen Pointer:
Code:
int a=5;
int *p=&a;

wirklich mit delete freigeben? Der Speicher sollte doch nach verlassen des Scopes von [c]a[/c] wieder freigegeben werden. Afaik enstehen doch die berüchtigten Speicherlöcher, wenn man vergisst Pointer aufzuräumen, die mit
Code:
new
erstellt worden sind.

Also müsste ich:

Code:
Konto *k = new Konto(1500.21, 25589642, 27050101, "Vorname", "Nachname", -500.00);

mit delete freigeben,

Code:
int i = 5;
int *p = &i;

hingegen nicht?
 
T

Tomate_Salat

Gast
Jup.
[c]int i=5;[/c]
Der Speicher wird hier freigeben, sobald der Scope verlassen wird. Wenn du aber Speicher mit einem [c]new[/c] allocierst, wird der Speicher nach verlassen des Scopes nicht freigegeben (außer du deletest es).

Was man noch beachten sollte:
Speicher freigeben heißt nicht dass der Wert gelöscht wird. Deswegen ist es z.B. in C++ notwendig, neue Variablen auch zu definieren:
[c]int i;[/c]
lässt du das so, hast du eine sehr sehr seh hohe wahrscheinlichkeit, dass in i irgendein Datenmüll drinsteht.
 
Zuletzt bearbeitet von einem Moderator:

Fu3L

Top Contributor
Und wenn du dann das erste Programm fertig hast, dein System neu aufsetzen musst und die nötige Bibliothek sich nicht mehr einbinden lässt (was in C++ ja weniger leicht ist als in Java), dann wirst du dir entnervt eine Signatur wie meine zulegen^^ ;)
 
K

KuhTee

Gast
Ach ja... die Jammerlappen mal wieder :D

Heute hab ich gelesen, dass fast die Hälfte aller Kinder nicht mehr in der Lage sind sich die Schuhe selbst zu binden. Und die Hälfte aller Java Programmier sind nicht in der Lage einfache Pointer-Arithmetik zu verstehen :)

Aber ehrlich gesagt würde ich es auch nicht empfehlen, Pointer in C++ anhand von konstruierten Beispielen zu erlernen nur um des Lernens Willen, obwohl du es ja offenbar gar nicht wirklich willst. Klingt für mich alles sehr erzwungen hier, Schule oder Ausbildung?

Ausserdem fehlen hier glaube ich andere grundlegende Kenntnisse hinsichtlich Scope von Variablen, Unterschied zwischen Stack und Heap etc. Ich denke, man sollte zuerst das verstehen, bevor man wild anfängt zu referenzieren und zu dereferenzieren.

Aber zugegeben: es dauerte auch bei mir ein Weilchen bis es "klick" macht und man das Rumhantieren mit Pointern korrekt versteht. Aber es eröffnet einem auch eine Menge Möglichkeiten. Ich zB habe sehr gern für den Gameboy Advance programmiert, und versucht da mal Java laufen zu lassen :)
 

Gossi

Bekanntes Mitglied
Ach ja... die Jammerlappen mal wieder :D

Achja, die Klugs*****er mal wieder :bae:

Heute hab ich gelesen, dass fast die Hälfte aller Kinder nicht mehr in der Lage sind sich die Schuhe selbst zu binden. Und die Hälfte aller Java Programmier sind nicht in der Lage einfache Pointer-Arithmetik zu verstehen :)

Weil die Umsetzung....sagen wir umständlich ist

Aber ehrlich gesagt würde ich es auch nicht empfehlen, Pointer in C++ anhand von konstruierten Beispielen zu erlernen nur um des Lernens Willen, obwohl du es ja offenbar gar nicht wirklich willst. Klingt für mich alles sehr erzwungen hier, Schule oder Ausbildung?

Weder noch

Ausserdem fehlen hier glaube ich andere grundlegende Kenntnisse hinsichtlich Scope von Variablen, Unterschied zwischen Stack und Heap etc. Ich denke, man sollte zuerst das verstehen, bevor man wild anfängt zu referenzieren und zu dereferenzieren.

Scope von Variablen, wenn du damit mein Beispiel von weiter oben meinst, da habe ich selber geschrieben, dass der Test schwachsinnig war, ich bin mir über den Scope von Variablen sehr wohl im klaren, da dieser sich bei C++ und Java nicht (minimal) unterscheidet

Aber zugegeben: es dauerte auch bei mir ein Weilchen bis es "klick" macht und man das Rumhantieren mit Pointern korrekt versteht. Aber es eröffnet einem auch eine Menge Möglichkeiten. Ich zB habe sehr gern für den Gameboy Advance programmiert, und versucht da mal Java laufen zu lassen :)

Geht bestimmt auch.
 
K

KuhTee

Gast
...ich bin mir über den Scope von Variablen sehr wohl im klaren, da dieser sich bei C++ und Java nicht (minimal) unterscheidet
In Kombination mit Heap/Stack gibt es da schon Unterschiede, zumindest bei den Objekten. Und auch Pointer können da, wenn das Verständnis fehlt, schnell zum Fallstrick werden. Hab zB schon häufiger gesehen, dass die Leute einfach vergessen oder es Ihnen schlicht nicht klar ist, dass der Pointer bei "call by reference" natürlich trotzdem "call by value" übergeben wird.
 
G

Gast2

Gast
Da hast du Recht. Vor allem die Möglichkeit auf eine MemoryLeakFactory :D scnr.

Da ist natürlich was wahres dran aber ich muss mal für Java als auch für C++ eine Lanze brechen:

Beide Sprache sind in ihren jeweiligen Anwenungsgebieten unschlagbar wenn es um portierbarkeit geht. Die Frage ist eben was man machen muss. Serverseitig ist es definitiv Java und auch bei einfachen Desktopapplikationen für Endkunden punktet Java einfach aufgrund der umfangreichen API.

Wenn es in Richtung System und Embedded Programmierung geht ist C++ das Maß aller Dinge (Ich schließe hier natürlich C mit ein). Nach wie vor! (Ausnahmen Smartphones) Auch hier gibt es jede Menge Frameworks, man muss nur halt mühsam alles was man braucht selber zusammentragen. Für viele Probleme wie z.B. MemoryLeaks gibts zumindest Workarounds (Boost SmartPtr z.B., auch wenn einen die nicht von der Verantwortung entbinden) und vieles mehr.

Weder das eine noch das andere ist perfekt. Sich in beidem auszukennen erzeugt aber imho sehr viele Synergien, da man eben Schwachstellen beider Philosophhien kennt und daher auch ein viel besseres Verständnis für die Probleme erhält. Vieles aus meiner C++ Arbeit und Erfahrung kann ich in Java einbringen aber umgekehrt finden viele Dinge aus Java auch in C++ Anwendung.

Also bitte nicht noch ein "Wir diskutieren mal was besser ist" Thread!
 

Marco13

Top Contributor
Ich denke auch, dass es Vorteile haben kann, sich in beidem etwas auszukennen (und bei einigen der Antworten auf die ursprünglichen Fragen lief es mir kalt den Rücken runter :autsch: ;) ). Zugegeben, sowas wie der Unterschied zwischen
int *a = &b;
und
int& x = y;
kann schon verwirrend sein. Ich denke, dass ein paar Grundkenntnisse in C/C++ (auch und gerade die Pointersachen) hilfreich sein können - zumal man sagen könnte, dass Java in dieser Hinsicht einfach "weniger" ist: Eine Referenz in Java ist eigentlich ein C++-Pointer, aber eben OHNE den syntaktischen Clutter wie *(*(&x))->foo((void**)&y) und natürlich ohne Pointerarithmetik. Dass die Begriffe "Referenz" in Java und C++ damit komplett unterschiedliche Bedeutungen haben, macht einiges vielleicht schwerer, aber ... darüber nachzudenken, und sich die Bedeutungen und Unterschiede klarzumachen, ist so eine Art Abhärtung :smoke:

Und um die Diskussion zu der Frage, welche Sprache besser ist, mal wieder etwas anzuheizen :joke: : Ich vermisse schon so Sachen wie
Java:
int *a = new int[100];
compute(a+25, 50); // Rechne auf den Mittleren (!) 50 Elementen rum
oder die "brutale Allgemeingültigkeit" eines void*-Pointers, der auf jeden beliebigen rohen Speicherblock zeigen kann. Aber man kann eben viel K***e damit machen.

Zumindest habe ich gemerkt, dass ich (nachdem ich lange praktisch nur Java programmiert habe) immer wenn ich etwas in C++ mache, einen sehr Java-haften Stil verwende...
 
G

Gast2

Gast
Zumindest habe ich gemerkt, dass ich (nachdem ich lange praktisch nur Java programmiert habe) immer wenn ich etwas in C++ mache, einen sehr Java-haften Stil verwende...

Kann ich bestätigen. Vor allem was Umsetzungen der allgemeinen Design Patterns betrifft orientiere ich mich häufig an den Java Implementationen. Mehrfachvererbung vermeide ich wenn es nur irgend geht und verwende auch in C++ Interfaces. Es gibt zwar an und für sich keine Interfaces aber eben abstrakte Klassen. Und was anderes ist ein Interface ja auch nicht ^^
 

Gossi

Bekanntes Mitglied
C++-Code (funktioniert nicht, hat wohl probleme mit int[] als Rückgabewert):

Code:
int[] getPrimZahl(int max) {
    int primzahlen[max];
    int count = 0;
    for(int i = 0; i <= max; i++) {
        if(isPrimzahl(i)) {
            primzahlen[count] = i;
            count ++;
        }
    }
    int size = sizeof( primzahlen ) / sizeof( primzahlen[0] );
    int returnArray[size];
    for(int i = 0; i <= size; i++) {
        if(primzahlen[i] != NULL && primzahlen[i] != 0) {
            returnArray[i] = primzahlen[i];
        } else {
            break;
        }
    }
    return returnArray;
}

Das gleiche in Java:

Java:
int[] getPrimZahl(int max) {
    int primzahlen[max];
    int count = 0;
    for(int i = 0; i <= max; i++) {
        if(isPrimzahl(i)) {
            primzahlen[count] = i;
            count ++;
        }
    }
    int returnArray[primzahlen.length];
    for(int i = 0; i <= primzahlen.length; i++) {
        if(primzahlen[i] != NULL && primzahlen[i] != 0) {
            returnArray[i] = primzahlen[i];
        } else {
            break;
        }
    }
    return returnArray;
}

//oder schöner:

List<Integer> getPrimZahlen(int max) {
    List<Integer> returnList = new ArrayList<Integer>();
    for(int i = 0; i <= max; i++) {
        if(isPrime(i)) {
            returnList.add(i);
        }
    }
    return returnList;
}
 
G

Gast2

Gast
Ey stimmt, dito. Ich wusste, dass es sowas in C++ gibt aber verdränge es wohl^^. Bei VC++ gibt es im übrigen interfaces: __interface (C++)

Das ist nicht in C++. Das ist proprietär von Microsoft und daher sehr mit Vorsicht zu genießen. Diese Dinger benötigen meistens ein .net framework oder die Visual Studio redistributables.

Man sollte sich wenn man auch auf Embedded targets hin entwickelt wirklich an quellofene Dinge halten (Boost, pugixml, openvpn, ...) und natürlich die basics aus der STL
 
G

Gast2

Gast
C++-Code (funktioniert nicht, hat wohl probleme mit int[] als Rückgabewert):

Code:
    int size = sizeof( primzahlen ) / sizeof( primzahlen[0] );
    int returnArray[size];

[/code]

Das geht nicht. Arrays müssen in C++ statisch initialisiert werden. Das geht nicht dynamisch!

Verwende die Containerklassen aus der STL für solche Dinge! Arrays sind böse! ;)
 
G

Gast2

Gast
Deswegen hab ich geschreiben: Bei VC++. (Kann mich irren, aber afaik steht VC++ für Visual C++ und setzt somit Visual Studio und deren mitgelieferten Compiler vorraus)

Ups überlesen! Hast natürlich Recht. Aber wer macht das schon? Ich verwende zwar VS als Editor Compiler und Debugger aber ich verwende keine VC++ Libraries zwecks portierbarkeit!
 

Fu3L

Top Contributor
Verwende die Containerklassen aus der STL für solche Dinge! Arrays sind böse!

Das finde ich persönlich so Schade an C++: Man bekommt alle möglichen Hilfsmittel (zB Arrays). Man baut was damit und denkt: "Bin ich cool, es tut". Im nächsten Moment kommt jemand mit etwas mehr Erfahrung und sagt: "Neee, so macht man das aber nicht"... Ich habn Anfängerbuch über C++ gelesen und da standen solche Sachen mit keiner Silbe erwähnt.
Deswegen bin ich zu dem Schluss gekommen, dass ich C++ erst (weiter)lerne, wenn ich wirklich mal die Zeit dazu habe, weil man einfach so viel (wenig) offensichtliches beachten muss.
 
G

Gast2

Gast
Achtung folgende Aussagen beziehen sich auf Command Line Programmierung für Multi Target (auch Embedded):

Imho ist es nur möglich guten C++ Code zu schreiben wenn man sich gut in der STL und der Boost auskennt, da viele Dinge die einfach notwendig sind anders nur durch Krücken zu erreichen sind.
Die STL gehört zum C++ Standard, wird aber auch meiner Meinung nach in Büchern viel zu wenig integriert. Um ein gutes Buch zur STL kommt man daher eigentlich nicht drum herum.
Da aber selbst die STL viel zu wenig bietet was man heute braucht empfiehlt sich die Boost. Dort ist das meiste realsiert (z.B. Smart Pointer, Serialisierung) und vieles vieles mehr.

Ein so schönes Set fertiger APIs wie in Java gibts halt nicht.
 

Marco13

Top Contributor
Das geht nicht. Arrays müssen in C++ statisch initialisiert werden. Das geht nicht dynamisch!

Verwende die Containerklassen aus der STL für solche Dinge! Arrays sind böse! ;)

Das "Problem" bei STL-Klassen ist dann, dass da Dinge wie der Zuweisungsperator und der CopyKonstruktor verwendet werden, ohne dass man es sieht (oder sich bewußt macht). Wenn man einen "großen" STL-vector<int> irgendwo zurückgibt, wird er AFAIR kopiert. Abhilfe wäre dann, einen Zeiger zurückzugeben. Aber wer gibt ihn wieder frei? (Pfuh ... da lob ich mir doch Java <3 :D )
 
G

Gast2

Gast
Das "Problem" bei STL-Klassen ist dann, dass da Dinge wie der Zuweisungsperator und der CopyKonstruktor verwendet werden, ohne dass man es sieht (oder sich bewußt macht). Wenn man einen "großen" STL-vector<int> irgendwo zurückgibt, wird er AFAIR kopiert. Abhilfe wäre dann, einen Zeiger zurückzugeben. Aber wer gibt ihn wieder frei? (Pfuh ... da lob ich mir doch Java <3 :D )

Du hast Recht. Und das lässt sich in C++ generell so zusammenfassen:
Man hat viel mehr Verantwortung zu tragen!
 

Gossi

Bekanntes Mitglied
So, hab nochmal ne frische Fuhre Anfängercode, wollte das umbedingt vorm Feierabend durch haben...

Code:
    list<int> primes = getPrimzahlen(10);
    list<int>::iterator iterPrime = primes.begin();
    while( iterPrime != primes.end() ) {
        list<int>::iterator thisone = iterPrime;
        iterPrime++;
        cout << *thisone << " ist eine Primzahl" << endl;
    }

Code:
list<int> getPrimzahlen(int max) {
    list<int> returnList;
    for(int i = 0; i <= max; i++) {
        if(isPrimzahl(i)) {
            returnList.push_back(i);
        }
    }
    return returnList;
}

Code:
bool isPrimzahl(int kandidat) {
    for(int i = 2; i < kandidat; i = i + 1) {
        if(kandidat % i == 0) {
            return false;
        }
    }
    return true;
}

Ales nicht schön, aber es funzt...
 

schalentier

Gesperrter Benutzer
Das "Problem" bei STL-Klassen ist dann, dass da Dinge wie der Zuweisungsperator und der CopyKonstruktor verwendet werden, ohne dass man es sieht (oder sich bewußt macht). Wenn man einen "großen" STL-vector<int> irgendwo zurückgibt, wird er AFAIR kopiert. Abhilfe wäre dann, einen Zeiger zurückzugeben. Aber wer gibt ihn wieder frei? (Pfuh ... da lob ich mir doch Java <3 :D )

Korrekt, das wurde inzwischen wohl auch von den C++ "Goettern" erkannt. Deswegen gibt es im C++11 Standard nun auch einen Move-Konstruktor. In Kombination mit shared_ptr und unique_ptr (beides imho inzwischen auch in der STL, wenn nicht, dann bald) kann man wohl in den meisten Faellen auf Pointer und vor allem new und delete verzichten.

@Gossi: Anstatt [c]list<int>[/c] verwende lieber [c]vector<int>[/c].
 
G

Gast2

Gast
Ich würde das nicht so pauschal sagen.

std::list ist eine doppelt verkettete Liste - Einfügen an beliebiger Stelle geht sehr schnell aber es ist aufwendiger, einen bestimmten Datensatz per Index anzusprechen.

std::vector ist ein Array mit dynamischer Länge - Elemente sind sehr schnell zu erreichen, aber einfüge oder Löschoperationen am Anfang dauern entsprechend länger.
 

schalentier

Gesperrter Benutzer
Ich würde das nicht so pauschal sagen.

std::list ist eine doppelt verkettete Liste - Einfügen an beliebiger Stelle geht sehr schnell aber es ist aufwendiger, einen bestimmten Datensatz per Index anzusprechen.

std::vector ist ein Array mit dynamischer Länge - Elemente sind sehr schnell zu erreichen, aber einfüge oder Löschoperationen am Anfang dauern entsprechend länger.

Nein, eben nicht. Ich zitier mich mal selbst: http://www.java-forum.org/plauderecke/22639-java-quiz-75.html#post868404

LinkedList (std::list) ist nur dann schneller, wenn man (ausschliesslich) am Anfang oder am Ende einfuegt. Also nur dann, wenn man einen Stack oder eine Queue verwendet. In allen anderen Faellen ist std::vector (deutlich) performanter und vor allem skalierbarer. Die Geschwindigkeit (Einfuegen und Loeschen) in einer LinkedList sinkt exponentiell mit der Groesse. Ich wuerd mir einfach von Anfang an angewoehnen, den vector zu nehmen ;-)

Wenn du dir mal bisschen (guten) C++ Quellcode ansiehst, wirst du feststellen, dass fast immer std::vector benutzt wird.
 
G

Gast2

Gast
Nein, eben nicht. Ich zitier mich mal selbst: http://www.java-forum.org/plauderecke/22639-java-quiz-75.html#post868404

LinkedList (std::list) ist nur dann schneller, wenn man (ausschliesslich) am Anfang oder am Ende einfuegt. Also nur dann, wenn man einen Stack oder eine Queue verwendet. In allen anderen Faellen ist std::vector (deutlich) performanter und vor allem skalierbarer. Die Geschwindigkeit (Einfuegen und Loeschen) in einer LinkedList sinkt exponentiell mit der Groesse. Ich wuerd mir einfach von Anfang an angewoehnen, den vector zu nehmen ;-)

Wenn du dir mal bisschen (guten) C++ Quellcode ansiehst, wirst du feststellen, dass fast immer std::vector benutzt wird.

Ich habe nur gesagt man darf es nicht pauschalisieren!
Ich verwende selber zu 95% std::vector. Einem Neuling sollte man dennoch nicht generell von einer Collection abraten, sondern die Unterschiede aufzeigen. Du hast jedoch Recht, ich hätte noch darauf hinweisen sollen, dass bis auf Ausnahmen vector die bessere Wahl ist.
 

Gossi

Bekanntes Mitglied
So, nu werden die Benutzereingaben über ne Datei gehändelt, für Verbesserungen bin ich immer offen:

Code:
int main()
{
    int max = 0;
    fstream in;
    in.open("test.txt", ios::in);
    in >> max;
    in.close();
    vector<int> primes = getPrimzahlen(max);
    vector<int>::iterator iterPrime = primes.begin();
    cout << endl << "Druecken sie eine Taste um die Primzahlen anzuzeigen" << endl;
    while(!kbhit()) {
        Sleep(100);
    }
    getch();
    fstream out;
    out.open("test.txt", ios::out);
    out << max << endl;
    while( iterPrime != primes.end() ) {
        vector<int>::iterator thisone = iterPrime;
        iterPrime++;
        out << *thisone << " ist eine Primzahl" << endl;
        cout << *thisone << " ist eine Primzahl" << endl;
    }
    out.close();
}

Die Datei:

Vorher:
Code:
20

Nachher:
Code:
20
0 ist eine Primzahl
1 ist eine Primzahl
2 ist eine Primzahl
3 ist eine Primzahl
5 ist eine Primzahl
7 ist eine Primzahl
11 ist eine Primzahl
13 ist eine Primzahl
17 ist eine Primzahl
19 ist eine Primzahl
 
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben