
FAQ CConsultez toutes les FAQ
Nombre d'auteurs : 28, nombre de questions : 175, création le 11 janvier 2013
Sommaire→Les types et les variables→Les opérateurs- Quelle est la différence entre = et == ?
- Pourquoi if (a = b) ne génère pas d'erreur de compilation ?
- Que signifie 'x = (a == b) ? 5 : 10' ?
- Comment calculer le reste d'une division entière ?
- Que fait exactement l'opérateur / ?
- Quelle est la différence entre i++ et ++i ?
- Que font les opérateurs << et >> ?
- Que signifie E1 & E2 ?
- Que signifie E1 | E2 ?
- Quelle est la différence entre (E1 && E2) et (E1 & E2) ?
- Comment est évaluée l'expression E1 && E2 ?
- Comment accéder à un bit d'une variable ?
L'opérateur = est l'opérateur d'assignation, c'est-à-dire qu'il attribue la valeur qui se trouve à sa droite à l'élement qui se
trouve à sa gauche.
L'opérateur == est l'opérateur de comparaison, c'est-à-dire qu'il renvoie vrai si les éléments à sa gauche et à sa droite sont
identiques.
Parce qu'en C, l'opérateur = est valide dans un test bien que la plupart des compilateurs émettent un avertissement à ce sujet. Le programme suivant :
#include <stdio.h>
int main(void)
{
int a = 5, b = 10;
if (a = b)
{
/* Vrai car l'expression a = b vaut la valeur de a apres affectation c'est-a-dire : 10. */
/* Or en C, toute valeur differente de 0 (par exemple 10) vaut 'VRAI', d'ou le resultat. */
printf("Coucou !\n");
}
return 0;
}
Affichera Coucou !
Le programme suivant par contre n'affichera rien du tout.
#include <stdio.h>
int main(void)
{
int a = 5, b = 10;
if (a == b)
{
/* Faux car a (5) est different de b (10). */
printf("Coucou !\n");
}
return 0;
}
Lien : Quelle est la différence entre = et == ?
Lien : Existe-t-il un type booléen en C ?
L'opérateur ?: est un opérateur ternaire c'est-à-dire qu'il prend 3 opérandes. L'expression a ? b : c vaut b si a vaut 'vrai' et c sinon. Ainsi, avec l'instruction 'x = (a == b) ? 5 : 10;', x vaut 5 si (a == b) et 10 dans le cas contraire.
Sur un nombre positif, l'opérateur modulo (%) correspond strictement à sa définition mathématique, c'est-à-dire calcule le reste de la division entière. Par exemple 5 % 3 donne 2 (reste de la division de 5 par 3). Retenez donc qu'un nombre quelconque modulo N sera toujours compris entre 0 et N, N exclu. La norme n'exige pas que l'opérateur modulo puisse également s'utiliser avec un nombre négatif.
Voici un petit rappel des règles s'appliquant aux divisions en C :
- Si les deux opérandes sont de type entier (char, int, short, long, long long) alors la division effectuée sera entière, et donnera de ce fait toujours un résultat entier.
- Si au moins l'une des deux opérandes est de type flottant (float, double, long double) alors la division effectuée sera réelle, donnant un résultat décimal.
- Le type du résultat de la division est celui de l'opérande réelle (si au moins l'une des deux l'est) possédant la plus grande capacité.
double r1 = 7 / 10; /* r1 = 0 */
double r2 = 7.0 / 10; /* r2 = 0.7 */
double r3 = 7 / 10.0f; /* r3 = 0.7f */
double r4 = 7.0 / 10.0f; /* r4 = 0.7 */
L'opérateur ++ est un opérateur d'incrémentation : il ajoute 1 à la variable à laquelle il est appliqué. La seule différence est que
i++ permet d'utiliser et seulement ensuite de l'incrémenter, alors que ++i incrémente la variable avant de l'utiliser.
L'opérateur -- fonctionne exactement de la même façon, sauf qu'il s'agit d'une décrémentation.
Ces deux opérateurs effectuent un déplacement (shift) des bits dans une variable.
<< effectue un décalage à gauche du nombre de positions précisées
>> effectue un décalage à droite du nombre de positions précisées
<<= effectue un décalage à gauche du nombre de positions précisées et assigne le résultat à la première opérande
>>= effectue un décalage à droite du nombre de positions précisées et assigne le résultat à la première opérande
unsigned char c1, c2, c3, c4;
c1 = 5; /* 00000101 */
c2 = 4; /* 00000100 */
c3 = c1 << 2; /* 00000101(c1) -> 00010100(c3) */
c4 = c2 >> 2; /* 00000100(c2) -> 00000001(c4) */
c1 <<= 2; /* 00000101(c1) -> 00010100(c1) */
c2 >>= 2; /* 00000100(c2) -> 00000001(c2) */
Cela signifie qu'on effectue un ET bit à bit entre E1 et E2. Le bit résultant est 1 lorsque les 2 bits sont à 1, 0 sinon.
0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1
++ unsigned char c1, c2;
++
++ c1 = 5; /* 00000101 */
++ c2 = 4; /* 00000100 */
-> c1 & c2 = 4 /* 00000100 */
On dit qu'on a masqué c1 avec c2. On appelle ça (c2) un masque car il permet de cacher (masquer) certains bits de c1 (cacher signifie mettre à zéro).
Cela signifie qu'on effectue un OU bit à bit entre E1 et E2. Le bit résultant est 1 lorsque un au moins des 2 bits est à 1, 0 sinon.
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1
++ unsigned char c1, c2;
++
++ c1 = 5; /* 00000101 */
++ c2 = 4; /* 00000100 */
-> c1 | c2 = 5 /* 00000101 */
L'opérateur && désigne l'opérateur ET logique. E1 && E2 correspond à l'expression 'E1 est vrai ET E2 est vrai'.
L'opérateur & désigne l'opérateur ET binaire. E1 & E2 retourne donc le ET bit à bit entre E1 et E2.
De même, || désigne l'opérateur OU logique. E1 || E2 correspond à l'expression 'E1 est vrai OU E2 est vrai'.
L'opérateur | désigne l'opérateur OU binaire. E1 | E2 retourne donc le OU bit à bit entre E1 et E2.
L'opérateur ^ quant à lui permet de faire un OU EXCLUSIF (XOR) binaire. Il n'y a pas d'opérateur
qui fasse le OU EXCLUSIF logique (E1 '^^' E2 = (E1 && !E2) || (E2 && !E1)).
Lien : Que signifie E1 & E2 ?
Lien : Que signifie E1 | E2 ?
Lors de l'utilisation des opérateurs && et ||, les différents membres sont évalués de gauche à droite. L'évaluation est stoppée dès que le résultat final est connu de manière certaine, c'est-à-dire :
- Si lors de l'utilisation de && un membre est évalué à faux.
- Si lors de l'utilisation de || un membre est évalué à vrai.
Il est souvent intéressant d'accéder aux bits d'une variable, ce qui permet, par exemple, de stocker 8 flags (nombre de bits minimal d'un
char) dans un seul char plutôt que d'utiliser un char par flag.
Pour manipuler les bits, il suffit d'utiliser les opérateurs du langage : & (opérateur ET) pour tester un bit, | (opérateur OU) pour
positionner un bit et & (opérateur ET) et ~ (opérateur NON) pour enlever un bit
Voici deux petites macros, permettant respectivement de positionner un flag et de lire la valeur d'un flag :
#define SET(flag, bit) ((flag) |= (1 << (bit)))
#define CLEAR(flag, bit) ((flag) &= ~(1 << (bit)))
#define GET(flag, bit) ((flag) & (1 << (bit)))
Remarque : dans ces macros, nous considérons que le bit de poids faible est le bit 0.



