home *** CD-ROM | disk | FTP | other *** search
- ==========================================================================
- APPRENTISSAGE du C version ALB_10
-
- CHAPITRE 3: LES OPERATEURS.
- ==========================================================================
-
-
- Ce sont: l'opérateur d'affectation (=),
- les opérateurs arithmétiques,
- les opérateurs de manipulation de bits.
- les opérateurs logiques,
- et des opérateurs spéciaux.
-
- Le C est très riche en opérateurs. Il utilise ceux des langages évolués
- mais aussi ceux de l'assembleur pour manipuler des bits.
-
-
-
- 1. L'OPERATEUR D'AFFECTATION (=).
- ================================
-
- +----------------------------------------------------------+
- | Ce n'est surtout pas un symbole d'égalité! |
- +----------------------------------------------------------+
-
- test= 5; signifie que la valeur 5 est affectée à la variable test.
- 5= test; est illégal, on n'affecte pas une variable au nombre 5.
-
- => Le membre à droite doit être une valeur ou une expression calculée
- => Le membre à gauche doit être impérativement un élément modifiable
- comme par exemple une variable, on dit une "lvalue".
-
- * test+ 5= y- 2; est rejeté, le membre de gauche n'est pas une lvalue
-
- * x= y= z= 0; est correct si les variables sont du même type.
- L'associativité se fait de droite à gauche.
-
- Mais on ne peut pas user de cette facilité dans une déclaration:
- double x= y= z= 3; est rejeté.
-
-
-
- 2. LES OPERATEURS ARITHMETIQUES.
- ================================
-
- 2.1. Les opérateurs dits "unaires" parce qu'ils
- n'agissent que sur un seul élément.
- ---------------------------------------------------------
- * + et - qui déterminent le signe d'une variable: -test;
-
- * les opérateurs d'incrémentation et de décrémentation:
-
- on incrémente i quand on écrit: i= i+ 1;
- on décrémente j : j= j- 1;
-
- Proche en cela de l'assembleur, le C offre des opérateurs qui
- permettent d'accélérer ces opérations:
-
- i++ ou ++i incrémente la variable i de 1.
- j-- ou --j décrémente j de 1.
- Chapitre 3: Les opérateurs page 1
-
-
-
- => A l'intérieur d'un calcul les 2 formes ne sont pas équivalentes:
-
- z= 10; signifie: test= 10 et z= 11,
- test= z++; 10 est affecté à test puis on incrémente z .
-
- z= 10; signifie: test= 11 et z= 11,
- test= ++z; on incrémente z puis 11 est affecté à test.
-
- z= 10;
- test= z--; test= 10 et z= 9.
-
- z= 10;
- test= --z; test= 9 et z= 9.
-
- => Il est possible d'écrire:
- test= 5+ ++z;
-
- on incrémente z, on l'ajoute à 5 et le résultat est affecté à test.
- L'inconvénient est de rendre le code plus difficile à lire, ne vaut
- il pas mieux écrire sur 2 lignes:
- ++z; // ou: z++;
- test= 5+ z;
-
- => On ne peut incrémenter ou décrémenter une expression :
-
- ( test* 3/ z)++ est rejeté.
-
- => Ces opérateurs ont la plus forte priorité dans les calculs.
-
- 2.2. Les opérateurs "binaires", qui portent sur deux termes:
- -------------------------------------------------------------
-
- * + l'addition, - la soustraction,
- * la multiplication, / la division.
-
- * On ajoute les opérateurs parenthèses () pour fixer l'ordre des calculs.
-
- * L'opérateur modulo, noté %, qui donne le reste de la division entière
- d'un entier par un autre: 25 % 5= 0, 25 % 7= 4, 25 % 19= 6.
-
- * Les opérateurs raccourcis. Ils sont utilisés à cause de leur rapidité.
-
- test= test+ z; s'écrit en raccourcis: test+= z;
-
- Dans le premier cas, le C réserve une place en mémoire pour conserver
- la variable test qui doit être conservée, alors qu'avec l'écriture
- raccourcie l'opération se fait dans le registre qui contient test dont
- on ne conservera pas l'ancienne valeur.
- On a selon le même principe:
-
- x+= y; <=> x= x+ y; x-= y; <=> x= x- y;
-
- x*= y; <=> x= x* y; x/= y; <=> x= x/ y;
-
- x%= y; <=> x= x% y;
-
- => Comme avec l'opérateur d'affectation, le membre à gauche doit être
- impérativement une "lvalue", un élément modifiable, et le membre à
- droite doit être une expression calculée ou une valeur.
- Chapitre 3: Les opérateurs page 2
-
-
-
- 3. LES OPERATEURS DE MANIPULATION DE BITS.
- ==========================================
-
- Ils agissent directement sur le code binaire des mots machine, ce
- qui accélère les opérations simples. On qualifie ces opérations de
- "bas niveau". Ces opérateurs ne s'appliquent qu'à des variables de type
- entier ou assimilé: int, char, short, long int, signés ou non.
-
- 3.1. L'opérateur unaire d'inversion bit à bit. symbole: ~ ( Alt 126)
- ----------------------------------------------
- Il inverse un à un tous les bits d'un mot:
-
- 0111 1111 1111 1110 <=> 32766
- ~32566 => 1000 0000 0000 0001 <=> - 32767
-
- C'est à 1 près la valeur inverse en décimal.
-
-
- 3.2. Opérateur logiques binaires bit à bit. ( & , | , ^ )
- ---------------------------------------------
- Ils s'appliquent à des valeurs entières: symbole
-
- ET logique bit à bit: &
- OU logique bit à bit: | ( Alt 124)
- OU logique exclusif bit à bit: ^
-
- +---------------------------------------------------------+
- | X Y X & Y X | Y X ^Y |
- +---------------------------------------------------------+
- | 0 0 0 0 0 |
- | 1 0 0 1 1 |
- | 0 1 0 1 1 |
- | 1 1 1 0 1 |
- +---------------------------------------------------------+
-
- exemples: X 0000 1111 0000 1111 <=> 3855
- Y 0001 0000 1111 1001 <=> 4345
- X & Y 0000 0000 0000 1001 <=> 9
-
- X 0000 1111 0000 1111 <=> 3855
- Y 0001 0000 1111 1001 <=> 4345
- X | Y 0001 1111 1111 1111 <=> 8191
-
- X 0000 1111 0000 1111 <=> 3855
- Y 0001 0000 1111 1001 <=> 4345
- X ^ Y 0001 1111 1111 0110 <=> 8182
- Chapitre 3: Les opérateurs page 3
-
-
-
- 3.3. Les opérateurs de décalage binaire vers la droite et vers la gauche.
- --------------------------------------------------------------------------
-
- Ils permettent des opérations sur des entiers,
- les bits sortants sont perdus,
- les bits entrants sont des 0.
-
- * Décalage à gauche: x << y
- 4345 << 2 la valeur binaire de 4345 est décalée 2 fois à gauche.
- C'est la multiplication par 2 autant de fois qu'il y a de décalages,
- mais à l'intérieur du domaine de définition des variables.
-
- Voici 3 exemples où on utilise des int de 16 bits:
-
- 0001 0000 1111 1001 <=> 4345
- 4345 << 2 0100 0011 1110 0100 <=> 17380 = 4* 4345
- 2 décalages
- 1100 0010 0111 0100 <=> -15756
- -15756 << 1 1000 0100 1110 1000 <=> -31512 = 2* (-15756)
- 1 décalage
- 1101 1111 1100 0110 <=> -8250
- -8250 << 2 0111 1111 0001 1000 <=> 32536
-
- on est sorti du domaine des int: 32536= 32768 + ( -8250* 4+ 32768)
- = limite+ dépassement algébrique
-
-
- ************
- * Décalage à droite: x >> y Analysez: CH03_01.C
- On divise par 2 à chaque décalage. ************
-
- 0001 0000 1111 1001 <=> 4345
- 4345>>2 0000 0100 0011 1110 <=> 1086= 4345/ 4
-
- Pour ces opérateurs binaires on dispose d'expressions raccourcies:
-
- x&= y <=> x= x& y x^= y <=> x= x^ y x>>= y <=> x= x>> y
-
- x|= y <=> x= x| y x<<= y <=> x= x<< y
- Chapitre 3: Les opérateurs page 4
-
-
-
- 4. LES OPERATEURS LOGIQUES.
- ===========================
-
- Ils font des comparaisons ou des opérations logiques sur des variables
- en utilisant une convention:
-
- si la réponse à la question posée est:
-
- "FAUX" l'opérateur renvoie 0
- "VRAI" l'opérateur renvoie une valeur différente de 0.
-
- 4.1. Les opérateurs de comparaison. ( <, >, <=, >=, !=, == )
- -----------------------------------
-
- x= 3 y= 0 x < y renvoie 0 x > y renvoie 1
- x <= y 0 x >= y 1
-
- != est le test "différent de": x != y renvoie 1
-
- == est le test d'égalité : x == y renvoie 0
- Il ne faut surtout pas le confondre avec l'opérateur d'affectation (=),
-
- 4.2. Les opérateurs logiques. ( && , || , ! )
- -----------------------------
- ************
- NON ! analysez: CH03_02.C
- ET && Intersection ************
- OU inclusif || Union
-
- +---------------------------------------------------------+
- | x y x && y x || y !x |
- +---------------------------------------------------------+
- | 0 0 0 0 1 |
- | 1 0 0 1 0 |
- | 0 1 0 1 |
- | 1 1 1 0 |
- +---------------------------------------------------------+
-
- Il ne faut pas les confondre avec les opérateurs binaires: &, |, ^,
- qui ne portent que sur des entiers.
-
- => Dans le programme CH03_02.C notez plus particulièrement:
-
- si t0= 0 , !t0= 1 si= t2= 3 , !t2= 0
- ************
- => Décortiquez le programme CH03_03.C . CH03_03.C
- ************
- Son prétexte est une vérification des lois de Morgan,
- classiques en algèbre de Boole.
- Notez qu'il y a un ordre de priorité entre ces opérateurs:
- ! possède une priorité supérieure à && et && à ||. Dans le calcul de
- test1 la machine évalue d'abord !( t0< t1) et !( t1< t2) puis fait
- l'opération &&.
- Vous trouverez plus loin une rubrique qui précise ces priorités.
- Chapitre 3: Les opérateurs page 5
-
-
-
- 5. LES OPERATEURS SPECIAUX.
- ===========================
-
- Nous étudierons:
- l'opérateur ternaire (?),
- l'opérateur séquentiel (,),
- l'opérateur de conversion de type (),
- l'opérateur sizeof(),
- les opérateurs unaires de référence et de déréférencement.
-
- 5.1. L'opérateur ternaire conditionnel (?).
- -------------------------------------------
-
- C ? A : B ternaire puisque nous avons 3 expressions C, A, B.
-
- 1° Il teste l'expression C.
- 2° Si cette expression est "VRAI", il évalue A et renvoie sa valeur.
- Si cette expression est "FAUX", il évalue B et renvoie sa valeur.
-
- ************
- analysez: CH03_04.C
- ************
- Remplacez dans la déclaration float par double et les %f par %lf dans
- les quatres printf(). L'erreur d'arrondi disparait.
-
- 5.2. L'opérateur séquentiel (,).
- --------------------------------
- Il permet d'enchaîner plusieurs instructions, la dernière donne sa valeur
- à l'expression. On l'utilise par exemple pour:
-
- * Des déclarations multiples: double x, y= 2.36e-5, z;
-
- * Dans la partie initialisation et celle de fin de la boucle "for"
- comme nous le verrons plus loin.
-
- * Dans des calculs: ************
- il est à employer sans excès, analysez: CH03_05.C
- ************
-
- 5.3. L'opérateur de conversion de type (). ( ou opérateur de cast)
- ------------------------------------------
- * Cet opérateur nous est familier en mathématiques où il permet de
- contrôler l'ordre des opérations dans un calcul: ( x- y)/ 1.3-( y- 1)* 4
-
- * En C c'est aussi un opérateur qui permet de forcer la conversion
- d'un type de variable en un autre type.
-
- ( nouveau type qu'on force) expression à convertir
-
- par exemple: (int) z z étant double.
-
- Je cherche à obtenir la valeur entière d'une expression z:
- double x= 1.3e-4, y= 25.3, z;
- int a;
- z= ( x- 3.5)/ ( 7* y+ 5.1)+ 18; // z= 17.980791
- a= (int) z; // a= 17
-
- On a forcé la variable double z, à se convertir en un entier.
- Chapitre 3: Les opérateurs page 6
-
-
-
- ATTENTION, cette opération présente des dangers ************=
- quand on sort du domaine de définition des variables: CH03_06.C
- Dans ce programme on passe aux long int pour pallier cet ************=
- inconvénient.
- Notez que l'opération de conversion ne se fait qu'après le calcul de
- l'expression. Celui ci se fait dans les conditions normales:
-
- a= (int) ( ( x- 3.5)/ ( 7* y+ 5.1)+ 18 );
-
- 5.4. L'opérateur sizeof().
- -------------------------
- Il permet de calculer la taille en octets d'une variable et donc de
- son type.
- sizeof( nom de la variable)
- int a= 25;
- printf(" taille de la variable a= %d", sizeof( a));
-
- Nous obtiendrons: taille de la variable a= 2
- L'écriture sizeof( int) aurait donné 2
- sizeof( double) aurait donné 4
-
- 5.5. Les opérateurs unaires d'adresse et d'indirection & et * .
- ----------------------------------------------------------------
- Nous avons vu qu'au moment de la déclaration d'une variable, le
- compilateur réserve un espace mémoire pour stocker la valeur qui sera
- ensuite affectée à cette variable quand on l'initialise. Le compilateur
- conserve dans une table le nom de la variable avec l'adresse de cette zone.
-
- * L'opérateur unaire d'adresse ( ou de référencement) & permet
- d'obtenir cette adresse( ou cette référence). On utilise le même
- symbole que celui du ET bit à bit qui est un opérateur binaire.
- Cet opérateur s'applique à une variable:
-
- Si a est une variable, &a est une adresse, la référence de a.
-
- * Inversement, on peut obtenir la valeur stockée à l'adresse indiquée,
- avec l'opérateur unaire d'indirection ( ou de déréférencement) qui
- utilise le même symbole * que l'opérateur binaire de multiplication.
- Cet opérateur s'applique à une adresse:
-
- Si &a est une adresse, *(&a) est la valeur
- de la variable située à cette adresse, donc a.
- ************
- Analysez: CH03_07.C
- ************
- C'est une application directe des définitions précédentes.
- Chapitre 3: Les opérateurs page 7
-
-
- ************
- Analysez: CH03_08.C
- ************
- Ce programme est presque identique au précédent. Une ligne est ajoutée, et
- c'est capital:
- *(&a)= 32; ce qui a entraîné a= 32
-
- L'adresse déréférencée a été modifiée. La variable a suivi. C'est lourd de
- conséquences pour l'évolution du langage. Une variable a été modifiée
- indirectement à partir de son adresse. Les développeurs du langage, pour
- généraliser ce comportement ont créé une nouvelle catégorie d'objets qui
- sont par leur nature des adresses.
-
- Si un de ces nouveaux objets est une variable b, sa valeur est donc
- une adresse. Si nous affectons à b l'adresse de la variable a, b= &a;
- Alors *b, la valeur déréférencée de b, est égale à la valeur de a.
- Si nous modifions *b, alors la variable a sera modifiée.
-
- On appelle l'objet *b, valeur déréférencée de la variable adresse b, un
- POINTEUR car il semble qu'il montre, qu'il pointe la variable a.
-
- ************
- Analysez: CH03_09.C
- ************
- ------------------------------------------------------------
- | *b étant déclaré, si: b= &a; alors: *b= a; |
- ------------------------------------------------------------
- Chapitre 3: Les opérateurs page 8
-
-
-
-
- 6. ORDRE DE PRIORITE DES OPERATEURS EN C.
- =========================================------------------------------
-
- ( ) appel de fonction gauche à droite
- [ ] élément de tableau
- . membre d'une structure ou d'une union
- -> pointeur sur un membre
- sizeof taille d'un objet en bytes
- sizeof taille d'un type en bytes
- -----------------------------------------------------------------------
- ++ post incrémentation (lvalue++) droite à gauche
- ++ pre incrémentation (++lvalue)
- -- post décrémentation (lvalue--)
- -- pre décrémentation (--lvalue)
- ~ inversion de bits
- ! non logique
- - moins unaire
- + plus unaire
- & addresse
- * indirection
- (type) conversion de type
- ----------------------------------------------------------------------
- * multiplication gauche à droite
- / division
- % modulo
- ----------------------------------------------------------------------
- + addition gauche à droite
- - soustraction
- ----------------------------------------------------------------------
- << décalage à gauche gauche à droite
- >> décalage à droite
- ----------------------------------------------------------------------
- < plus petit que gauche à droite
- <= plus petit ou égal
- > plus grand que
- >= plus grand ou égal
- ----------------------------------------------------------------------
- == égalité gauche à droite
- != inégalité
- ----------------------------------------------------------------------
- & ET logique bit à bit gauche à droite
- ----------------------------------------------------------------------
- ^ OU logique exclusif bit à bit gauche à droite
- ----------------------------------------------------------------------
- | OU logique bit à bit gauche à droite
- ----------------------------------------------------------------------
- && ET logique gauche à droite
- ----------------------------------------------------------------------
- || OU inclusif gauche à droite
- ----------------------------------------------------------------------
- ? : opérateur ternaire droite à gauche
- ----------------------------------------------------------------------
- = affectation droite à gauche
- et aussi += -= *= /= %=
- &= ^= |= >>= <<=
- ----------------------------------------------------------------------
- , opérateur séquentiel gauche à droite
- ----------------------------------------------------------------------
- Fin du chapitre 3: Les opérateurs page 9
-
-
-
-