Was ist der richtige Weg, um über einen Vektor in C++ zu iterieren?
Betrachten Sie diese beiden Codefragmente, dieses hier funktioniert gut:
for (unsigned i=0; i < polygon.size(); i++) {
sum += polygon[i];
}
und dieses hier:
for (int i=0; i < polygon.size(); i++) {
sum += polygon[i];
}
was dazu führt Warnung: Vergleich zwischen vorzeichenbehafteten und vorzeichenlosen Ganzzahlausdrücken
.
Die unsigned
Variable sieht für mich ein wenig beängstigend aus und ich weiß, dass unsigned
Variablen gefährlich sein können, wenn sie nicht korrekt verwendet werden, also - ist das korrekt?
11 Stimmen
Die ununterzeichnete ist korrekt, weil polygon.size() vom Typ unsigned ist. Unsigned bedeutet immer positiv oder 0. Das ist alles, was es bedeutet. Wenn die Variable immer nur für Zähler verwendet wird, dann ist unsigned die richtige Wahl.
0 Stimmen
Um die Warnung bezüglich signed/unsigned zu lösen, ersetzen Sie einfach
int
durchuint
(unsigned int
) bei der Deklaration voni
.3 Stimmen
@AdamBruss
.size()
ist nicht vom Typunsigned
a.k.a.unsigned int
. Es ist vom Typstd::size_t
.1 Stimmen
@underscore_d size_t ist ein Alias für unsigned.
5 Stimmen
@AdamBruss Nein.
std::size_t
ist ein implementationsdefiniertes Typedef. Siehe den Standard.std::size_t
könnte in Ihrer aktuellen Implementierung äquivalent zuunsigned
sein, aber das ist nicht relevant. Wenn man so tut, kann dies zu nicht-portablem Code und undefiniertem Verhalten führen.0 Stimmen
@underscore_d In welcher Version von C++ entspricht unsigned nicht size_t?
1 Stimmen
@underscore_d Ich lag falsch, als ich sagte, dass unsigned äquivalent zu size_t ist. size_t beträgt unter einer 64-Bit-Build 8 Bytes, wie du festgestellt hast. Dies gilt auch für Microsoft Visual C++. Aber wenn size_t tatsächlich zwischen zwei Compilern unterschiedlich wäre, wie du es sagst, dann hättest du nicht-portablen Code einfach durch die Verwendung von size_t.
0 Stimmen
@AdamBruss ...touché! Besiegt mit meiner eigenen Logik, macht meine Schimpftirade in meinem letzten Kommentar scheinheilig :-) Ja, implementierungsdefiniertes Verhalten scheint mit Typdefinitionen wie dieser garantiert zu sein, egal ob man sie verwendet oder ignoriert. Ich würde sagen, es ist wohl besser, sie zu verwenden, wenn verfügbar, auch wenn der Nutzen rein theoretischer Natur ist - aber im Gegensatz dazu stehen andere Diskussionen, bei denen Leute argumentieren, dass
std::size_t
weitgehend sinnlos ist und alle normalen Schleifen mitint
durchgeführt werden sollten! Ich glaube, das sind keine wirklich praktischen Themen, da nur wenige Menschen jemals solch große Arrays verwenden werden.0 Stimmen
@underscore_d Ich denke, dass size_t eine notwendiges Übel ist, um eine size()-Funktion zu ermöglichen, die beispielsweise anstelle einer Funktion zurückgeben kann, die ein 4-Byte-unsigned und eine Funktion zurückgeben kann, die ein 8-Byte-unsigned zurückgibt. Ich stimme dem großen Containers zu.
1 Stimmen
@underscore_d Es handelt sich nicht um den Typ
size_t
, sondern um den Typdecltype(polygon)::size_type
.