Vous êtes sur la page 1sur 29

COURS LANGAGE C & C++

Enseignant : M. EBOA Michel Anicet


Plan du cours
Chapitre 1 : Les bases de la programmation en C
Pour valider le module :
Chapitre 2 : Structure d’un programme C
Chapitre 3 : Les types de base
• CC : Présence, TP et TPE
Chapitre 4 : Les operateurs et les expressions
• Un examen de fin de Chapitre 5 : Les instructions de contrôle
semestre Chapitre 6 : Les fonctions

Code B2033 Chapitre 7 : Les tableaux et les pointeurs


Volume Horaire 32 h Chapitre 8 : Les chaines de caractères
Crédits 3
Chapitre 9 : Les structures et les unions
Niveau 1
Semestre 1 Chapitre 10 : Introduction au Langage C++
Pré-requis Raisonnement logique
Chapitre 4 : Les operateurs et les expressions

Objectifs
• Connaître les différents types d’opérateur et les manipuler
• Connaître les différents types d’expressions et les manipuler

Eléments de contenu
• Les opérateurs arithmétiques
• La conversion implicite de type dans les expressions
• Les opérateurs relationnels
• Les opérateurs logiques
• L’opérateur d’affectation simple
• Les opérateurs d’incrémentations et de décrémentation
• Les opérateurs de manipulations de bits
• Les opérateurs d’affectation élargie
• L’opérateur conditionnel
• Les conversions explicites
• L’opérateur de “cast”
• L’opérateur séquentiel
• L’opérateur sizeof
VI.1. LES OPERATEURS ARITHMETIQUES
VI.1.a. Leur rôle
On trouve en C :
• 5 opérateurs “binaires“ (c’est à dire qui portent sur deux opérandes)
• 2 opérateurs unaires qui portent sur un seul opérande.

Le tableau suivant vous fournit la liste de ces différents opérateurs :

TYPE OPERATEUR ROLE

Binaire + somme
- différence A l’exception de l’opérateur “%“ qui ne peut porter
* produits
que sur des entiers, ces opérateurs peuvent
/ quotient
s’appliquer à tous les types numériques. Cela
% reste de division
(modulo) signifie qu’un même symbole tel que ”*” définit en
Unaire - opposé
fait plusieurs opérations différentes suivant le type
+ Identité
des quantités sur lesquelles il porte.
Les opérateurs binaires ne sont, à priori, définie que pour des opérandes de même type et ils
fournissent un résultat de ce même type. Ce dernier point mérite un peu d’attention. En effet, si ‘on
s’attend effectivement à ce que la somme de deux entiers soit un entier, les choses sont moins
évidentes pour l’opérateur quotient (“/”). Ainsi par exemple, si 5/2 est le quotient de deux valeurs
doubles, et à ce titre fournit bien le résultat 2.5 qui est aussi (de type double). Par contre, si 5/2 est le
quotient de deux valeurs de type int et le résultat est de type int, a savoir ici 2.

Remarque
Il n’existe pas d’opérateur d’élévation à la puissance (^), il est nécessaire de faire appel soit â des
produits successifs, soit à la fonction power de la bibliothèque.

VI.1.b. Leurs priorités relatives x


Lorsque plusieurs opérateurs apparaissent. dans une même expression, il est nécessaire de savoir
dans quel ordre ils sont mis enjeu. En C, comme dans les autres langages, les règles sont naturelles et
rejoignent celles de l’algèbre traditionnelle ( en ce qui concerne les opérateurs arithmétiques)
Les opérateur unaire + et - ont la priorité la plus élevée, On trouve en suite à un même niveau les
opérateurs *,/ et % . Enfin sur un dernier niveau apparaissent les opérateurs binaires + et - .
En cas de priorité identique, les calculs s’effectuent de gauche à droite. Enfin, des parenthèses
permettent d’outre passer ces règles de porter en forçant le calcul préalable de l’expression qu’elles
contiennent. Notez que ces parenthèses peuvent également être employées pour assurer une
meilleure lisibilité d’une expression.

