Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
08.03.2002, 19:44
NeW GoD



was sind den die unterschiede?

was ist besser?

hab gehört cout ist lame!

--

zum Seitenanfang zum Seitenende Profil || Suche
001
08.03.2002, 19:45
Retro



Ich habe gehört du bist lame... =)

Nee mal im ernst, du solltest nicht alles glauben was du hörst! ;) Eigentlich gibt es keine signifikanten Unterschiede...

--

shielding people from their own stupidity is an evolutionary step backwards anyway.

/* God is dead!............Nietzsche */
/* Nietzsche is dead!......God */
/* Nietzsche is God!.......The Dead */

zum Seitenanfang zum Seitenende Profil || Suche
002
08.03.2002, 20:30
Zeeke



Ich finde printf besser... ein paar Leute hier wie z.B. Arch, Prefect, etc vielleicht auch...
Andere wie Kriz und weitere finden cout besser...

Geschmäcke sind eben verschieden :)

Aber lame ist cout bestimmt nicht...

--

zum Seitenanfang zum Seitenende Profil || Suche
003
08.03.2002, 20:40
Retro



Retro wiederum bevorzugt cout und printf gemischt im selben Programm zu verwenden! :hrhr: ;)

--

shielding people from their own stupidity is an evolutionary step backwards anyway.

/* God is dead!............Nietzsche */
/* Nietzsche is dead!......God */
/* Nietzsche is God!.......The Dead */

zum Seitenanfang zum Seitenende Profil || Suche
004
08.03.2002, 23:21
apfelkorn



cout nimmt vor dem ausschreiben irgendeine ominöse überprüfung vor, printf tut das nicht, trotzdem ist cout nicht langsamer als printf. cout ist ausserdem neuer und nicht wahrscheinlich schreiben "große" c-gurus ihre Lehrbücher nicht umsonst nur noch mit cout und cin

--

zum Seitenanfang zum Seitenende Profil || Suche
005
08.03.2002, 23:23
Tron



Zitat:
apfelkorn postete
cout nimmt vor dem ausschreiben irgendeine ominöse überprüfung vor, printf tut das nicht, trotzdem ist cout nicht langsamer als printf. cout ist ausserdem neuer und nicht wahrscheinlich schreiben "große" c-gurus ihre Lehrbücher nicht umsonst nur noch mit cout und cin

was meinst du mit ominoeser pruefung?

ich bevorzuge cout, da es typensicherhiet bietet und man kann durch operator ueberladen bequem eine ausgabe fuer eigene strukte/klassen hinzufuegen.

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
006
09.03.2002, 00:44
Kriz



printf() ist eine Funktion, die einen Wert zurückgibt (afaik die Anzahl der ausgegebenen Zeichen). printf() ist zudem nicht typsicher. printf() baut auf Indikatoren auf (Formatierungsanweisungen), die durch die Funktion in eventuell mitübergebene Varaiblenwerte eingebaut werden. Im Prinzip muß der übergebene String durch einen Parser laufen, die Werte in Strings umgewandelt (sofern es sich dabei um Zahlenwerte handelt) und in den neu allozierten Hauptstring eingeflochten werden, ehe die Funktion die Ausgabe auf der stdout (Standard Output) rauswirft. Viel Aufwand für ein wenig Text...

cout ist ein Makro, das keinen Wert zurückgibt (außer eine Referenz auf sich selber für die Streamverkettung), da cout eine Methode der Klasse iostream bzw. ostream ist. Man verkettet alle Angaben, Strings und Variablenwerte durch den Linkschiebeoperator << miteinander und erspart dadurch Parsing, Stringreplacing und Alloziierungen. Durch den internen Aufbau von cout handelt es sich hierbei um einen rekursiven Datenaufruf, daß heißt das cout bei sehr sehr großen Ausgabemengen pro einzelnes cout mitunter viel Speicher belegen kann auf dem Stack.

In C hat man eh nur printf(), bei C++ die Wahl zwischen printf() oder cout.

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
007
09.03.2002, 10:00
Tron



cout ist ein makro? cout ist doch ein objekt von einer von ostream abgeleiteten klasse? fuer mich hat ein makro was mit #define zu tun, ich denke mal, das meinst du nicht. cout ist sicher keine methode einer klasse, es ist ein globales objekt.

ich denke nicht, dass cout mehr stack beim aufruf braucht als printf, in beiden faellen muesse alle auszugeben werte auf den stack gepusht werden.
bei cout ist der nachteil, dass es fuer jede ausgabe einen (wahrscheinlich virtuellen) methodenaufruf macht.

btw: hast recht, printf gibt die anzahl der ausgegebenen bytes zurueck.

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
008
09.03.2002, 11:10
apfelkorn



