Chapitre suivantIndex des CoursChapitre précedentChapitre 4

LES OPERATEURS ET LES EXPRESSIONS

 

Eléments de contenu :

1- LES OPERATEURS ARITHMETIQUES

I.1 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

 

*

produits

 

/

quotient

 

%

reste de division (modulo)

Unaire

-

opposé

 

+

Identité

A l’exception de l’opérateur “%“ qui ne peut porter que sur des entiers, ces opérateurs peuvent s’appliquer à tous les types numériques. Cela signifie qu’un même symbole tel que ”*” définit on fait plusieurs opérations différentes suivant le type 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 e deux entiers soit un entier, les choses sont moins évidentes pour l’opérateur quotient (“/”). Ainsi par exemple, 5/2 est le quotient de deux valeurs doubles, et à ce titre fournit bien le résultat 2.5 qui est aussi (le type double. Par contre 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.

L2 Leurs priorités relatives

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 on suite à un même niveau es 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 porte en forçant e calcul préalable de l’expression qu’elles contiennent. Notez que ces parenthèses peuvent également être employées jour 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%c)
                                     -c % d                                            (-c)%d
                                     -a/-b+c                                          ((-a)/(-b))+c

Il- 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.

11.1     Exemples de conversions implicites sur des types numériques

Supposons que nous avons effectué les déclarations suivantes :

int, 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

p + 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 floa.t(moyennant une conversion supplémentaire ).

II .2 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 on 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 aura 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 qu’en soit calculée la différence. Le résultat est de type int.

II-3 Règles générales de con version implicite

a) Conversions systématiques et conversion  d’ajustement de type

Comme on a vu dans es 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.

b)  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)

c)  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 prévoir que unsigned .

III- 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

Inférieur à

<=

Inférieur ou égal à

Supérieur à

>=

Supérieur ou égal à

= =

Egal à

!=

Différent de

En ce qui concerne leurs priorités, il faut savoir  que les quatre premiers opérateurs (<, <=, >, <=) sont de même priorité. Les deux derniers (== et ! =) possédant également la même priori té, mais celle-ci est inférieure à celle des précédents. Ainsi l’expression

a <b == c< d

est interprétée 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, les opérateurs arithmétiques. Cela permet souvent d’éviter certaines parentheses dans des expressions. Ainsi :

x + y < a+2

est équivalent à

(x+y ) < (a + 2)

IV- LES 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 I (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’import e 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//p                  !n

sont acceptées par le compilateur. Notez que Ion 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 :

t

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 // 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 // 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).

V- L’OPERATEUR D’AFFECTATION SIMPLE

V. 1 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 suivante n’aurait pas de sens.

               c+5=x

V.2 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.

On langage C, la syntaxe du langage est lette 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.

V.3 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- LES OPERATEURS D’INCREMENTATION ET DE DECREMENTATION

VI.1 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 de après 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.2 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.3Leur 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.

VII- LES OPERATEURS DE MANIPULATION DE BITS

VII.1Pré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)

VII.2 Les opérateurs “bit à bit”

Les trois opérateurs &, I et  ^ appliquent en fait la même opération à chacun des bits dés deux opérandes. Leur résultat peut ainsi être défini à partir ‘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.

VII..3 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.

VIII- 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.

IX- L’OPERATEUR CONDITIONNEL

Considérons cette “structure de choix” :

If(a>b)

max= a;

p

e/se

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.

X-  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”.

X.1  L’opérateur de “cast”
Si, par exemple n et p sont des variables entière, 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 je 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.

Xl- 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.

XII- 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 [ ],
des références à des champs de structures : opérateurs - > et . ,
des opérateurs d’adressage : * et &.

Ces opérateurs seront étudier ultérieurement dans les chapitres correspondant, néanmoins, ils figurent dans le tableau proposé

CATEGORIE

OPERATEURS

ASSOCIATIVITE

Référence

() [] -> .

—>

Unaire

+ - ++ -- ! ~ * & (cast) sizeof

­­­­­­­­­­­­­­<—

Arithmétique

* /  %

—>

Arithmétique

+ -

—>

Décalage

<< >>

—>

Relationnel

< <=> > =

—>

Relationnel

== !=

—>

Manipulation de bits

&

—>

Manipulation de bits

^

—>

Manipulation de bits

|

—>

Logique

&&

—>

Logique

||

—>

Conditionnel

:?

—>

Affectation

= += -= *= /= %= &= ^= |= <<= >>=

<—

Séquentiel

,

—>

Chapitre précedentIndex des CoursChapitre suivant

Révisé le :23-Sep-2007| ©2007 www.technologuepro.com