Voici quelques exemples d’expressions équivalentes :

a+b*c a+(b* c)
a*b+c%d (a*b)+(c%d)
-c % d (-c)%d
-a/-b+c ((-a)/(-b))+c
VI.2. LES CONVERSIONS IMPLICITES DE TYPE DANS LES EXPRESSIONS
A l’opposé de ce qui se passe dans un langage comme Pascal, Le langage C est très tolérant vis a
vis du mélange des types dans les expressions.
Ainsi, par exemple, si n est le type int, et x de type double, une expression telle que : n+x
sera acceptée par le compilateur. Elle conduira à la mise en place d’instructions réalisant :
• la conversion de n en double. Cette opération a un sens et est toujours possible.
• l’addition des deux valeurs de type double. Le résultat sera lui aussi de type double.
On dit qu’il y a eu mise en place de “conversions implicites” puisque celles-ci n’ont pas été
explicitées au sein des instructions.
D’une manière générale, on peu dire que si un opérateur porte sur deux opérandes de type
différents, il y a en quelque sorte, conversion du type “le plus faible’ dans le type “le plus fort”. Ainsi,
dans notre exemple double était plus fort que int.
Une grande originalité du C est d’étendre ces facilités de conversions aux types caractères. Cette
fois cependant le mécanisme sera un peu diffèrent car tout opérande de type char apparaissant
dans une expression sera systématiquement converti en int avant d’intervenir dans les calculs.
Il est à noter aussi que tous les calculs flottants ne s’effectuent que sur des valeurs de type double.
Pour ce faire tout opérande de type float est systématiquement converti en double.
VI.2.a. Exemples de conversions implicites sur des types numériques
Supposons que nous avons effectué les déclarations suivantes :
Int n, p
long q, r
float x
double z
Voici trois exemples d’expressions et la manière dont elles vont être évaluées :
• n + q : La valeur de n est convertie en long avant d’être ajoutée à celle de q. Le résultat est de
type long
• q + n *p : Le produit n * p est évalué en int puis le résultat est converti en long pour être ajouté à
la valeur de q. Le résultat est de type long
• x * n : Les valeurs de x et de n sont converties en double. Le résultat est de type double. Bien
entendu, rien n’empêchera ce résultat d’être assigné à une variable de type float (moyennant
une conversion supplémentaire).
VI.2.b. Exemples de conversions implicites de char et int
Supposons que nous avons effectué les déclarations suivantes :
int n
char cl , c2
Voici, à nouveau quelques exemples d’expressions et la manière dont elles sont évaluées :
• C1 + 1 : La valeur de cl est d’abord convertie en int. Cette conversion revient en fait à considérer que les 8
bits occupés par cl forment une valeur entière codée de la même manière que les entiers (mais sur 8 bits
au lieu de 16). Il faudra toutefois distinguer deux cas suivant que cl possède l’attribut signed ou unsigned :
- si cl est unsigned la conversion revient effectivement à prendre la valeur du code ASCII du
caractère on obtiendra ainsi, une valeur entière comprise entre 0 et 255.
- si cl est signed, le premier des 8bits Sera interprété comme un bit de signe. On obtiendra ainsi une
valeur entière comprise entre -128 et 127.
au résultat de cette conversion, on ajoutera la valeur entière de 1.
• cl + n : Là encore, la valeur de cl sera convertie en int. Le résultat sera ajoutée la valeur n pour fournir une
valeur de type int.
• c2 - cl : Ici, bien que les deux opérandes soient de type char, il y aura néanmoins conversion préalable
des valeurs de cl et c2 on int avant que soit calculée la différence. Le résultat est de type int.
VI.2.c. Règles générales de conversion implicite
i) Conversions systématiques et conversion d’ajustement de type
Comme on a vu dans les exemples précédents, il faut distinguer les conversions qui ont lieu
systématiquement de celles qui ne sont réalisées qu’en cas de besoin par ”absorption” par un type plus fort.
Les conversions systématique se résument
char —> int
float —> double
Quant aux autres conversions, elles permettent de faire porter un opérateur sur des valeurs de même type.
Le type commun étant imposé par celui des opérandes ayant le type le plus fort. Voici le schéma
récapitulant ces règles. Les flèches horizontales correspondent à des conversions systématiques. Les flèches
verticales correspondent â des conversions d’ajustement de type.
char —> int —> long

