Wohin zeigt string::end ?
-
string staatsfeinde = "Sepp Xsaver Mueller Frank Peter" string::iterator i = staatsfeinde.begin(); for( ; i!=staatsfeinde.end(); ++i ) {cout << *i << endl;}Und laut C++ Reference ist das nicht nur logisch, sondern auch richig!
Äh, ja, und? Was willst Du damit sagen?
-
http://www.cplusplus.com/reference/string/string/end/
Returns an iterator referring to the next element after the last character in the string.
das heißt, dass du die speicheradresse von cstr()[letztes zeichen] eins weiter zählen lassen kannst und dann bei end() landest.
-
dgrat schrieb:
http://www.cplusplus.com/reference/string/string/end/
Returns an iterator referring to the next element after the last character in the string.
das heißt, dass du die speicheradresse von cstr()[letztes zeichen] eins weiter zählen lassen kannst und dann bei end() landest.
Es wird einen Iterator zurückgegeben, dass darfst du nicht einfach überlesen. Ein Iterator muss nicht gleich einem Zeiger sein. Wie Tachyon sagt, ist ein Iterator nur eine Abstraktion. Alles was damit ausgesagt wird: Wenn du den Iterator, welcher von
end()zurückgegeben wird, um 1 dekrementierst, dann verweist dieser auf das letzte Element.Auch noch wichtig:
std::stringarbeitet intern nicht mit Nullterminierung. Die Länge wird separat mitgeführt. Auch ist nicht gewährleistet, dass ein std::string Speicher hat, welcher an einem Stück ist. Undc_strmuss keinen Zeiger auf den internen Speicher zurückgeben, sondern hier kann auch ein eigener temporärer Puffer erstellt werden.Grüssli
-
dgrat schrieb:
http://www.cplusplus.com/reference/string/string/end/
Returns an iterator referring to the next element after the last character in the string.
das heißt, dass du die speicheradresse von cstr()[letztes zeichen] eins weiter zählen lassen kannst und dann bei end() landest.
steht so aber 100pro nicht im standard...
da end nicht dereferenzierbar sein muss, kann es hinzeigen wo es will - unter anderem kann es auch auf 0 zeigen oder einfach gar nirgendwohin zeigen... (stichwort liste und dummy-knoten)
das, was du sagst ist vll in der praxis bei vector so zu finden (und da string meistens von vector abgeleitet ist, auch bei string) - aber imho nirgendwo vorgeschrieben...bb
-
Ja und wie geht das dann mit der for schleife?
"Solange iterator ungleich irgendwo ist, inkrementiere" So kann das wohl kaum funktionieren!?

-
Klark Cent schrieb:
Ja und wie geht das dann mit der for schleife?
"Solange iterator ungleich irgendwo ist, inkrementiere" So kann das wohl kaum funktionieren!?

Nicht ungleich irgendwo sondern ungleich irgendwas. Bei 'ner Liste geht es ja auch. Und da gibt es kein "hinter dem letzten Element".
-
verstehe ich nicht.

irgendwo/irgendwas - gibts da irgendein unterschied ??
der != operator vergleicht jedesmal ob die adresse teil des strings ist oder was? Wär das nicht bisserl langsam? :p
-
der ungleich operator prüft, ob die adresse, auf die der iterator zeigt, gleich der anderen ist - dabei ist aber nicht gesagt, wo der letzte iterator hinzeigt - man nimmt bei listen gern einen dummy-knoten, bei vectoren wird es eins hinter dem letzten element sein(nicht lt. definition, sondern in der praxis) - man könnte end aber auch auf 0 zeigen lassen - nur könnte man das eben nicht so effektiv implementieren, deshalb wird es nicht so häufig gemacht - allerdings würde ich nicht behaupten wollen, dass es nie so gemacht wird - da es keinen richtigen weg gibt, gibt es auch keinen falschen....
bb
-
unskilled schrieb:
der ungleich operator prüft, ob die adresse, auf die der iterator zeigt[...]
Nein,
operator!=überprüft, ob die Iteratoren ungleich sein. Mehr nicht. Das muss nichts mit Adressen zu tun haben.
-
#include <limits> #include <iostream> #include <cassert> class WoodooIterator { public: static int const THE_WOODOO_LIMIT = 10; private: int m_value; public: WoodooIterator() : m_value(std::numeric_limits<int>::max()) { } WoodooIterator(int start) : m_value(start) { } public: WoodooIterator& operator ++() { assert(m_value <= THE_WOODOO_LIMIT); ++m_value; if(m_value > THE_WOODOO_LIMIT) { m_value = std::numeric_limits<int>::max(); } return *this; } WoodooIterator& operator --() { if(m_value > THE_WOODOO_LIMIT) { m_value = THE_WOODOO_LIMIT; } else { --m_value; } return *this; } int operator *() const { assert(m_value <= THE_WOODOO_LIMIT); return m_value; } bool operator !=(WoodooIterator const& rhs) const { return m_value != rhs.m_value; } }; int main() { WoodooIterator iter = WoodooIterator(-8); WoodooIterator end; for(; iter != end; ++iter) { std::cout << *iter << ','; } std::cout << *(--end) << std::endl; return 0; }Der Iterator ist zwar nicht ganz Standardkonform, aber er sollte aufzeigen, was wir dir probieren zu erklären. Der
endIterator hat einen völlig anderen Wert, als die anderen. Sein Wert ist nicht ein nachfolge Wert. Wenn man denendIterator dekrementiert, bekommt man allerdings trotzdem den letzten Wert.
Auch siehst du hier ganz klar nochmals, dass ein Iterator nicht gleich einer Adresse sein muss. Man kann alles in einen Iterator packen.Grüssli
-
Ein etwas kürzeres Beispiel:

std::istream_iterator<std::string> iter(std::cin); std::istream_iterator<std::string> end; for(; iter != end; ++iter) { std::cout << *iter << '\n'; }Wie soll hier ein Zeiger hinter das Ende des Streams aussehen? Wo ist denn das Ende des Streams? Ein Zeiger? Wohl kaum.
Edit:
Aber das Beispiel von Dravere zeigt gut, wie es intern aussehen kann. :pBeim String könnten intern genauso gut irgendwelche Indizes verwaltet werden, und
std::string::end()arbeitet irgendwie mitstd::string::npos. Alles mögliche ist denkbar.
-
Tachyon schrieb:
Ein etwas kürzeres Beispiel:

Da gebe ich mir extra solche Mühe ...

Aber gutes Beispiel, vielleicht helfen ja auch beide
Grüssli
-
yeah ich habs gecheckt! TYVM!

-
Das geht Dich nichts an.
(Nach reichlich zehn Jahren durfte ich endlich mal diesen Satz in einem Fachforum schreiben, yeah!)