C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

simple for Schleife will nicht arbeiten
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Andreas Schmidt
Guest





PostPosted: Fri Oct 15, 2004 9:16 am    Post subject: simple for Schleife will nicht arbeiten Reply with quote



Hallo NG,

mein Schreibtisch hat schon arg viele Bißspuren, da ich schlich nicht sehe,
was an meiner Routine falsch ist.

Folgendes: Ich habe vor ein paar Jahren in einer NG für VB Programmierung
ein Routine gefunden, die 2 Stringwerte vergleicht und einen
Ähnlichkeitsindex ausspuckt. Ich empfand sie als Besser gegenüber den
Standard Routinen zu soundex, levenshtein etc.

Diese Routine werkelt seit dem auch in einem VBA Projekt super vor sich
hin.

Nun wollte ich das ganze in C++ umsetzen (ich versuche gerade diese Sprache
zu lernen) und stoße dabei auf ein Problem.

Hier mal der Quelltext:

int CalcSimilarity(char *cS1, char *cS2)
{
unsigned int iDist = 0, iK = 0, iJ = 0, iI = 0, iLastI = 0;
int iFsum = 0, iSum = 0, iResult = 0;
bool bFound, bBreak;
unsigned int iB1, iB2;

iB1 = (int) strlen(cS1) - 1;
iB2 = (int) strlen(cS2) - 1;

for (iDist = 0; iDist <= iB1 - 1; iDist++)
{
for (iK = 0; iK <= iB1 - iDist; iK++)
{
bFound = false;
printf("JJJJJ: %in", iJ);
for (iJ = 0; iJ <= iB2 - iDist; iJ++);
{
bBreak = false;
printf("k:%i, j:%in", iK, iJ);

<--- Hier steht noch anderer Quelltext, der aber mit dem Fehler nix zu tun
hat --->

}
if (bFound)
{
iSum += iDist + iDist + 2;
} else {
iSum += iDist;
iFsum -= 1;
}
iLastI = 0;
}
printf("%i - %in", iFsum, iSum);
}

<--- Hier steht noch anderer Quelltext, der aber mit dem Fehler nix zu tun
hat --->

return iResult;
}

Die printf Anweisungen habe ich erst mal nur dazwischen geknallt, um mir
mal die Werte meiner Variablen anzuzeigen.
Und dabei bin ich auf das Problem auch aufmerksam geworden. In der dritten
for Schleife verwende ich die Variable iJ zum hochzählen ... begonnen
werden soll dabei (wie bei den anderen auch) mit 0. Nur, hat komischerweise
bereits zu beginn der Schleife iJ einen Wert, der die Länge des zu erst
übergebenen Stringwertes (welche in iB2 festgehalten wird). Vielleicht noch
eines ... es wird als cS2 immer der längere von beiden Strings übergeben.

Warum beginnt iJ nicht mit 0?? An keiner anderen Stelle wird iJ verändert.

Hoffe ihr könnt helfen!!!

Danke schon mal.

Bye
Andreas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Maximilian Hrabowski
Guest





PostPosted: Fri Oct 15, 2004 12:18 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote



Hallo,

zuerst ein paar Anmerkungen:

- Du willst const char* anstatt char* an deine Methode übergeben. Das verhindert, dass Du ausversehen Deine strings veränderst.
- Vielleicht willst Du lieber gleich auf char* verszichten und mit std::string arbeiten
- Anstatt printf verwendet man bei C++ die Ausgabe Streams. Also statt z.B. printf("%in",i) lieber std::cout << i << std::endl;
(#include
Quote:

int CalcSimilarity(char *cS1, char *cS2)
{
unsigned int iDist = 0, iK = 0, iJ = 0, iI = 0, iLastI = 0;
int iFsum = 0, iSum = 0, iResult = 0;
bool bFound, bBreak;
unsigned int iB1, iB2;

iB1 = (int) strlen(cS1) - 1;
iB2 = (int) strlen(cS2) - 1;

for (iDist = 0; iDist <= iB1 - 1; iDist++)
{
for (iK = 0; iK <= iB1 - iDist; iK++)
{
bFound = false;
printf("JJJJJ: %in", iJ);
for (iJ = 0; iJ <= iB2 - iDist; iJ++);

generell empfiehlt es sich eine variable erst dann zu definieren wenn Du sie brauchst. In Deinem Fall also

for( int iJ=0; iJ<= iB2- iDist; iJ++ )

genauso mit den anderen Variablen.

Dein Problem könnte mit dem Semikolon direkt hinter besagtem Schleifenkopf zusammen hängen. Das Semikolon bewirkt dass es sich
hierbei um eine Schleife mit leerem Anweisungsblock handelt.

Gruß,
Maxim

Quote:
{
bBreak = false;
printf("k:%i, j:%in", iK, iJ);

--- Hier steht noch anderer Quelltext, der aber mit dem Fehler nix zu tun
hat ---

}
if (bFound)
{
iSum += iDist + iDist + 2;
} else {
iSum += iDist;
iFsum -= 1;
}
iLastI = 0;
}
printf("%i - %in", iFsum, iSum);
}

--- Hier steht noch anderer Quelltext, der aber mit dem Fehler nix zu tun
hat ---

return iResult;
}

Die printf Anweisungen habe ich erst mal nur dazwischen geknallt, um mir
mal die Werte meiner Variablen anzuzeigen.
Und dabei bin ich auf das Problem auch aufmerksam geworden. In der dritten
for Schleife verwende ich die Variable iJ zum hochzählen ... begonnen
werden soll dabei (wie bei den anderen auch) mit 0. Nur, hat komischerweise
bereits zu beginn der Schleife iJ einen Wert, der die Länge des zu erst
übergebenen Stringwertes (welche in iB2 festgehalten wird). Vielleicht noch
eines ... es wird als cS2 immer der längere von beiden Strings übergeben.

Warum beginnt iJ nicht mit 0?? An keiner anderen Stelle wird iJ verändert.

Hoffe ihr könnt helfen!!!

Danke schon mal.

Bye
Andreas


--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Michael Karcher
Guest





PostPosted: Fri Oct 15, 2004 12:29 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote



Andreas Schmidt <nospaming (AT) online (DOT) de> wrote:
Quote:
for (iJ = 0; iJ <= iB2 - iDist; iJ++);
^ Oops!
{
bBreak = false;
printf("k:%i, j:%in", iK, iJ);

for Schleife verwende ich die Variable iJ zum hochzählen ... begonnen
werden soll dabei (wie bei den anderen auch) mit 0.

Das tut es auch, aber die Schleife besteht aus der Leeranweisung ";", wenn
die Schleife durchgelaufen ist, sollte iJ = iB2-iDist+1 sein, und mit dem
Wert wird dann der Block dahinter ausgeführt.

Michael Karcher

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Malte Starostik
Guest





PostPosted: Sat Oct 16, 2004 5:02 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote

Andreas Schmidt schrieb:
Quote:
Nun wollte ich das ganze in C++ umsetzen (ich versuche gerade diese Sprache
zu lernen) und stoße dabei auf ein Problem.

Dein eigentliches Problem wurde ja schon beantwortet, aufgrund des
obigen Satzes noch ein paar Anmerkungen, bitte nicht übelnehmen:

Quote:
Hier mal der Quelltext:

int CalcSimilarity(char *cS1, char *cS2)

Wie Maximilian bereits gesagt hat, sollten cS1 und cS2 auf jeden Fall
const sein, da CalcSimilarity sie nicht verändert, noch besser
std::string statt C-Strings.

Quote:
{
unsigned int iDist = 0, iK = 0, iJ = 0, iI = 0, iLastI = 0;
int iFsum = 0, iSum = 0, iResult = 0;
bool bFound, bBreak;
unsigned int iB1, iB2;

Solche Mammut-Deklarationen am Anfang einer Funktion sind erforderlich
in C. In C++ sind sie unnötig. Variablen sollten beim ersten Gebrauch
deklariert werden, dann wird auch der Hungarian-Notation-Präfix (i for
int, b vor bool etc.) überflüssig. Diese Präfixe können zwar theoretisch
helfen, da man nicht zurückscrollen muß, um zu sehen, was für eine
Variable iDist ist, sagen aber z.B. nichts über deren initalen Wert aus.
Wenn eine Variable später im Typ geändert wird, muß ihr Name an allen
Vorkommen mitgeändert werden oder es entstehen Diskrepanzen, wie hier
bereits eine existiert: iDist, iK, iJ, iI, iLastI, iB1 und iB2 sehen vom
Präfix her nach ints aus, sind aber unsigned ints! Sie sind einfach
unschön (okay, das ist Geschmackssache). Variablennamen sollten eine
Aussage über die Funktion der Variablen beinhalten, der Typ ist bereits
aus der Deklaration ersichtlich und die ist immer leicht zu finden, wenn
sie sich kurz vor dem Gebrauch befindet.

Grundsätzlich sollten einbuchstabige Variablennamen vermieden werden
(und im Grunde ist auch iJ ein solcher, das i ist ja nur bereits
erwähnter Präfix). i als Schleifenzähler ist üblich, wenn zu viele
verschachtelte Schleifen und damit j, k, ... nötig werden, ist das
oftmals ein Zeichen schlecht strukturierten Codes.

Quote:

iB1 = (int) strlen(cS1) - 1;
iB2 = (int) strlen(cS2) - 1;

Dies sind C-Style-Casts. Besserer C++-Stil wäre (inkl. Deklaration, nach
Entfernen selbiger aus den vorangehenden Zeilen):
int iB1 = int(strlen(cS1)) - 1;

iB1 und iB2 (B wie Länge? Smile sind vom Typ unsigned int. Wenn z.B.
strlen(cS1) 0 ist, ist iB1 unsigned(-1), also eine sehr hohe positive
Zahl. Da hilft auch der zwischenzeitliche Cast nichts.

Soll das letzte Zeichen wirklich ignoriert werden (- 1), oder ist das
ein Fehler beim Übersetzen von VB (dessen String-Behandlung ich nicht
kenne)?

Quote:

for (iDist = 0; iDist <= iB1 - 1; iDist++)

Warum "iDist <= iB1 - 1"? "iDist < iB1" ist leserlicher.
Statt iDist++ ist ++iDist vorzuziehen, da billiger. Macht bei int nichts
aus, bei Iteratoren z.B. schon, da die Postfix-Variante eine hier
unnötige temporäre Kopie erstellt.
Im Falle von strlen(cS1) == 0 wird diese Schleife z.B. auf einem System
mit 32-bittigen ints 4294967295 mal ausgeführt (s.o.)

Quote:
{
for (iK = 0; iK <= iB1 - iDist; iK++)
{
bFound = false;
printf("JJJJJ: %in", iJ);

Besserer C++-Stil mit Typsicherheit unter Verhinderung von Problemen mit
Diskrepanzen zwischen dem %i und dem Typ von iJ:
std::cout << "JJJJJ: " << iJ << std::endl;

Quote:
for (iJ = 0; iJ <= iB2 - iDist; iJ++);

Wie bereits in den anderen Antworten gefunden: diese for-Schleife hat
einen leeren Anweisungsteil. Dies ist übrigens ein Nachteil der
Deklaration von iJ gleich am Anfang der Funktion. Mit diesem Konstrukt:
for (unsigned int iJ = 0; iJ < iB2 - iDist; ++iJ);
wäre der Fehler sofort aufgefallen, da dann im folgenden Block iJ nicht
mehr definiert wäre.

Schön' Gruß,
Malte

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Olaf Krzikalla
Guest





PostPosted: Mon Oct 18, 2004 1:09 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote

Hi,

Andreas Schmidt schrieb:
Quote:
Die printf Anweisungen habe ich erst mal nur dazwischen geknallt, um mir
mal die Werte meiner Variablen anzuzeigen.
In Anlehnung an ein Sprichwort: den Fisch hast Du ja nun schon bekommen.

Aber eigentlich fehlt Dir die Angel - mit einem Debugger hättest Du den
Fehler schnell selbst gefunden. Deswegen: besorge Dir einen Debugger
bzw. lerne den Umgang mit dem für Deinen Compiler mitgelieferten
Debugger. Variablenwerte läßt man sich während der Entwicklung nicht
durch irgendwohin geschriebene Ausgabestatements anzeigen, man schaut
sie sich im Debugger an.

MfG
Olaf Krzikalla

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Axel Panning
Guest





PostPosted: Mon Oct 18, 2004 3:05 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote


Quote:

for (iDist = 0; iDist <= iB1 - 1; iDist++)


Warum "iDist <= iB1 - 1"? "iDist < iB1" ist leserlicher.
Statt iDist++ ist ++iDist vorzuziehen, da billiger. Macht bei int nichts
aus, bei Iteratoren z.B. schon, da die Postfix-Variante eine hier
unnötige temporäre Kopie erstellt.

verstehe ich das richtig?

vector
//fülle mit irgendwas

for ( it;it!=myvector.end();++it){
//irgendwas
}

ist schneller als

for ( it;it!=myvector.end();it++){
//irgendwas
}

wie handle ich dann das erste element ab?
it=myvector.begin()-1; dürfte wohl blödsinn ergeben oder?

gruß axel

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Martin Krause
Guest





PostPosted: Mon Oct 18, 2004 6:01 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote

Hllo Axel,

Axel Panning <axel (AT) harnackstrasse (DOT) de> wrote:

Quote:


for (iDist = 0; iDist <= iB1 - 1; iDist++)


Warum "iDist <= iB1 - 1"? "iDist < iB1" ist leserlicher.
Statt iDist++ ist ++iDist vorzuziehen, da billiger. Macht bei int nichts
aus, bei Iteratoren z.B. schon, da die Postfix-Variante eine hier
unnötige temporäre Kopie erstellt.

verstehe ich das richtig?

vector vector<anyclass

//fülle mit irgendwas

for ( it;it!=myvector.end();++it){
for ( vector

it!=myvector.end();++it){
Quote:
//irgendwas
}

ist schneller als

for ( it;it!=myvector.end();it++){
//irgendwas
}

Ja, die formale Syntax lautet

for (Initial-Value, Condition, Progress)

und der Prefix-operator ++ braucht keine Kopie des Iterators.

Quote:
wie handle ich dann das erste element ab?
Das ist der initial-Value für den ersten Durchlauf


Quote:
it=myvector.begin()-1; dürfte wohl blödsinn ergeben oder?

Genau.

Gruß
Martin
--
------------------- Martin Krause ----------------------------
email: [email]mkr-dr350 (AT) telda (DOT) net[/email] | DRZ 400S


--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Maeder
Guest





PostPosted: Mon Oct 18, 2004 6:31 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote

Axel Panning <axel (AT) harnackstrasse (DOT) de> writes:

Quote:
verstehe ich das richtig?

vector<anyclass>::iterator it=myvector.begin();

//fülle mit irgendwas

for ( it;it!=myvector.end();++it){
//irgendwas
}

ist schneller als

for ( it;it!=myvector.end();it++){
//irgendwas
}

Das Potential ist da, aber ich würde nachmessen.


Quote:
wie handle ich dann das erste element ab?

*it


Quote:
it=myvector.begin()-1; dürfte wohl blödsinn ergeben oder?

Das hat undefiniertes Verhalten - aber warum meinst Du, dass Du das brauchst?

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Mang
Guest





PostPosted: Mon Oct 18, 2004 6:57 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote


"Martin Krause" <mkr-dr350 (AT) telda (DOT) net> schrieb im Newsbeitrag
news:5o08n09uu1r235jnjpkdo4u9907k1aajjk (AT) news (DOT) dirtbike.dns2go.com...
Quote:
Hllo Axel,

Axel Panning <axel (AT) harnackstrasse (DOT) de> wrote:



for (iDist = 0; iDist <= iB1 - 1; iDist++)


Warum "iDist <= iB1 - 1"? "iDist < iB1" ist leserlicher.
Statt iDist++ ist ++iDist vorzuziehen, da billiger. Macht bei int
nichts
aus, bei Iteratoren z.B. schon, da die Postfix-Variante eine hier
unnötige temporäre Kopie erstellt.

verstehe ich das richtig?

vector vector<anyclass

//fülle mit irgendwas

for ( it;it!=myvector.end();++it){
for ( vector it!=myvector.end ++it){
//irgendwas
}

Da hast Du 2 Klammern nach 'end' und ein Semikolon vergessen.


Quote:

ist schneller als

for ( it;it!=myvector.end();it++){
//irgendwas
}

Ja,

Noch schneller ist es, den End-Iterator zu speichern. Dann muß nicht jedes
mal die Funktion aufgerufen werden und der Iterator kopiert werden (Hängt
natürlich vom Typ des iterators und den Optimierungs-möglichkeiten des
Compilers ab).
Außerdem kann man wieder die Funktionsstil-Initialisierung verwenden, was
bei komplexen iterator-Klassen und dummen Compilern eine weitere Kopie
spart:

for (std::vector<anyclass>::iterator It(myvector.begin()),
End(myvector.end());
It != End; ++It)
{
// blah
}


Natürlich sollte man, falls möglich, const_iterator verwenden.


Thomas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Olaf Krzikalla
Guest





PostPosted: Tue Oct 19, 2004 10:29 am    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote

Hi,

Axel Panning schrieb:
Quote:
verstehe ich das richtig?

vector<anyclass>::iterator it=myvector.begin();

//fülle mit irgendwas

for ( it;it!=myvector.end();++it){
//irgendwas
}
Wenn ich das richtig verstehe, willst Du den begin-Iterator in 'it'

speichern und danach myvector mit 'irgendwas' 'füllen'. Dieses Vorgehen
ist falsch, da der Iterator danach ungültig ist. Erst nach erfolgter
vector-'Befüllung' kannst Du Dir den Iterator holen.

Quote:
ist schneller als

for ( it;it!=myvector.end();it++){
//irgendwas
}

wie handle ich dann das erste element ab?
it=myvector.begin()-1; dürfte wohl blödsinn ergeben oder?
Hier scheint ein fundamentales Mißverständnis über die Arbeitsweise der

prä- und postinkrement-Operatoren vorzuliegen. Das Inkrementieren
passiert nicht etwa einmal am Anfang der Schleife und einmal am Ende
selbiger (so erscheint mir Deine Frage), sondern nur am Anfang bzw. am
Ende des (Teil-)Ausdrucks, in dem der Inkrement-Operator vorkommt.


MfG
Olaf Krzikalla

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Andreas Schmidt
Guest





PostPosted: Tue Oct 19, 2004 2:09 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote

Quote:

Grundsätzlich sollten einbuchstabige Variablennamen vermieden werden
(und im Grunde ist auch iJ ein solcher, das i ist ja nur bereits
erwähnter Präfix). i als Schleifenzähler ist üblich, wenn zu viele
verschachtelte Schleifen und damit j, k, ... nötig werden, ist das
oftmals ein Zeichen schlecht strukturierten Codes.

Nun, das mit den einbuchstabige Variablennamen ist eine Angewohnheit aus
VB. Das ich das i davor gesetzt habe, verdanke ich auch nur einem Buch :-)

Quote:

iB1 = (int) strlen(cS1) - 1;
iB2 = (int) strlen(cS2) - 1;

Dies sind C-Style-Casts. Besserer C++-Stil wäre (inkl. Deklaration, nach
Entfernen selbiger aus den vorangehenden Zeilen):
int iB1 = int(strlen(cS1)) - 1;

OK, setzte ich um ... Danke!!

Quote:
iB1 und iB2 (B wie Länge? Smile sind vom Typ unsigned int. Wenn z.B.

Smile ... B wie Länge kommt schon hin Wink. Ich habe die Variablennamen
weitestgehend übernommen aus der VB Routine. Sollte Sie funktionieren,
werde ich wahrscheinlich eh mal alles ordentlich machen (JaJa ... ist
Doppelarbeit ... ich weiß)

Quote:
strlen(cS1) 0 ist, ist iB1 unsigned(-1), also eine sehr hohe positive
Zahl. Da hilft auch der zwischenzeitliche Cast nichts.

Soll das letzte Zeichen wirklich ignoriert werden (- 1), oder ist das
ein Fehler beim Übersetzen von VB (dessen String-Behandlung ich nicht
kenne)?


Nun, das strlen brachte mir grundsätzlich eine Längenangabe die +1 der
originalen Anzahl an Buchstaben entspricht. Wenn ich das richtig verstanden
habe, liegt das an als Abschluss eines Strings im Speicher ... richtig??
Das ist ein Zeichen, was ich aber nicht auswerten will ... wobei es ja
evtl. auch keine große Rolle spielt.
Zeichenketten mit einer Länge Null werden der Routine nicht übergeben, das
checkt das Hauptscript vorher ab.

Quote:
Wie bereits in den anderen Antworten gefunden: diese for-Schleife hat
einen leeren Anweisungsteil. Dies ist übrigens ein Nachteil der
Deklaration von iJ gleich am Anfang der Funktion. Mit diesem Konstrukt:
for (unsigned int iJ = 0; iJ < iB2 - iDist; ++iJ);
wäre der Fehler sofort aufgefallen, da dann im folgenden Block iJ nicht
mehr definiert wäre.

Ah ja ... OK, danke

Quote:

Schön' Gruß,
Malte

Vielen Dank!!

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Andreas Schmidt
Guest





PostPosted: Tue Oct 19, 2004 2:12 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote

Quote:
In Anlehnung an ein Sprichwort: den Fisch hast Du ja nun schon bekommen.
Aber eigentlich fehlt Dir die Angel - mit einem Debugger hättest Du den
Fehler schnell selbst gefunden. Deswegen: besorge Dir einen Debugger
bzw. lerne den Umgang mit dem für Deinen Compiler mitgelieferten
Debugger. Variablenwerte läßt man sich während der Entwicklung nicht
durch irgendwohin geschriebene Ausgabestatements anzeigen, man schaut
sie sich im Debugger an.

Ja, Du hast Recht ... ist ne gaaanz schlechte Angewohnheit. Muss ich mir
abgewöhnen, wo das Programmierwergzeug doch sowas mitbringt.
Quote:

MfG
Olaf Krzikalla

Andreas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Andreas Schmidt
Guest





PostPosted: Tue Oct 19, 2004 2:12 pm    Post subject: Re: simple for Schleife will nicht arbeiten Reply with quote

SUPPER !!! :-)

Sorry für die späte Reaktion, aber hatte aber leider keine Zeit in die NG
zu schauen ... aber jetzt!!

Und daher:

Vielen Vielen Dank an alle!! Nicht nur das ich dadurch festgestellt habe,
das ich Blind bin (hab das Semikolon echt nicht gesehen, so oft ich die
Routine auch durchgeschaut habe), bin ich auch durch Eure Tipps gleich
schlauer. Werde mich mal mit std::string und Co beschäftigen.

Was die Definition der Variablen angeht, empfinde ich es an sich
übersichtlicher, alles am Anfang zu definieren, aber ich werd es mal
umsetzen und schauen, ob ich damit klar komme Smile
Ansonsten schaue ich mir natürlich auch die vielen anderen Infos mal an.

Bye
Andreas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Jörg Barfurth
Guest





PostPosted: Wed Oct 20, 2004 9:01 am    Post subject: Copy- oder Direct Initialization [Was: simple for Schleife w Reply with quote

Hi Thomas,

Du - und manch anderer in dieser Gruppe - propagieren bei jeder sich
bietenden Gelegenheit die 'Funktionsstil-' (oder Direkt-)
Initialisierung. Das finde ich in dieser Allgemeinheit nicht
gerechtfertigt. Kopierinitialisierung ist ein vollwertiger Bestandteil
von C++. Anfängern, deren Kurs, Buch oder Arbeit oft abweichende
Vorgaben macht, solche Änderungen vorzuschlagen, auch wenn diese keinen
Unterschied machen, kann sogar Verwirung stiften.

Thomas Mang schrieb:
Quote:
Außerdem kann man wieder die Funktionsstil-Initialisierung verwenden, was
bei komplexen iterator-Klassen und dummen Compilern eine weitere Kopie
spart:


Kennst du einen so dummen Compiler? Alle Compiler die ich kenne sparen
sich diese Kopie immer - i.d.R. sogar wenn Optimierungen ausgeschaltet
sind. Im Gegenteil findet man eher mal den Fehler, dass hier ein
fehlender Kopierkonstruktor unbemerkt bleibt.

Nach derselben Logik müsste man statt

void f( Something const & );
f( Something() );

besser

void f( Something const & );

{
Something arg;
f( arg );
}

schreiben, da im ersten Fall ein hirnverbrannter Compiler noch eine
Kopie anlegen darf.

Wenn man dies Argument also ignoriert, dann bin ich keineswegs
überzeugt, dass 'Funktionsstil'-Initialisierung grundsätzlich besser als
Kopierinitialisierung ist.

Quote:
for (std::vector<anyclass>::iterator It(myvector.begin()),
End(myvector.end());
It != End; ++It)
{
// blah
}


Ein wesentlicher Vorteil der Kopierinitialisierung ist dass sie in
vielen Fällen zu besser lesbarem Code führt. Gerade das Beispiel einer
for-Schleife scheint mir da typisch.

Betrachten wir

for (Typ some(foo()),more(bar());some.test(more);baz(some),baz(more))

und

for (Typ some=foo(),more=bar();some.test(more);baz(some),baz(more))

Wenigstens für mich ist das zweite deutlich leichter lesbar.

Folgende Punkte tragen dazu bei, dass Kopierinitialisierung generell
lesbarer ist:
- Die visuelle Unterscheidung von Deklarationen und Funktionsaufrufen.
- Bei for-Schleifen: Vereinfachung des Klammerwaldes.
- Visuelle Ähnlichkeit zu Zuweisungen. [+]
- Analogie zu anderen, visuell ähnlichen Sprachen (Java, C)

[+] Natürlich ist es oft wichtig zwischen Zuweisungen und
Initialisierungen zu unterscheiden. Häufiger ist es aber m.E. so, dass
dieser Unterschied für das Verständnis des Programms auf höherer Ebene
(Algorithmus) unwesentlich ist.

Zur Lesbarkeit kommt noch hinzu, dass Kopierinitialisierung
- die Möglichkeit ungewollter impliziter Konvertierungen verringert.
(wenn auch nur geringfügig)
- nicht mit einer Funktionsdeklaration verwechselt werden kann.

Insgesamt reichen diese Vorteile für mich so weit, dass ich gelegentlich
sogar lieber
Typ t = Typ(...);
statt
Typ t(...);
verwende, wenn
Typ t = ...;
nicht möglich ist.

Ubrigens gibt es auch einen Fall, in dem nur die
Kopierinitialisierungssyntax möglich ist: Initialisierung in einer
/condition/. Also z.B.:

while (int selection=select_something()) ...;
if (T* t = dynamic_cast<T*>(p)) ...;
for (int index=0; X* x=getX(index); ++index) ...;

aber nicht

while (int selection(select_something())) ...;
if (T* t(dynamic_cast<T*>(p))) ...;
for (int index(0); X* obj(getX(index)); ++index) ...;

Gruss, Jörg

P.S.: Natürlich verwende ich auch oft Direktinitialisierung ...

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Mang
Guest





PostPosted: Wed Oct 20, 2004 8:53 pm    Post subject: Re: Copy- oder Direct Initialization [Was: simple for Schlei Reply with quote


"Jörg Barfurth" <jub.exp-aug04 (AT) gmx (DOT) net> schrieb im Newsbeitrag
news:cl59i8$r0r$1 (AT) news1 (DOT) ewetel.de...
Quote:
Hi Thomas,

Du - und manch anderer in dieser Gruppe - propagieren bei jeder sich
bietenden Gelegenheit die 'Funktionsstil-' (oder Direkt-)
Initialisierung. Das finde ich in dieser Allgemeinheit nicht
gerechtfertigt. Kopierinitialisierung ist ein vollwertiger Bestandteil
von C++. Anfängern, deren Kurs, Buch oder Arbeit oft abweichende
Vorgaben macht, solche Änderungen vorzuschlagen, auch wenn diese keinen
Unterschied machen, kann sogar Verwirung stiften.


Natürlich kann es in gewissem Maße Verwirrung stiften. Das betrifft aber die

typ T = 1;

Initialisierung genauso. Mach mal eine Umfrage, wieviele sich da einen
Aufruf an operator= erwarten.


Quote:

Wenn man dies Argument also ignoriert, dann bin ich keineswegs
überzeugt, dass 'Funktionsstil'-Initialisierung grundsätzlich besser als
Kopierinitialisierung ist.

for (std::vector<anyclass>::iterator It(myvector.begin()),
End(myvector.end());
It != End; ++It)
{
// blah
}


Ein wesentlicher Vorteil der Kopierinitialisierung ist dass sie in
vielen Fällen zu besser lesbarem Code führt. Gerade das Beispiel einer
for-Schleife scheint mir da typisch.

Betrachten wir

for (Typ some(foo()),more(bar());some.test(more);baz(some),baz(more))

und

for (Typ some=foo(),more=bar();some.test(more);baz(some),baz(more))

Wenigstens für mich ist das zweite deutlich leichter lesbar.


Das liegt wohl sehr im Auge des Betrachters. Für mich ist beides gleich gut
lesbar - was natürlich nicht darauf schließen läßt, daß andere die eine oder
andere Art besser lesbarer finden.


Quote:

Folgende Punkte tragen dazu bei, dass Kopierinitialisierung generell
lesbarer ist:
- Die visuelle Unterscheidung von Deklarationen und Funktionsaufrufen.
- Bei for-Schleifen: Vereinfachung des Klammerwaldes.
- Visuelle Ähnlichkeit zu Zuweisungen. [+]
- Analogie zu anderen, visuell ähnlichen Sprachen (Java, C)

[+] Natürlich ist es oft wichtig zwischen Zuweisungen und
Initialisierungen zu unterscheiden. Häufiger ist es aber m.E. so, dass
dieser Unterschied für das Verständnis des Programms auf höherer Ebene
(Algorithmus) unwesentlich ist.

Zur Lesbarkeit kommt noch hinzu, dass Kopierinitialisierung
- die Möglichkeit ungewollter impliziter Konvertierungen verringert.
(wenn auch nur geringfügig)
- nicht mit einer Funktionsdeklaration verwechselt werden kann.


Insgesamt reichen diese Vorteile für mich so weit, dass ich gelegentlich
sogar lieber
Typ t = Typ(...);
statt
Typ t(...);
verwende, wenn
Typ t = ...;
nicht möglich ist.

Das setzt aber einen verfügbaren Kopierkonstruktor voraus.


Quote:

Ubrigens gibt es auch einen Fall, in dem nur die
Kopierinitialisierungssyntax möglich ist: Initialisierung in einer
/condition/. Also z.B.:

while (int selection=select_something()) ...;
if (T* t = dynamic_cast<T*>(p)) ...;
for (int index=0; X* x=getX(index); ++index) ...;

aber nicht

while (int selection(select_something())) ...;
if (T* t(dynamic_cast<T*>(p))) ...;
for (int index(0); X* obj(getX(index)); ++index) ...;

Das ist in der Tat ein Problem, und meiner Ansicht nach ein "bug" in der
Syntax.

Das gleiche betrifft auch arrays - die fressen auch nur die
Kopierinitialisierung.


Du darfst aber nicht vergessen, daß es semantische Unterschiede zw. den
beiden Initialisierungen gibt:

So muß etwa bei Kopierinitialisierung ein Kopierkonstruktor zugänglich sein
(ist z.B. nicht bei der iostream-Bibliothek gegeben).
Des weiteren schreibt man gerne:

typ T = 1;

statt

typ T = typ(1);

was wiederum eine Rolle spielt, falls der Konstruktor, der ein int (oder
einen Typ der von einem int umwandelbar ist) als Parameter erhält,
'explicit' ist. (Was zumindest bei mir praktisch alle
Ein-Argument-Konstruktoren sind).

Schließlich spielt die Anzahl an möglichen impliziten Umwandlungen eine
Rolle (Wir hatten hier unlängst ein Beispiel, wo die Kopierinitialisierung
nicht funktionierte, die Funktionsstilinitialisierung schon - einfach weil
die Kopierinitialisierung 2 implizite Umwandlungen gebraucht hätte).

Und zuletzt kannst Du in der Konstruktor-Initialisierungsliste nur die
Funktionsstilinitialisierung anwenden. Und die verwendest Du doch auch,
oder?


Aus Gründen der Symmetrie wegen scheint mir die Funktionsstil -
Initialisierung die vernünftigere zu sein.


Natürlich könnnten wir über den besser lesbaren Stil unendliche Diskussionen
führen, aber das würde wohl zu keinem Ziel führen.


Thomas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.