float —> double


De plus, ces règles doivent être complétées par la manière dont sont pris en compte les attributs signed et
unsigned. Pour ce faire on va distinguer le type char des types entiers.
ii) Prise en compte de l’attribut signe pour les caractères
Cet attribut intervient lors de la conversion systématique en int. S’il s’agit d’un caractère non signé le
résultat de la conversion est un entier compris entre O et 255 ; la conversion revient simplement dans
ce cas à compléter le motif de 8 bits par des zéros à gauche. Lorsqu’il s’agit d’un caractère signé, le
résultat de la conversion est un entier compris entre - 128 et +127 ; la conversion revient à “propager
le bit de signe du caractère dans les 8 bits de gauche de L’entier à fabriquer, <i C~) ~r Ct)

iii) prise en compte de l’attribut signe pour les entiers


En ce qui concerne la prise en compte de l’attribut signe pour les types entiers, la règle ne prévoir
que unsigned .
VI.3. LES OPERATEURS RELATIONNELS
Comme tout Langage, C permet de ‘‘comparer” les expressions à laide d’opérateurs classiques de
comparaison. En voici un exemple : 2 * a > b+5
Par contre, C se distingue des autres langages sur deux points :
• Le résultat de la comparaison est, non pas une valeur booléenne (on dit aussi ‘logique”) prenant
l’une des deux valeurs vrai ou faux, mais un entier valant :
- 0 si le résultat de a comparaison est faux
- 1 si le résultat de la comparaison est vrai.
Ainsi la comparaison ci-dessus devient en fait une expression de type entier. Cela signifie quelle
pourra éventuellement intervenir dans des calculs arithmétiques
• les expression comparées pourront être d’un type de base quelconque et elles seront soumises
aux règles de conversion présentées dans le paragraphe précédent. Cela Signifie qu’au bout du
compte on ne sera amené à comparer que des expression des types numérique.
Le tableau suivant fournit la liste des opérateurs relationnels existant en C. Remarquez bien que la
notation (==) de l’opérateur de légalité, le signe (=) étant, comme nous le verrons, réservé aux
affectations.
OPERATEUR SIGNIFICATION En ce qui concerne leurs priorités, il faut savoir que les
< Inférieur à quatre premiers opérateurs (<, <=, >, <=) sont de même
<= Inférieur ou égal à
priorité. Les deux derniers (== et ! =) possédant également la
> Supérieur à
>= Supérieur ou égal à même priorité, mais celle-ci est inférieure à celle des
== Egal à précédents. Ainsi l’expression : a < b == c < d est interprétée
!= Différent de comme suit : (a < b)== (c < d)

ce qui, en C, a effectivement une signification, compte tenu de ce que les expressions a<b et c<d
sont, finalement, des quantités entières.
D’autre part, ces opérateurs relationnels sont moins prioritaires, que les opérateurs arithmétiques.
Cela permet souvent d’éviter certaines parenthèses dans des expressions. Ainsi :
x + y < a + 2 est équivalent à (x + y ) < (a + 2)
VI.4. OPERATEURS LOGIQUES
C dispose de trois opérateurs logiques classiques
OPERATEUR SIGNIFICATION
&& et
II Ou (inclusif)
! négation

