Je prends l'adjectif «technique» pour désigner le comportement / les bizarreries du langage et les effets secondaires du compilateur tels que les performances du code généré.
À cette fin, la réponse est: non (*). Le (*) est "veuillez consulter le manuel de votre processeur". Si vous travaillez avec un système RISC ou FPGA à boîtier périphérique, vous devrez peut-être vérifier quelles instructions sont générées et ce qu'elles coûtent. Mais si vous utilisez à peu près une architecture moderne classique, alors il n'y a pas de différence de niveau de processeur important entre le coût lt
, eq
, ne
et gt
.
Si vous utilisez un cas limite , vous pouvez constater que !=
nécessite trois opérations ( cmp
, not
, beq
) contre deux ( cmp
, blt xtr myo
). Encore une fois, RTM dans ce cas.
Pour la plupart, les raisons sont défensives / durcies, en particulier lorsque vous travaillez avec des pointeurs ou des boucles complexes. Considérer
// 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;
}
Un exemple moins artificiel serait où vous utilisez des valeurs de retour pour effectuer des incréments, en acceptant des données d'un utilisateur:
#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(;;)
}
}
Essayez ceci et entrez les valeurs 1, 2, 10, 999.
Vous pouvez empêcher cela:
#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;
}
}
Mais ce que vous vouliez probablement était
#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;
}
}
Il existe également une sorte de parti pris conventionnel <
, car la commande dans des conteneurs standard repose souvent sur operator<
, par exemple le hachage dans plusieurs conteneurs STL détermine l'égalité en disant
if (lhs < rhs) // T.operator <
lessthan
else if (rhs < lhs) // T.operator < again
greaterthan
else
equal
Si lhs
et rhs
sont une classe définie par l'utilisateur écrivant ce code comme
if (lhs < rhs) // requires T.operator<
lessthan
else if (lhs > rhs) // requires T.operator>
greaterthan
else
equal
L'implémenteur doit fournir deux fonctions de comparaison. Ainsi <
est devenu l'opérateur privilégié.
i++
ài+=2
(par exemple), il fonctionnera très longtemps (ou peut-être pour toujours). Maintenant, puisque vous utilisez généralement<
pour les cas où vous incrémentez l'itérateur de plus de 1, vous pouvez aussi bien utiliser<
également pour le cas où vous l'incrémentez de 1 (pour la cohérence).