das wars was ich mit ominöser prüfung meinte: es bietet typensicherheit...

--

zum Seitenanfang zum Seitenende Profil || Suche
009
09.03.2002, 11:14
Prefect



Wirklich große C-Gurus schreiben ihre Programme sicher nicht mit cout und cin, die gibt's in C nämlich nicht ;P

Im Prinzip hab ich ja auch nichts gegen Klassen, aber ich hab was gegen "unnatürliche" Operator-Overloads. << und >> sehe ich nunmal als Shiftoperatoren an...

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
010
09.03.2002, 11:42
Tron



Zitat:
Prefect postete
Im Prinzip hab ich ja auch nichts gegen Klassen, aber ich hab was gegen "unnatürliche" Operator-Overloads. << und >> sehe ich nunmal als Shiftoperatoren an...

unnatuerlich ist definitionssache, mathematiker sehen << und >> als "viel kleiner als" und "viel groeser als", binaer geschoben wird in mathe mit 2 'hoch' x mit x 'element von' Z (;

wie haettest du es gemacht?
etwa cout.print("Hallo, ").print(Name).print('!'); ?

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
011
09.03.2002, 11:45
Kriz



Zitat:
Tron postete
cout ist ein makro? cout ist doch ein objekt von einer von ostream abgeleiteten klasse? fuer mich hat ein makro was mit #define zu tun, ich denke mal, das meinst du nicht. cout ist sicher keine methode einer klasse, es ist ein globales objekt.

ich denke nicht, dass cout mehr stack beim aufruf braucht als printf, in beiden faellen muesse alle auszugeben werte auf den stack gepusht werden.
bei cout ist der nachteil, dass es fuer jede ausgabe einen (wahrscheinlich virtuellen) methodenaufruf macht.

btw: hast recht, printf gibt die anzahl der ausgegebenen bytes zurueck.


1. Ja, cout ist ein Makro, da es als alleinstehendes Gebilde weder eine Funktion, weder eine Methode, weder ein Schlüsselwort oder eine Instanz darstellt. Der überdeckte Teil von cout lautet: ostream::operator<<(cout, referenz).

2. Ja, cout ist global.

3. Cout belegt pro rekursiven Verkettungsaufruf einen 32 Bit Stackplatz für den Zeiger auf die nächste Verkettung:
cout << "Blablabla = " << bla1 << ", blubblubblub = " << blub;

ist identisch mit

(((cout << "Blablabla = ") << bla1) << ", blubblubblub = ") << blub;

d.h. cout würde hier 3 mal den Zeiger für die nächste rekursive Verkettung auf den Stack kloppen = 3 * 32 Bit = 96 Bit = 12 Byte Bedarf.

4. Ein virtueller Aufruf wird wohl mit Sicherheit erfolgen, da cout sowohl bei ostream als auch beim vererbten iostream auftaucht.

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
012
09.03.2002, 11:59
Tron



Zitat:
Kriz postete
1. Ja, cout ist ein Makro, da es als alleinstehendes Gebilde weder eine Funktion, weder eine Methode, weder ein Schlüsselwort oder eine Instanz darstellt. Der überdeckte Teil von cout lautet: ostream::operator<<(cout, referenz).

cout ist doch ein ganz stinknormales globales objekt.

Zitat:
3. Cout belegt pro rekursiven Verkettungsaufruf einen 32 Bit Stackplatz für den Zeiger auf die nächste Verkettung:
cout << "Blablabla = " << bla1 << ", blubblubblub = " << blub;

ist identisch mit

(((cout << "Blablabla = ") << bla1) << ", blubblubblub = ") << blub;

d.h. cout würde hier 3 mal den Zeiger für die nächste rekursive Verkettung auf den Stack kloppen = 3 * 32 Bit = 96 Bit = 12 Byte Bedarf.

fuer die auszugeben werte braucht printf genausoviel stack wie cout .(dareuber sind wir uns wohl einig)

die referenz auf die naechste verkettung befindet sich zum selben zeitpunkt inmmer nur einmal auf dem stack, also dein bsp. in pseudo-assembler:

// es werden natuerlich immer nur adressen (referenzen) gepusht
push blub
push ", blubblubblub = "
push bla1
push "Blablabla = "
push cout
// vtable aufloesen hab ich jetzt wegelassen
call cout_fuer_char*
add esp, 4 // cout und parameter von stack entfernen
push eax // in eax wird der rueckgabewert (referenz auf cout) zurueckgegeben
call cout_fuer_bla1
add esp, 4
push eax
call cout_fuer_char*
add esp, 4
push eax
call cout_fuer_blub
add esp, 4

es befindet sich also immer nur eine referenz auf cout auf dem stack, was einen stackmehrverbrauch von 4 byte ist, da aber printf immer einen formatstring benoetigt (auch 4 byte) kommt es auf's gleiche raus.

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
013
09.03.2002, 15:05
Kriz



Ich glaube , wir reden aneinander vorbei :D

cout als Makro wird daher als Makro bezeichnet, weil es für den Benutzer u.a. als globales Objekt nicht sichtbar instanziert wird. Das geschieht bereits in iostream.h bzw. ostream.h. Makro daher, weil der Linksschiebeoperator naturgemäß ebenfallsnicht auf Nichtintegerwerte angewendet werden kann. Daher ist cout makrofiziert, damit es als Objekt an sich den Linksschiebeoperator benutzen und überladen kann. Da cout nur von ostream geerbt werden kann, ist cout naturgemäß immer global. Schließlich konnte Bjarne nicht jede Möglichkeit für cout berücksichtigen, benutzerdefinierte Klassenobjekte über den ostream ausgeben zu lassen. Daher "ostream& ostream::operator<<(ostream&, referenz&);"

Natürlich sieht man hier schon, daß cout kein Objekt im wahren Sinne ist, nur ein Makro für ostream selber. Trotzdem verhält sich cout wie ein echtes Objekt, schließlich kann man ja Späße treiben wie cout.precision() usw. Ein weiteres kleines Beispiel für die Makrofizierung von ostream ist das makro flush oder endl. Beides sind auch nur funktionale Aliase für eine ostream-Funktionalität.

Bei der Stackgeschichte würde ich das vorher mal austesten, ob der Compiler nicht erst alle vorhandenen Referenzen auf den Stack kloppt, ehe er ihn wieder abbaut und zeitgleich die stdout bearbeitet. Schließlich muß er pro cout ja 2 Zeiger pushen (einer von der nächsten cout-Referenz bzw. ostream-Referenz und einen für das auszugebende Objekt selber). Aber das ist mir ehrlich gesagt erstmal schnurz, denn wichtig ist nur zu wissen, daß cout, endl, flush und wie sie alle heißen nur makrofizierte Bezeichner für ostream sind.

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
014
07.09.2002, 16:43
Prefect



Mit fällt auf, daß ich auf einen Post hier im Thread nicht geantwortet habe.

Zitat:
Tron postete
wie haettest du es gemacht?
etwa cout.print("Hallo, ").print(Name).print('!'); ?

Ich würde von den Meistern (aka Trolltech) lernen ;)
Ich bin mir jetzt bei der genauen Syntax nicht ganz sicher, aber bei Qt kann man so etwas machen:

string = QString("C++ zealot at %0,%1!\n").arg(x).arg(y);

_Das_ ist gutes Design :)
Und etwas entsprechendes wünsche ich mir für Streams.

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
015
07.09.2002, 21:17
Tron



das ist imho ein totaler krampf!
das ist das schlechteste aus beiden moeglichkeiten gemischt!
man braucht eine parser fuer den formatierungsstring und man hat einen prozeduraufruf pro parameter.
zudem muss der formatierungsstring zwischengespeichert werden.

ich finde die stream-loesung mit << am elegantesten (und alle das-ist-der-linksschiebe-operator-fetischisten moegen sich bitte an das NUL-geraet schicken)

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
016
08.09.2002, 21:11
Prefect



Hmm.. seit wann kann man ein simples strchr(..., '%') "Parser" nennen? Aber was solls...

Die gezeigte Methode verbindet das beste aus beiden Welten, nämlich zum einen den klaren, flexiblen Formatierungsstring von printf und zum anderen die Typensicherheit von I/O-Streams. Zum anderen wird das Ergebnis in einem String und nicht einem Stream gespeichert. Das ist von Vorteil wenn man mit dem resultierenden String auch noch etwas anderes machen will (sicher, man kann auch über einen Stream in einen String schreiben, aber das benötigt zwei zusätzliche Zeilen). Zu guter letzt - und damit ist diese Methode sowohl dem klassischen printf als auch Streams überlegen - kann man die Reihenfolge der Parameter im Formatierungsstring auch vertauschen.

Der einzige potentielle Nachteil entsteht dadurch, daß für jeden arg()-Aufruf alles nach dem ersetzten %? mindestens einmal kopiert werden muß. Wenn das wirklich ein Problem sein sollte könnte man aber ein String auf Rope-Basis verwenden, es ist also nur eine Frage der Implementierung.

Letztendlich ist die gezeigte Methode aber die einzige, die wirklich universell einsetzbar ist - schon mal was von i18n gehört?