Par exemple :
• (a < b) && (c < d ) : prend la valeur 1 (vrai) si les deux expressions a <b et c < d sont toutes deux
vrais(de valeur 1), la valeur 0 (faux) dans le cas contraire.
• (a < b) II ( c < d) : prend la valeur 1 (vrai) si l’une au moins des deux expressions a < b et c< d est
vraie (de valeur 1), la valeur 0 (faux) dans le cas contraire.
• !(a < b) : prend la valeur 1 (vrai) si la condition a < b est fausse (de valeur 0 ) et la valeur (faux)
dans le cas contraire. Cette expression est équivalente à : a >= b.
Notez bien que, ne disposant pas de type logique, C représente vrai par 1 et faux par 0 c’est
pourquoi ces opérateurs produisent un résultat numérique (de type int).
De plus, on pourrait s’attendre à ce que les opérandes de ces opérateurs ne puissent être que des
expressions prenant soit la valeur 0, soit la valeur1. En fait ces opérateurs acceptent n’importe quel
opérande numérique, y compris les types flottants, avec les règles de conversion implicite déjà
rencontrées. Leur signification reste celle évoquée ci-dessus, à condition de considérer que :

• 0 correspond à faux,
• toute valeur non nulle correspond à vrai.
Ainsi en C, si n et p sont des entiers, des expressions telles que : n && p n II p !n
sont acceptées par le compilateur. Notez que l’on rencontre fréquemment if( !n)
pour dire: if (n == 0)
L’opérateur (!) a une priorité supérieure à celle de tous les opérateurs arithmétiques binaires et aux
opérateurs relationnels. Ainsi, pour écrire la condition contraire de : a == b il est nécessaire d’utiliser
des parenthèses en écrivant : !(a== b).
En effet, l’expression !a == b serait interprétée comme : (!a) == b
L’opérateur II est mois prioritaire que &&. Tous deux sont de priorité inférieure aux opérateurs
arithmétiques ou relationnels. Ainsi, l’expression : a < b && c < d est équivalente à : (a < b) && (c < d)
Enfin, les deux opérateur && et II jouissent en C d’une propriété intéressante : leur second opérande
(celui qui figure à droite de l’opérateur) n’est évaluée que si la connaissance de sa valeur est
indispensable pour décider si l’expression correspondante est vraie ou fausse. Par exemple, dans une
expression telle que : a < b && c < d on commence par évaluer a < b. si le résultat est faux ; il est
inutile d’évaluer c < d puisque, de toutes façons, l’expression complète aura la valeur faux (0).
VI.5. L’OPERATEUR D’AFFECTATION SIMPLE
VI.5.a. Introduction
Nous avons déjà eu l’occasion de remarquer que i = 5 était un expression qui :
• réalisait un action : l’affectation de la valeur 5 à i
• possédait une valeur : celle de i après affectation, c’est à dire 5
Cet opérateur d’affectation (=) peut faire intervenir d’autres expressions, comme dans : c = b + 3
La faible priorité de cet opérateur = ( elle est inférieure à celle de tous les opérateurs arithmétiques et
de comparaison ) fait qu’il y a d’abord évaluation de l’expression b + 3. La valeur ainsi obtenue est
ensuite affectée à c.
Par contre, il n’est pas possible de faire apparaître une expression comme premier opérande de cet
opérateur =. Ainsi, l’expression c + 5 = x n’aurait pas de sens
VI.5.b. Notion de ‘‘IvaIue”
Nous voyons donc que cet opérateur d’affectation impose des restrictions sur son premier opérande.
En effet ce dernier doit être une “référence” a un“ emplacement mémoire” dont on pourra
effectivement modifier la valeur.
Dans Les autres langages, on désigne souvent une telle référence par le nom de “variable” ; on précise
généralement que ce terme, recouvre par exemple les éléments d’un tableaux ou les composantes
d’une structure.
En langage C, la syntaxe du langage est tel que cette notion de variable n’est pas assez précise. Il faut
introduire un mot nouveau : la IvaIue. Ce terme désigne une “valeur à gauche”, c’est à dire tout ce qui
peut apparaître à gauche d’un opérateur d’affectation.

