Historique de la question
La priorité des opérateurs a été introduite en C pour contrôler l'ordre des calculs dans les expressions mathématiques et logiques. Bien que les opérateurs mathématiques aient une priorité historiquement attendue (comme en algèbre), l'apparition de nombreux nouveaux opérateurs (logiques, bit à bit, d'assignation, etc.) a compliqué la situation. Pour réduire les risques d'erreurs et améliorer la lisibilité, une liste officielle de priorités et d'associativités des opérateurs a été créée.
Problème
Avec un plus grand nombre d'opérateurs et leur nature variée (arithmétiques, comparaisons, assignations, logiques, indexation), des ambiguïtés apparaissent lors de la création d'expressions complexes. Une mauvaise compréhension de l'ordre de leur application peut entraîner des erreurs logiques et des bugs parfois peu évidents, en particulier lors de la combinaison d'opérateurs bit à bit et logiques, de pointeurs, d'incrémentations et de l'opérateur ternaire.
Solution
Exemple de code :
#include <stdio.h> int main() { int a = 1, b = 2, c = 3, d; d = a + b * c; // b*c s'exécute d'abord : d = 1 + (2*3) = 7 printf("%d ", d); d = a + b << 1; // a + b = 3, puis 3 << 1 (6) printf("%d ", d); d = a < b ? a++ : b++; printf("%d ", d); // a < b est vrai => d = a (1), a augmentera après }
Caractéristiques clés :
Quel résultat donnera l'expression x = y > z ? y : z ; si les parenthèses sont oubliées ?
Réponse : L'opérateur ternaire ?: a une priorité plus basse que >. D'abord, (y > z) est évalué, puis on choisit entre y et z. Mais si on l'associe à une assignation, des effets inattendus peuvent survenir. Il est préférable d'utiliser toujours des parenthèses x = (y > z) ? y : z ;.
*Quel résultat donnera l'expression p++ et pourquoi ?
Réponse : L'opérateur d'incrémentation post (++) a une priorité plus élevée que la déréférence (*), donc *p++ devient *(p++) : d'abord p est utilisé et augmenté, puis il est dereférencé, ce qui peut être différent de *++p (déréférencement après l'incrément).
Pourquoi l'expression a & b == c ne fonctionne-t-elle pas comme prévu ?
Réponse : L'opérateur == a une priorité plus élevée que &, donc l'expression est analysée comme a & (b == c), et non comme (a & b) == c, ce qui produira un résultat inattendu. Pour la logique souhaitée, il faut utiliser des parenthèses.
if ((a & b) == c) { ... }
Cas négatif
Lors de l'optimisation du code, un programmeur a combiné plusieurs opérateurs sans parenthèses : if( mask & flag == 0 ) ..., ce qui a fait que la logique de vérification ne fonctionnait pas correctement et a entraîné un plantage du système.
Avantages :
Inconvénients :
Cas positif
Utilisation d'un groupement explicite : if( (mask & flag) == 0 ) ..., la logique est claire, il est facile de modifier les drapeaux.
Avantages :
Inconvénients :