Doppelpunkt Bedeutung in Bedingung
-
Hallo,
ich lerne gerade C++ mit dem Buch C++ programmieren (Ulrich Breymann). In einem seiner Beispiele hat er in einer for-Schleife eine Bedingung mit einem Doppelpunkt und ich finde im Buch und im Netz leider keine Antwort. Ich wäre wirklich dankbar, wenn mir jemand die Bedeutung des Doppelpunktes erläutern könnte.
for (auto zeichen : str)
Hier noch zur Vollständigkeit der komplette Code des Beispiels. Aufgabe ist es, den String als Long auszugeben.
int main() { const string str{"17462309"}; // aus Aufgabentext long int z = 0L; for (auto zeichen : str) { z *= 10; z += static_cast<int>(zeichen) - static_cast<int>('0'); } cout << "z = " << z; return 0; }
Ich hatte die Aufgabe wie folgt gelöst, was ebenfalls funktioniert. Aber würde gerne den Doppelpunkt verstehen (gibt leider keine Erklärungen im Buch zu den Lösungen):
const string Zahl = "17462309"; long int Hilfsvariable { 0L }; for (int i = 0; i < Zahl.length(); i++) { Hilfsvariable *= 10; Hilfsvariable += static_cast<int>(Zahl.at(i)) - static_cast<int>('0'); } cout << "Die Zahl ist: " << Hilfsvariable << '\n';
Vielen Dank,
Tommy
-
In der pdf-Version des Buches steht dazu auf Seite 98:
Zitat:
Auf die Zählvariable kann verzichtet werden, wenn auf alle Elemente des Containers
zugegriffen werden soll, weil dann die folgende Kurzform (englisch range based for)
verwendet werden kann:for (double wert : einVektor) { // Kopie jedes Elements cout << wert << ’\n’; }
Man kann die Schleife so lesen: Führe den Schleifenkörper für alle Objekte wert in
einVektor aus. Die lokale Variable wert ist dabei eine Kopie des jeweiligen Elements
des Containers. Die Kopie kann innerhalb der Schleife verändert werden, ohne dass sich
die Änderung auf den Container auswirkt, etwa:for (double wert : einVektor) { // veränderliche Kopie wert = 2.0 * wert; cout << wert << ’\n’; }
Ende des Zitats
-
Hallo Belli,
vielen, vielen Dank dir!
Jetzt wo du es geschrieben hast. Ist es mir auch eingefallen, dass ich es im Buch gesehen hatte. Hab es nur leider nicht mehr gefunden :(.Beste Grüße,
Tommy
-
Wo ist eigentlich der Unterschied zwischen
{ irgendwas };
und= irgendwas;
? Anscheinend ist C++ ja der Wilde Westen...
-
@EinNutzer0 hat hier jemand von Keksen gesprochen?
-
Das kommt auf den genauen Kontext (d.h. die konkreten Datentypen) an, aber lies dir mal die verschiedenen Initialisierungsmöglichkeiten durch: Initialization
Das einheitliche Initialisieren mittels
{ ... }
wird auch "uniform initialization" genannt, s.a. C++11/C++14 Uniform initialization sowie Modern C++ Features – Uniform Initialization and initializer_list.
-
@EinNutzer0 sagte in Doppelpunkt Bedeutung in Bedingung:
Wo ist eigentlich der Unterschied zwischen
{ irgendwas };
und= irgendwas;
? Anscheinend ist C++ ja der Wilde Westen...Das eine geht, das andere geht nicht:
int main() { int a; int b; int irgendwas; a = 5; b = 10; irgendwas = 20; b = irgendwas; // geht b{irgendwas}; // geht nicht }
-
@Belli: Wenn du den Code von @EinNutzer0 genauer angesehen hättest, dann würdest du wohl verstehen, daß es um die Initialisierung geht (bei
const string str{"17462309"};
bzw.const string Zahl = "17462309";
).Und ansonsten könnte man es auch genau andersrum beantworten:
int irgendwas; {irgendwas}; // geht = irgendwas; // geht nicht
-
@Th69 sagte in Doppelpunkt Bedeutung in Bedingung:
@Belli: Wenn du den Code von @EinNutzer0 genauer angesehen hättest, dann würdest du wohl verstehen, daß es um die Initialisierung geht
Die Stelle hab ich in:
@EinNutzer0 sagte in Doppelpunkt Bedeutung in Bedingung:
Wo ist eigentlich der Unterschied zwischen
{ irgendwas };
und= irgendwas;
? Anscheinend ist C++ ja der Wilde Westen...wohl übersehen ...
-
Und wofür genau wird
@Kvothe sagte in Doppelpunkt Bedeutung in Bedingung:
static_cast<int>(
benötigt? Also dieses
static_cast<int>
? Jedes Zeichen ist doch schon nur ein Codepoint. Und sogar, falls ein Zeichen keine "Zahl" sein sollte, wieso genügt nicht ein einfaches(int)
?
-
@EinNutzer0 sagte in Doppelpunkt Bedeutung in Bedingung:
Jedes Zeichen ist doch schon nur ein Codepoint.
@EinNutzer0 sagte in Doppelpunkt Bedeutung in Bedingung:
falls ein Zeichen keine "Zahl" sein sollte
wtf
-
@Swordfish sagte in Doppelpunkt Bedeutung in Bedingung:
wtf
Sehr aufschlussreich.
Hab es schon gefunden: https://stackoverflow.com/a/36310798
Der
static_cast<int>
ist an der Stelle falsch. Was ist das für ein Buch, ich dachte, der Breymann sei euer Standardwerk?
-
Was genau ist denn falsch? Würde es auch gerne verstehen, da ich es ja anscheinend aktuell falsch lerne aus dem Buch.
Danke, Grüße, Tommy
-
@Kvothe sagte in Doppelpunkt Bedeutung in Bedingung:
Was genau ist denn falsch? Würde es auch gerne verstehen, da ich es ja anscheinend aktuell falsch lerne aus dem Buch.
Danke, Grüße, TommyNichts
-
@Kvothe sagte in Doppelpunkt Bedeutung in Bedingung:
Was genau ist denn falsch? Würde es auch gerne verstehen, da ich es ja anscheinend aktuell falsch lerne aus dem Buch.
Danke, Grüße, TommyDer cast ist überflüssig, wenn der string nur Ziffern enthält, und hier sind nur schlechtgelaunte Menschen. Das ist das Problem. Aber verunstalte deinen Code ruhig.
-
@EinNutzer0, @Kvothe: Nein, der
static_cast<int>
(bzw. in C(int)
) ist nicht falsch, sondern hier nur überflüssig (der Code ist jedoch dadurch verständlicher).
Es reichtz += zeichen - '0';
Dies nennt sich "numeric promotion" (bzw. hier "integral promotion"), s.a. Implicit conversions (unter "Numeric promotions").
@EinNutzer0: Dein Link ist übrigens nicht genau genug, denn ASCII ist zwar die (heute auf den meisten Systemen) übliche Zeichenkodierung, aber vom C sowie C++ Standard nicht einzig vorgeschriebene (z.B. gibt es noch EBCDIC). Es ist aber für die Ziffern garantiert, daß diese hintereinander von
0
bis9
liegen, so daß man die Subtraktion durchführen kann (nur z.B. für Buchstaben gilt dies nicht mehr).
Man sollte nur nicht direktzeichen - 48
schreiben, da 48 nicht unbedingt der Code für0
sein muß (leider sieht man es so sehr häufig in [Anfänger-]Code).
-
Danke. So hätte ich diese Aufgabenstellung angegangen...:
#include <limits.h> #include <string> #include <iostream> unsigned long long getNumber(std::string s) { unsigned long long r = 0; for (char c : s) { int i = c - '0'; if (i < 0 || i > 9 || r > ULLONG_MAX + (r * 10 + i)) { return r; } r = r * 10 + i; } return r; } int main(int argc, char* argv[]) { using namespace std; string s = "98765432111111111101"; cout << getNumber(s) << endl; for (unsigned long long test = ULLONG_MAX - 10; test != ULLONG_MAX; test++) { cout << getNumber(to_string(test)) << endl; } for (unsigned long long test = ULLONG_MAX; test != ULLONG_MAX - 10; test--) { cout << getNumber(to_string(test)) << endl; } cout << getNumber("-123trash") << endl; return 0; }
(Also, ohne Akrobatik)
-
Hi, ich verstehe deine Lösung nur bedingt. Wenn ich sie ausführe kommt bei mir auch nicht die Nummer raus. Es fehlt hinten eine 1. Und die Punkte mit ULLONG_MAX sind mir auch noch neu. Verstehe daher die Lösung (siehe unten) nicht. Kannst du das genauer erklären was diese Tests machen?
Danke dir, Beste Grüße Tommy9876543211111111110
18446744073709551605
18446744073709551606
18446744073709551607
18446744073709551608
18446744073709551609
18446744073709551610
18446744073709551611
18446744073709551612
18446744073709551613
18446744073709551614
18446744073709551615
18446744073709551614
18446744073709551613
18446744073709551612
18446744073709551611
18446744073709551610
18446744073709551609
18446744073709551608
18446744073709551607
18446744073709551606
0
-
@Kvothe Die Ausgabe sieht bei mir auch so aus und ist intendiert.
"98765432111111111101" ist für
unsigned long long int
zu groß, die Verarbeitung sollte also an geeigneter Stelle abgebrochen werden.Die Randbereiche (
unsigned long long test = ULLONG_MAX - 10; test != ULLONG_MAX; test++
undunsigned long long test = ULLONG_MAX; test != ULLONG_MAX - 10; test--
) sollten hingegen alle die Test passieren."-123trash" ist Müll, der nicht geparst werden sollte (0 als Rückgabe oder eine Exception).
Implementierung:
r > ULLONG_MAX + (r * 10 + i)
prüft, ob ein Overflow (Underflow?) stattfinden wird, und bricht in diesem Fall die Verarbeitung ab.
-
Hi, danke dir für die Antwort. Ich versuche es noch im Detail zu verstehen :). ULLONG_MAX habe ich nachgeschaut und hat diesen Wert: 18,446,744,073,709,551,615 (0xffffffffffffffff). Du ziehst von dem Maximalwert immer 10 ab und gehst dann 10 Schritte wieder hoch und gibst die Zahlen aus, korrekt? Was genau ist der Grund dafür? Um zu zeigen was der maximal darstellbare Wert von long long ist würde doch eine Ausgabe von getNumber(to_string(ULLONG_MAX) reichen, oder wo hängt es bei mir gerade?
Sind die 10 einfach willkürlich gewählt um im Randbereich ein wenig mehr Sicherheit zu haben?Beste Grüße,
Tommy