VI.5.c. Associativité
Contrairement à tous les opérateurs que nous avons rencontrés jusqu’ici, cet opérateur d’affectation
possède une associativité de “droite à gauche”. C’est ce qui permet à une expression telle que : i=j
= 5 d’évaluer d’abord l’expression j=5 avant d’en affecter la valeur (5) à la variable j. La valeur finale
de cette expression est celle de i après affectation, c’est à dire 5.
VI.6. LES OPERATEURS D’INCREMENTATION ET DE DECREMENTATION
VI.6.a. Présentation
Dans des programmes écrits dans un langage autre que C, on rencontre souvent des expressions (ou
des instructions) telles que i = i + 1, n = n – 1 qui “incrémente” ou qui “décrémente” de 1 la valeur
d’une“ variable” (ou plus généralement d’une “lvalue”).
En C ces actions peuvent être réalisées par des opérateurs unaires portant sur cette “lvalue”. Ainsi,
l’expression : ++i a pour effet l’incrémenter de 1 la valeur de i et sa valeur est celle de i après
incrémentation.
Notez bien que, comme pour l’affectation, nous avons une expression qui, non seulement a une
valeur, mais qui réalise aussi une action (incrémentation de i).
Il est important de voir que la valeur de cette expression est celle incrémentation. Ainsi, si la valeur de
i est 5, l’expression : n = ++i – 5 affectera à i la valeur de 6 et à n la valeur de 1.
Par contre, lorsque cet opérateur est placé après la “lvalue” sur laquelle il porte, la valeur de
l’expression correspondante est celle de la variable avant incrémentation. Ainsi, si la valeur de i est 5,
l’expression : n = i++ - 5 affectera à i la valeur de 6 et à n la valeur de 0 (car ici la valeur de
l’expression i++ est 5).
On dit que ++ est :
• un opérateur de pré-incrémentation lorsqu’il est placé à gauche de la “lvalue” sur laquelle il
porte.
• un opérateur de post-incrémentation lorsqu’il est placé à droite de la “lvalue” sur laquelle il porte.
Lorsque seul importe l’effet d’incrémentation d’une “lvalue”, cet opérateur peut être indifféremment
placé avant ou après. Ainsi, ces deux instructions sont équivalentes : i++ ; ++i ;
De la même manière, il existe un opérateur de décrémentation noté ‘’--’’ qui, suivant les ces, sera :
• un opérateur de pré-décrémentation lorsqu’il est placé à gauche de la “lvalue” sur laquelle il
porte.
• un opérateur de post-décrémentation lorsqu’il est placé à droite de la “lvalue” sur laquelle il porte.

VI.6.b. Leurs priorités


Les priorités élevées de ces opérateurs unaires permettent d’écrire des expressions assez compliquées
sans qu’il ne soit nécessaire d’employer des parenthèses pour isoler la Ivalue sur laquelle ils portent.
Ainsi, l’expression suivante a un sens : 3 * I++ * j-- + k++
VI.6.c. Leur intérêt
Ces opérateurs allègent l’écriture de certaines expressions et offrent surtout le grand avantage d’éviter la
‘redondance” qui est de mise dans la plus part des autres langages. En effet, dans une notation telle
que : i++
on ne“ cite” qu’une seule fois la “lvalue” concernée alors qu’on est amené à le faire deux fois dans la
notation i=i+1
Les risques d’erreurs de programmation s’en trouvent ainsi quelque peu limités. Cet aspect prendra d’autant
plus d’importance que la“ lvalue” correspondante sera d’autant plus complexe.
D’une manière générale, nous utiliserons fréquemment ces opérateurs dans la manipulation de tableaux ou
de chaînes de caractères.