(Interessant dabei ist übrigens, daß in C# auch die von mir genannte Methode verwendet wird, wenn auch IIRC leicht abgewandelt)

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
017
09.09.2002, 00:43
Tron



Zitat:
Prefect postete
Hmm.. seit wann kann man ein simples strchr(..., '%') "Parser" nennen? Aber was solls...

ein parser ist ein parser ist ein parser ist ein parser. da gibt es nix dran zu ruetteln. der formatierungsstring wir zeichen fuer zeichen zerlegt und entsprechend verarbeitet, das ist genau das was ein parser macht.

Zitat:
(sicher, man kann auch über einen Stream in einen String schreiben, aber das benötigt zwei zusätzliche Zeilen)

wo nimmst du 2 zusaezliche zeilen her? wie waer's mit einem ganz normalen strstream?

und was ich an der formatierungsstring methode haesslich finde ist, dass man immer vor und zurueck springen muss, um es zu lesen (vorne formatstring, hinten parameter, vorne formatstring, hinten parameter, vorne formatstring, hinten parameter, ...)
bei einem stream kann man einfach von links nach rechts lesen wie in einem buch.

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
018
09.09.2002, 17:43
TheTinySteini



Dafür wird ein Stream ziemlich unübersichtlich, wenn man viele Formatierungsanweisungen drin hat...

--

TheTinySteini
Coder Poke646
"Don't Panic" - Hitchhiker's Guide to the Galaxy

zum Seitenanfang zum Seitenende Profil || Suche
019
09.09.2002, 18:33
Diablo_bth



Also ich bin da auch eher Stram-Anhänger. Im Gegensatz zur Formatierten IO sind Streams die Übersicht in Person - auch wenns mit Formatierungsanweisungen mal heftiger wird.

Was ich persönlich aber am Stream-Konzept am meisten befürworte sind die Vereinheitlichungsmöglichkeiten von Datei, Console, Klassen IO. Damit lassen sich z.B. virtuelle Dateisysteme ohne große Codeänderung durch Ableitungen vom i/ostream in Projekte einfgügen. Man kann auch relativ einfach einen Consolen-Output mit einer Logfile kombinieren.

--


Dieser Beitrag wurde am 09.09.2002 um 18:33 von Diablo_bth bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
020
16.09.2002, 09:53
gerk



Gibt es eine Möglichkeit mit cout auch 64Bit-Integer auszugeben?

Der Compiler mein nämlich, dass der Operator << mehrdeutig sei. Wahrscheinlich will er ihn als Shift-Operator interpretieren. Aber warum nur den 64er?

--

„Und da wir uns ja seit heute etwas näher gekommen sind, kann ich nur sagen: Mir hilft da immer Norther volle Lautstärke (so wie jetzt), sodass die ganzen unrasierten, Wasserpfeife rauchenden, alternativen Wichsstudenten aus ihren, aus Bananenschalen und Abfall gebastelten, Sitzkissen fliegen.“

zum Seitenanfang zum Seitenende Profil || Suche
021
16.09.2002, 11:10
Tron



Zitat:
Lag of death postete
Gibt es eine Möglichkeit mit cout auch 64Bit-Integer auszugeben?

Der Compiler mein nämlich, dass der Operator << mehrdeutig sei. Wahrscheinlich will er ihn als Shift-Operator interpretieren. Aber warum nur den 64er?

das klingt schwer nach VC++, das unterstuetzt bei streams afaik keine 64 bit zahlen. (die fehlermeldung mit 'mehrdeutig' hatte ich da auch schon)
falls die zahlen nicht zu gros sind, einfach auf int casten und gut ist.

mit MinGW klappt das ausgeben von long long per cout wunderbar.

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
022
17.09.2002, 18:25
theDon



gibt _i64toa oso damit kann man das in einen string konvertieren...

--

\o tanz den naziprau! o/

And more than ever, I hope to never fall,
Where enough is not the same it was before

zum Seitenanfang zum Seitenende Profil || Suche
023
17.09.2002, 20:44
gerk



mal ne dumme frage:

ist es schwer für c++ nen neuen datentyp zu erzeugen:

zb nen __int128? __int512?

fragt mich nicht warum, aber es täte mich interessieren.

ich kann mir vorstellen, dass man das in nem

_asm-block realisieren könnte.
da ich aber in c++ noch ziemlich grün und in asm sowieso ne lusche bin, hab ich keine ahnung, wie man sowas ansetzen würde.

--

„Und da wir uns ja seit heute etwas näher gekommen sind, kann ich nur sagen: Mir hilft da immer Norther volle Lautstärke (so wie jetzt), sodass die ganzen unrasierten, Wasserpfeife rauchenden, alternativen Wichsstudenten aus ihren, aus Bananenschalen und Abfall gebastelten, Sitzkissen fliegen.“

zum Seitenanfang zum Seitenende Profil || Suche
024
17.09.2002, 22:30
Tron



natuerlich geht das:

class __int128
{
/* implementierung mit vielen ueberladenen operatoren: do it like int does! */
};

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche