Ich verstehe das Adjektiv "technisch" als Sprachverhalten / Macken und Compiler-Nebenwirkungen wie die Leistung des generierten Codes.
Zu diesem Zweck lautet die Antwort: nein (*). Das (*) lautet "Bitte konsultieren Sie Ihr Prozessorhandbuch". Wenn Sie mit einem Edge-Case-RISC- oder FPGA-System arbeiten, müssen Sie möglicherweise überprüfen, welche Anweisungen generiert werden und was sie kosten. Aber wenn Sie so ziemlich jede herkömmliche moderne Architektur verwendet wird , dann gibt es keine signifikante Prozessorebene Kostendifferenz zwischen lt
, eq
, ne
und gt
.
Wenn Sie eine Kante Fall verwenden könnten Sie feststellen , dass !=
erfordert drei Operationen ( cmp
, not
, beq
) vs zwei ( cmp
, blt xtr myo
). Wieder RTM in diesem Fall.
Die Gründe sind größtenteils defensiv / härtend, insbesondere wenn mit Zeigern oder komplexen Schleifen gearbeitet wird. Erwägen
// highly contrived example
size_t count_chars(char c, const char* str, size_t len) {
size_t count = 0;
bool quoted = false;
const char* p = str;
while (p != str + len) {
if (*p == '"') {
quote = !quote;
++p;
}
if (*(p++) == c && !quoted)
++count;
}
return count;
}
Ein weniger ausgeklügeltes Beispiel wäre, wenn Sie Rückgabewerte verwenden, um Inkremente durchzuführen und Daten von einem Benutzer zu akzeptieren:
#include <iostream>
int main() {
size_t len = 5, step;
for (size_t i = 0; i != len; ) {
std::cout << "i = " << i << ", step? " << std::flush;
std::cin >> step;
i += step; // here for emphasis, it could go in the for(;;)
}
}
Versuchen Sie dies und geben Sie die Werte 1, 2, 10, 999 ein.
Sie könnten dies verhindern:
#include <iostream>
int main() {
size_t len = 5, step;
for (size_t i = 0; i != len; ) {
std::cout << "i = " << i << ", step? " << std::flush;
std::cin >> step;
if (step + i > len)
std::cout << "too much.\n";
else
i += step;
}
}
Aber was Sie wahrscheinlich wollten, war
#include <iostream>
int main() {
size_t len = 5, step;
for (size_t i = 0; i < len; ) {
std::cout << "i = " << i << ", step? " << std::flush;
std::cin >> step;
i += step;
}
}
Es gibt auch eine gewisse konventionelle Tendenz <
, da das Bestellen in Standardcontainern häufig davon abhängt operator<
, dass beispielsweise das Hashing in mehreren STL-Containern die Gleichheit bestimmt, indem es sagt
if (lhs < rhs) // T.operator <
lessthan
else if (rhs < lhs) // T.operator < again
greaterthan
else
equal
Wenn lhs
und rhs
sind eine benutzerdefinierte Klasse, die diesen Code als schreibt
if (lhs < rhs) // requires T.operator<
lessthan
else if (lhs > rhs) // requires T.operator>
greaterthan
else
equal
Der Implementierer muss zwei Vergleichsfunktionen bereitstellen. So <
ist der bevorzugte Betreiber geworden.
i++
zui+=2
(zum Beispiel) wechseln , läuft es sehr lange (oder möglicherweise für immer). Da Sie dies normalerweise<
für Fälle verwenden, in denen Sie den Iterator um mehr als 1 erhöhen , können Sie ihn<
auch für den Fall verwenden, dass Sie ihn um 1 erhöhen (aus Gründen der Konsistenz).