VI.7. LES OPERATEURS DE MANIPULATION DE BITS


VI.7.a. Présentation des opérateurs de manipulations de bits
Le langage C dispose d’opérateurs permettant de travailler directement sur le“ motif binaire“ d’une valeur.
Ceux-ci lui procurent ainsi les possibilités traditionnelles réservées à la programmation en langage
assembleur.
A priori, ces opérateurs ne peuvent porter que sur des types entiers. Toutefois, compte tenu des règles de
conversion implicite, ils pourront également s’appliquer à des caractères (mais le résultat en sera entier).
TYPE OPERATEUR SIGNIFICATION
Binaire & et (bit à bit)
I ou (bit à bit)
^ ou exclusif bit à bit)
<< décalage à gauche
>> Décalage à droite
Unaire ~ Complément à un (bit à bit)

VI.7.b. Les opérateurs “bit à bit”


Les trois opérateurs &, I et ^ appliquent en fait la même opération à chacun des bits des deux
opérandes. Leur résultat peut ainsi être défini à partir d‘une table dite “table de vérité”
fournissant le résultat de cette opération. Lorsqu’on la fait porter sur deux bits de même rang de
chacun des deux opérandes. Cette table est donnée dans le tableau suivant :
Opérande 1 0 0 1 1
Opérande 2 0 1 0 1
ET(&) 0 0 0 1
OU inclusif (I) 0 1 1 1
OU exclusif (^) 0 1 1 0
L’opérande unaire ~ (“dit de complément à un”) est également de type “bit à bit”. Il se contente
d’inverser chacun des bits de sont unique opérande (0 donne 1 et 1 donne 0).
Notez que la qualificatif signed /unsigned des opérandes n’a pas incidence sur le motif binaire créé
par ces opérateurs.

VI.7.c. Les opérateurs de décalage


Ils permettent de réaliser des “décalages à droite ou à gauche” sur le motif binaire correspondant à
leur premier opérande. L’amplitude du décalage exprimée en nombre de bits est définie par le
second opérande. Par exemple : n << 2
fournit comme résultat la valeur obtenue en décalant le “motif binaire” de n de 2 bits vers la
gauche ; les bits de gauche sont perdus et des bits à zéro apparaissent à droite.
De même n >> 3 fournit comme résultat la valeur obtenue en décalant le “motif binaire” de n de 3
bits vers la droite les bits de droite sont perdus et des bits apparaissent à gauche.
Ces derniers dépendent du qualificatif signe/unsigned du premier opérande. S’il s’agit d’un
unsigned, les bits ainsi créés à gauche seront à zéro. S’il s’agit d’un signed, les bits ainsi crées seront
identiques au bit de signe du premier opérande. On dit qu’il y propagation du bit de signe.
VI.8. LES OPERATEURS D’AFFECTATION ELARGIE
Nous avons déjà vu comment les opérateur d’incrémentation permettaient de simplifier l’écriture
de certaines affectations. Ainsi, par exemple : i++ remplaçait avantageusement : i = i+ 1
Mais C dispose d’opérateurs encore plus puissants. Ainsi, vous pourrez remplacer : i = i+k par: i+= k
ou encore : a = a*b par : a *= b ou même n = n << 3 par : n <<= 3.
D’une manière générale C permet de condenser les affectations de la forme :
Ivalue = Ivalue opérateur expression En : Ivalue opérateur = expression
Cette possibilité concerne tous les opérateurs binaires arithmétiques et de manipulation de bits.
Voici la liste complète de tous ces nouveaux opérateurs nommés “opérateurs d’affectation
élargie“ :
+= -= *= /= %= I= ^= &= <<= >>=
Ces opérateurs, comme ceux d’incrémentation permettent de condense l’écriture de certaines
Instructions et contribuent à éviter le redondance introduite fréquemment par l’opérateur
d’affectation classique.
VI.9. L’OPERATEUR CONDITIONNEL
Considérons cette “structure de choix” :
If(a>b)
max= a;
else
max=b ;
Elle attribut à la variable max la plus grande des deux valeurs de a et de b. La valeur de max pourrait être
définie par cette phrase : Si a>b alors a sinon b
En langage C, il est possible, grâce à laide de “l’opérateur conditionnel”, de traduire presque littéralement la
phrase ci-dessus de la manière suivante : max = a>b ? a : b
L’expression figurant à droite de l’opérateur d’affectation est en fait constituer de trois expressions (a>b, a et b)
qui sont les trois opérandes de l’opérateur conditionnel, lequel se matérialise par 2 symboles séparés : ? et :
D’une manière générale, cet opérateur évalue la première expression qui joue le rôle d’une condition. Comme
toujours en C, celle-ci peut être de n’importe quel type. Si Sa valeur est diffèrent de zéro, il y a évaluation du
second opérande, ce qui fournit le résultat, par contre, si sa valeur est nulle, il y a évaluation du troisième
opérande, ce qui fournit le résultat.
La priorité de l’opérateur conditionnel est faible (il arrive juste avant l’affectation), de sorte qu’il est rarement
nécessaire d’employer des parenthèses pour en délimiter les différents opérandes.
VI.10. LES CONVERSIONS EXPLICITES - L’OPERATEUR DE ‘‘CAST”
Nous avons vu comment le compilateur pouvait être amené à mettre en place des “conversions
implicite” dans l’évaluation de certaines expressions.
par ailleurs, nous avons dit que l’affectation pouvait conduire à la mise en place d’une ”conversion
d’office” dans le cas où le type de l’expression était différent de celui de la “lvalue” réceptrice. De
plus, en C, le programmeur peut, s’il le souhaite, forcer la conversion d’un expression quelconque
dans un type de son choix, à laide d’un opérateur unaire nommé en anglais “cast’
Ces deux sortes de conversions “forcées” (affectation ou “cast”) suivent les mêmes règles, de sorte
qu’il nous suffira de vous les présenter sur l’opérateur de “cast”.

VI.10.a L’opérateur de “cast”


Si, par exemple n et p sont des variables entière (int), l’expression (double) (n/p) aura comme valeur celle de
l’expression entière n/p convertie en double.
La notation (double) correspond en fait à un opérateur unaire dont le rôle est d’effectuer la conversion dans le type
double de l’expression sur laquelle il porte. Notez bien que cet opérateur force la conversion du résultat de
l’expression et non celle des différentes valeurs qui concourent à son évaluation, autrement dit, ici, il y a d’abord
calcul, dans le type bit du quotient de n par p ; c’est seulement ensuite que le résultat sera converti en double.
D’une manière générale, il existe autant d’opérateur “cast” que de types différents (y compris les types dérivés que
nous rencontrerons ultérieurement). Leur priorité élevée fait qu’il est généralement nécessaire de placer entre
parenthèses l’expression concernée. Ainsi, l’expression : (double) n/p conduirait d’abord à convertir n en double ;
les règles de conversions implicites amènerait alors à convertir p en double avant que n’ait lieu la division (en double).
Le résultat serait alors différent de celui obtenu par l’expression donnée en début de ce paragraphe.

VI.11. L’OPERATEUR SEQUENTIEL


L’opérateur dit “séquentiel” permet, en quelque sorte, d’exprimer plusieurs calculs successifs au sein
d’une même expression. Par exemple : a * b, i +j est une expression qui évalue d’abord a * b, puis i+j
et qui prend comme valeur la dernière calculée (donc celle de i + j). Certes, dans cet exemple le
calcul préalable de a*b est inutile, puisqu’il n’intervient pas dans la valeur de l’expression globale et
qu’il ne réalise aucune action.
Par contre, une expression telle que : i++, a+b peut présenter un intérêt puisque la première
expression (dont la valeur ne sera pas utilisée) réalise en fait l’incrémentation de la variable i.
Il en est de même de l’expression suivante : i++, j= i + k
dans laquelle il y a:
• évaluation de l’expression i++,
• évaluation de l’affectation j= i+k, notez alors qu’on utilise la valeur de i après incrémentation par
l’expression précédente.
Cet opérateur séquentiel qui jouit dune associativité de “gauche à droite”, peut facilement faire
intervenir plusieurs expressions (sa faible priorité évite l’usage des parenthèses)
i++, j = i + k, j-- i++; j + i + k; j--
Un tel opérateur peut être utilisé pour réunir plusieurs instructions en une seule. Ainsi, les deux
formulations suivantes sont équivalentes : i++, j = i + k , j-- i++; j= I+k ; j--
Dans la pratique, ce n’est pas là le principal usage de cet opérateur séquentiel. Par contre, ce
dernier pourra fréquemment intervenir dans les instructions de choix ou dans les boucles comme
dans l’exemple suivant if (i++,k>0)…. Remplace i++; if(k>0)…
Remarque importante:
Ne confondez pas l’opérateur séquentiel (,) avec la virgule utilisée (avec la même priorité) comme
séparateur dans une liste d’arguments dans un appel de fonction comme, par exemple
printf (“%d %d”,n+2,p);
Si vous souhaitez utiliser cet opérateur séquentiel dans une telle liste, il est nécessaire d’en placer le
résultat entre parenthèses. Par exemple : printf (“%d %d”,a,(b==5,3*b));
• imprime la valeur de a,
• évalue l’expression : b=5,3*b, ce qui conduit à affecter 5 à b et à calculer ensuite la valeur de 3 *
b.
• afficher la valeur de cette expression, c’est à dire la valeur de 3 * b.
VI.12. L’OPERAXEUR SIZEOF
l’opérateur sizeof dont l’emploi ressemble à celui d’une fonction fournit la taille d’une variable de
nom donné. Par exemple, si x est de type int, l’expression : sizeof(x) vaudra 2
Il peut également s’appliquer à un type de nom donné. Par exemple : sizeof (int) vaut 2
sizeof(long int) vaut 4 sizeof(double) vaut 8
Cet opérateur offre un intérêt :
lorsqu’on souhaite écrire des programmes portables dans lesquels il est nécessaire de connaître la
taille exacte de certains objets.
Pour éviter de calculer soi-même la taille d’objets d’un type relativement complexe pour lequel on
ne sera pas certain de la manière dont il sera “implémenté” par le compilateur. Ce sera notamment
des structures.
Le tableau suivant fournit la liste complète de tous les opérateurs du C, classés par ordre de priorité
décroissante, accompagnés de leurs mode d’associativité.
Notez bien qu’en langage C, un certain nombre de notations servant à “référencer” des objets sont
considérés comme des opérateurs et, entant que tels, soumises à des régies de priorités. Ce sont
essentiellement les références à des élément d’un tableau réalisées par [ ],
CATEGORIE OPERATEURS ASSOCIATIVITE
des références à des champs
Référence () [] -> . —>
de structures : opérateurs - > et Unaire + - ++ -- ! ~ * & (cast) sizeof <—
Arithmétique */ % —>
. , des opérateurs d’adressage :
Arithmétique +- —>
* et &. Décalage << >> —>
Relationnel < <= > >= —>
Ces opérateurs seront étudier
Relationnel == != —>
ultérieurement dans les Manipulation de bits & —>
Manipulation de bits ^ —>
chapitres correspondant,
Manipulation de bits | —>
néanmoins, ils figurent dans le Logique && —>
Logique || —>
tableau proposé
Conditionnel :? —>
Affectation = += -= *= /= %= &= ^= |= <<= <—
>>=
Séquentiel , —>

Vous aimerez peut-être aussi