• Aucun résultat trouvé

Cours Informatique SMC S4 Idrissi Yassine

N/A
N/A
Protected

Academic year: 2022

Partager "Cours Informatique SMC S4 Idrissi Yassine"

Copied!
42
0
0

Texte intégral

(1)

SMC S4

Idrissi Yassine

(2)

Langage C

(3)

Historique

— En 1972, dans les ”Bell Laboratories”, Dennis M. Ritchie a con¸cu le Langage C pour d´evelopper une version portable du syst`eme d’exploitationUNIX.

— En1978, le duo Brian W. Kernighan et I Dennis M. Ritchie a publi´e la d´efinition classique du langage C(connue sous le nom de standard K &R-C).

— En 1983, le ”American National Standard Institute”(ANSI) chargeait une commission de mettre au point une d´efinition explicite et ind´ependante de la machine pour le langage C. Le r´esultat ´etait le standard AINSI-C.

Caract´ eristiques

C’est un langage :

— universel : C permet aussi bien la programmation syst`eme que la programmation de divers applications (scientifiques, de gestion,...).

— de haut niveau : C est un langage structur´e (offre plusieurs structures de contrˆole) et typ´e (d´eclarations obligatoires).

— pr`es de la machine : Offre des op´erateurs qui sont tr`es proches de ceux du langage machine et des fonctions qui permettent un acc`es simple et direct aux fonctions internes de l’ordinateur (par exemple : les op´erateurs de d´ecalage des bits et l’acc`es aux registres).

— ind´ependant de la machine :peut ˆetre utilis´e sur n’importe quel syst`eme en possession d’un compilateur C.

— portable : en respectant le standard ANSI-C, il est possible d’utiliser le mˆeme pro- gramme sur d’autres compilatuers.

— ...

Phases de la programmation en C

Il ya trois grandes ´etapes concernant la cr´eation d’un programme en langage C `a savoir :

´edition du programme, compilation et ´edition de liens.

L’´edition du programme (on dit aussi parfois«saisie») consiste `a cr´eer, `a partir d’un clavier, tout ou partie du texte d’un programme qu’on nomme programme source. En g´en´eral, ce texte sera conserv´e dans un fichier que l’on donnera un nom ”fichier source” et qui portera l’extension C.

La compilation permet de transformer notre code en un vrai programme ex´ecutable, Si le

(4)

code source contient des erreurs, le compilation ´echoue et les erreurs sont affich´e pour que le programmeur les corrige.

L’´edition des liens permet de rechercher dans la biblioth`eque standard les fonctions pr´ed´efinies (on dit aussi «fonctions standard») utilis´ees par votre programme. Le r´esultat de l’´edition de liens est ce que l’on nomme un programme ex´ecutable. Si ce programme ex´ecutable est rang´e dans un fichier, il pourra ult´erieurement ˆetre ex´ecut´e sans qu’il soit n´ecessaire de faire appel `a un quelconque composant de l’environnement de programmation en C.

(5)

Notion de Base

1.1 Premier programme en langage C

Ce programme affiche le message : ”Bonjour tout le monde”

/* Premier programme enC */

#include<stdio.h>

#include<stdlib.h>

main() {

printf(”Bonjour tout le monde\n”) ; system(”pause”) ;

}

— Les commentaires sont des textes explicatifs destin´es aux lecteurs du programme, ils n’ont aucune incidence sur sa compilation et sur son ex´ecution. Les commentaires d´ebutent par /* et se terminent par */. Si le commentaire est court et tient sur une seule ligne on peut taper un double slash (//) suivi de notre commentaire. Par exemple : // ceci est un commentaire.

— #include<stdio.h> informe le compilateur d’inclure le fichier stdio.h qui contient les fonctions d’entr´ees-sorties (i pour input et o pour output), dont la fonction printf et#in- clude<stdlib.h>informe le compilateur d’inclure le fichier stdlib.h (contient la fonction system) qui permet d’interagir avec le syst`eme d’exploitation sur lequel le programme s’ex´ecute.

— La fonction main est la fonction principale des programmes en C : Elle se trouve obliga- toirement dans tous les programmes.

— L’appel de printf avec l’argument ”Bonjour tout le monde\n” permet d’afficher sur l’´ecran : Bonjour et \n ordonne le passage `a la ligne suivante.

— En C, toute instruction simple est termin´ee par un point-virgule ;

1.2 Les types de base du langage C

Un type de donn´es repr´esente un ensemble de valeurs d’une mˆeme nature. Pour faire simple, on peut parler du type entier (qui repr´esente l’ensemble des valeurs num´eriques enti`ere et relative : par exemple : 1, 2, 3, 4, ...), du type flottant (3.1415926, 4.4, ...) .... Les types de base du langage

(6)

C se r´epartissent en trois grandes cat´egories en fonction de la nature des informations qu’ils permettent de repr´esenter :

— nombres entiers (mot cl´e int),

— nombres flottants (mot cl´e float ou double),

— caract`eres (mot cl´e char) ; nous verrons qu’en fait char apparaˆıt (en C) comme un cas particulier de int.

1.2.1 Le type entier

Les diff´erents types d’entiers

Le C pr´evoit que, sur une machine donn´ee, on puisse trouver jusqu’`a trois tailles diff´erentes d’entiers, d´esign´ees par les mots-cl´es suivants :

— short int (qu’on peut abr´eger en short),

— int,

— long int (qu’on peut abr´eger en long).

Caract´eristiques :

D´efinition Valeur minimale Valeur maximale Nombre d’octets

short -32768 32767 2

int -32768 32767 2

long -2147483648 2147483647 4

Le type short est en g´en´eral cod´e dans 2 octets. Comme une variable int occupe aussi 2 octets sur notre syst`eme, le type short devient seulement n´ecessaire, si on veut utiliser le mˆeme programme sur d’autres machines, sur lesquelles le type standard des entiers n’est pas forc´ement 2 octets.

Si on ajoute le pr´efixe unsigned `a la d´efinition d’un type de variables enti`eres, les domaines des variables sont d´eplac´es comme suit :

D´efinition Valeur minimale Valeur maximale Nombre d’octets

unsigned short 0 65535 2

unsigned int 0 65535 2

unsigned long 0 4294967295 4

Notation des constantes enti`eres : La fa¸con la plus naturelle d’introduire une constante enti`ere dans un programme est de l’´ecrire simplement sous forme d´ecimale, avec ou sans signe, comme dans ces exemples :

+533 48 −273

1.2.2 Les types flottants

Les types flottants permettent de repr´esenter, de mani`ere approch´e, une partie des nombres r´eels. Le C prevoit que, sur une machine donn´ee, on puisse trouver jusqu’`a trois types de r´eels : Le type float pour les nombres d´ecimaux en simple pr´ecision, double pour les nombres d´ecimaux en double pr´ecision et long double pour les r´eels de tr`es grande pr´ecision.

(7)

D´efinition Plage de valeurs accept´ee Nombre d’octets float ±3.4×10−38 `a ±3.4×1038 4

double ±1.7×10−308 `a ±1.7×10308 8 long double ±3.4×10−4932 `a ±3.4×104932 10

1.2.3 Le type char

le type char permet de stocker des nombres compris entre −128 et 127. En pratique le type char sert surtout au stockage de lettres. Chaque lettre poss`ede son ´equivalent en code num´erique : c’est le code ASCII (American Standart Code for Information Interchange). Par exemple, 97 est l’´equivalent ASCII de la lettre a.

Le langage C permet de faire tr`es facilement la traduction lettre ←→nombre correspondant.

Pour obtenir le nombre associ´e `a une lettre, il suffit d’´ecrire cette lettre entre apostrophes, comme ceci : ’A’. `A la compilation, ’A’ sera remplac´e par la valeur correspondante.

Type de donn´ees signification Nombre d’octets Plage des valeurs accept´ees

Char Caract`ere 1 -128`a 127

unsigned char Caract`ere non sign´e 1 0`a 255

1.3 Les variables

Une variable correspondra `a une portion de m´emoire, `a laquelle nous donnerons un nom. Ce nom permettra d’identifier notre variable. Nous allons ainsi pouvoir nommer les donn´ees que nous manipulons. En utilisant ce nom dans votre programme, vous adressez la donn´ee qui y est stock´ee.

1.3.1 Les noms de variable

Avant d’utiliser une variable dans votre programme, vous devez cr´eer un nom de variable qu’on appelle identificateurqui doit respecter plusieurs r`egles :

— Ce nom (=identificateur) peut contenir des lettres, des chiffres et le caract`ere .

— Le premier caract`ere doit ˆetre une lettre. Le caract`ere ( ) est aussi autoris´e, mais il n’est pas recommand´e.(les espaces ne sont pas autoris´es).

— Les lettres majuscules sont diff´erentes des minuscules. Par exemple, compte et Compte ne repr´esentent pas la mˆeme variable.

— Il ne faut pas utiliser les mots cl´es, ils font partie du langage C. Voici la liste compl`ete des 33 mots cl´es du C :

asm auto double int struct break else long switch case enum register typedef char extern return union continue for signed void do if static while default goto sizeof volatile const float short unsigned

— Il ne faut pas utiliser les caract`ere sp´eciaux : , < > . - ( ) ; $ : % [ ] # ? ’ & ” ˆ ! * / | - +

(8)

Nom de la variable Validit´e

Pourcent Correct

y2x5fg7h Correct

profit annuel Incorrect : contient espace 1990 Correct, mais d´econseill´e

compte#courant Incorrect : contient le caract`ere interdit # double Incorrect : double est un mot cl´e

9puits Incorrect : le premier caract`ere est un chiffre

1.3.2 D´ eclaration et initialisation des variables

En C, toute variable utilis´e dans un programme doit auparavant ˆetre d´efinie. La d´efinition d’une variable consiste `a la nommer et lui donner un type. C’est cette d´efinition qui r´eserve (on dira alloue) la place m´emoire n´ecessaire en fonction du type. Initialiser une variable consiste `a remplir, avec une constante, la zone m´emoire r´eserv´ee `a cette variable. Cette op´eration s’effectue avec l’op´erateur =.

Pour d´eclarer une variable, il suffit de :

— Indiquer le type de la variable `a cr´eer ;

— Ins´erer un espace ;

— Indiquer le nom (identificateur) attribu´e `a la variable, en respectant les r`egles de nomination concernant les identificateurs ;

— Enfin, de ne pas oublier le point-virgule, indispensable pour toute instruction en C.

Syntaxe : typeVariable nomVariable ;

On peut d´eclarer plusieurs variables du mˆeme type sur une seule ligne en les s´eparant par des virgules, par exemple :

— double z ; /* une seul variable double */

— int count, number, start ; /* trois variables enti`eres */

— float percent, total ; /* deux variables `a virgule flottante */

La d´eclaration de variable permet au compilateur de r´eserver l’espace m´emoire destin´e `a cette variable. La donn´ee qui sera stock´ee dans cet emplacement, la valeur de la variable, n’est pas encore d´efinie. Avant d’ˆetre utilis´ee, la variable d´eclar´ee doit ˆetre initialis´ee. Cela peut se faire en utilisant une instruction d’initialisation comme dans notre exemple :

— int count ; /* R´eservation de la m´emoire pour count */

— count = 0 ; /* Stocke 0 dans count */

Le signe ´egal fait partie des op´erateurs du langage C. En programmation, ce signe n’a pas le mˆeme sens qu’en alg`ebre. Si vous ´ecrivez : x = 12 dans une instruction alg´ebrique, vous ´enoncez un fait :

”x = 12”. En langage C, la signification est diff´erente : ”donner la valeur 12 `a la variable appel´ee x”. Vous pouvez initialiser une variable au moment de sa d´eclaration. Il suffit de faire suivre le nom de variable, dans l’instruction de d´eclaration, du signe ´egal suivi de la valeur initiale : Exemple des cas possibles :

— D´eclaration avec initialisation : int x=1 ;

— D´eclaration seule : double y ;

— D´eclaration de plusieurs variables de mˆeme type : char c, ch ;

— D´eclarations avec initialisations pour plusieurs variables de mˆeme type sur la mˆeme ligne s´epar´ees par une virgule : int a=2, b=6 ;

(9)

Attention, il ne faut pas initialiser la variable avec une valeur qui ne correspond pas au type d´eclar´e. Voici deux exemples d’initialisations incorrectes :

— int poids = 100000 ;

— unsigned int valeur = -2500 ;

Le compilateur ne d´etecte pas ce genre d’erreur, et le programme pourrait vous donner des r´esul- tats surprenants.

Remarque

Il n’existe pas de valeur par d´efaut pour les variables en langage C. Lors d’une d´eclaration sans initialisation, la variable prend la valeur qui se trouvait l`a avant dans la m´emoire, et cette valeur peut ˆetre n’importe quoi ! Il est donc toujours recommand´e d’initialiser la variable d`es qu’on la d´eclare.

1.3.3 Les constantes

Le langage C poss`ede deux types de constantes qui ont chacune un usage sp´ecifique.

Les constantes litt´erales

Une constante litt´erale est une valeur qui est introduite directement dans le code source. Voici deux exemples :

— int count = 20 ;

— float tax rate = 0.28 ;

20 et 0.28 sont des constantes litt´erales. Ces deux instructions stockent ces valeurs dans les variables count et tax rate. La valeur qui contient un point d´ecimal (.) est une constante `a virgule flottante, l’autre est une constante enti`ere. Par exemple 3 est consid´er´e comme une constante enti`ere

Comme dans la plupart des langages, les constantes flottantes peuvent s’´ecrire indiff´eremment suivant l’une des deux notations : d´ecimale ou exponentielle. La notation d´ecimale doit com- porter obligatoirement un point (correspondant `a notre virgule). La partie enti`ere ou la partie d´ecimale peut ˆetre omise (mais, bien sˆur, pas toutes les deux en mˆeme temps !). En voici quelques exemples corrects :

12.43 −0.38 384. .27

La notation exponentielle utilise la lettre e (ou E) pour introduire un exposant entier (puissance de 10), avec ou sans signe. Voici quelques exemples corrects (les exemples d’une mˆeme ligne ´etant

´equivalents) :

4.25E4 −542.7e−33 48.0E13

Par d´efaut, toutes les constantes flottantes sont cr´e´es par le compilateur dans le type double. Pour imposer `a une constante flottante d’ˆetre du type float, on suit son ´ecriture de la lettre F (ou f).

Toute repr´esentation d’une constante `a virgule flottante doit inclure le point d´ecimal, par exemple 3 (sans le point d´ecimal) est consid´er´e comme une constante enti`ere, alors que 3. est consid´er´e comme une constante flottante.

Les constantes litt´erales de type caract`ere se note entre apostrophes : ’a’ ’2’.

(10)

1.3.4 Les constantes symboliques

Une constante symbolique est un emplacement m´emoire utilis´e par votre programme. `A l’in- verse d’une variable, la valeur stock´ee dans une constante symbolique ne peut changer pendant l’ex´ecution du programme. Les constantes symboliques permettent au programmeur de cr´eer un nom pour une constante et d’utiliser ce nom tout au long du programme. Les constantes symbo- liques se d´efinissent `a l’aide de la directive

#define Nom constante

Le Nom devient alors un nom symbolique qui peut ˆetre utilis´e partout o`u l’on veut faire figurer la constante. Par exemple,

#define PI 3.14159

Remarquez que cette instruction ne se termine pas par un point-virgule ( ;). La commande #define peut se trouver n’importe o`u dans le code source, mais son effet est limit´e `a la partie de code qui la suit. En g´en´eral, les programmeurs groupent tous les #define ensemble, au d´ebut du fichier, avant la fonction main().

Il est possible de d´eclarer que la valeur d’une variable ne doit pas changer lors de l’ex´ecution du programme. Par exemple, avec :

const int n = 20 ;

on d´eclare n de type int et de valeur (initiale) 20 mais, de surcroˆıt, les ´eventuelles instructions modifiant la valeur den seront rejet´ees par le compilateur.

On pourrait penser qu’une d´eclaration (par const) remplace avantageusement l’emploi de define. En fait, nous verrons que les choses ne sont pas aussi simples, car les variables ainsi d´eclar´ees ne pourront pas intervenir dans ce qu’on appelle des«expressions constantes»(notamment, elles ne pourront pas servir de dimension d’un tableau !).

1.4 Instructions, expressions et op´ erateurs

Les programmes C sont constitu´es d’instructions qui contiennent, pour la plupart, des expres- sions et des op´erateurs.

1.4.1 Les instructions

Une instruction repr´esente une tˆache `a accomplir par l’ordinateur. En langage C, on ´ecrit une instruction par ligne et elle se termine par un point-virgule (`a l’exception de #define et #include ). Par exemple :

x = 2 + 3 ;

est une instruction d’affectation. Elle demande `a l’ordinateur d’ajouter 2 et 3 et d’attribuer le r´esultat `a la variable x.

Quand le compilateur lit une instruction, il ignore absolument tous espace, tabulation ou ligne de blancs du code source. Par exemple, l’instruction :

x=2+3 ;

(11)

est ´equivalente `a :

x = 2 + 3 ; ou mˆeme `a :

x = 2 + 3 ;

Cela nous laisse une grande libert´e pour la mise en page de notre code.

Un bloc (ou instructions compos´ees) est un groupe d’instructions entre accolades : {

printf(”Hello,”) ; printf(”world !”) ; }

Les accolades peuvent se positionner de diff´erentes fa¸cons. L’exemple suivant est ´equivalent au pr´ec´edent :

{printf(”Hello,”) ; printf(”world !”) ;}

En pla¸cant les accolades sur une ligne s´epar´ee, nous identifierons plus facilement le d´ebut et la fin du bloc, et nous ´eviterons d’en oublier une.

1.4.2 Les op´ erateurs

Les op´erateurs sont des symboles qui permettent de manipuler des variables, c’est-`a-dire ef- fectuer des op´erations sur les variables, les ´evaluer, etc. En langage C, les op´erateurs sont divis´ees en quatre cat´egories :

— l’op´erateur d’affectation ;

— les op´erateurs math´ematiques ;

— les op´erateurs de comparaison ;

— les op´erateurs logiques.

L’op´erateur d’affectation

L’op´eration la plus importante dans un langage de programmation est celle qui consiste `a donner une valeur `a une variable (ou un tableau). Cette op´eration est d´esign´ee par le symbole =.

Sa syntaxe est la suivante :

variable = expression

Le terme de gauche de l’affectation (variable) peut ˆetre une variable simple, un ´el´ement de tableau mais pas une constante. Cette op´eration a pour effet d’affecter la valeur de expression `a variable.

De plus, variable = expression poss´ede une valeur, qui est celle de expression. Ainsi, l’expression i = 5 vaut 5.

On rappelle que L’instruction d’affectation est l’op´eration qui consiste `a attribuer une valeur

`

a une variable, elle est diff´erentte de l’op´erateur ´egale : ==, A == B signifiera«est-ce que A est

´egal `a B»? Et la r´eponse sera alors soit vrai soit faux.

(12)

Les op´erateurs math´ematiques

Les op´erateurs math´ematiques de C r´ealisent des op´erations math´ematiques comme l’addition ou la soustraction. Il en existe deux unaires et cinq binaires.

Op´erateurs math´ematiques binaires

Les op´erateurs binaires du langage C travaillent avec deux composants.

Op´erateur Symbole Op´eration Exemple

Addition + Additionne les deux composant x + y

Soustraction - Soustrait la valeur du second composant `a la valeur du premier x-y

Multiplication * Multiplie les deux composant x * y

Division / Divise le premier composant par le second x / y

Modulo % Donne le reste de la division du premier composant par le second x % y

Une chose importante doit ˆetre pr´ecis´ee concernant la division : quand les deux nombres manipul´es sont de type entier, il s’agit d’une division enti`ere. Autrement dit, le quotient sera un entier et il peut y avoir un reste. Par exemple, 15/6, ne donnera pas 2,5 (division r´eelle), mais 2.

Le modulo est un peu le compl´ement de la division enti`ere : au lieu de donner le quotient, il renvoie le reste d’une division euclidienne. Par exemple, le modulo de 15 par 6 est 3, car 15 = 2

×6 + 3.

Avec les types flottants, la division se comporte autrement et n’est pas une division avec reste.

La division de deux flottants donnera un r´esultat«exact», avec potentiellement plusieurs chiffres apr`es la virgule.

Les op´erateurs math´ematiques unaires :

Les op´erateurs unaires op`erent sur une seule variable.

Op´erateur Symbole Op´eration Exemples

Incr´ementation ++ Augmente de 1 la valeur de la variable ++x, x++

D´ecr´ementation −− D´ecr´emente de 1 la valeur de la variable x −−x, x−−

Les op´erateurs d’incr´ementation ++ et de d´ecr´ementation −− s’utilisent aussi bien en suf- fixe (i++)/(i−−) qu’en pr´efixe (++i)/(−−i). Dans les deux cas la variable i sera incr´emen- t´ee/d´ecr´ement´ee. Toutefois dans le cas incr´ementation/d´ecr´ementation d’une variable et en mˆeme temps affecter sa valeur `a une autre variable, on doit choisir entre la notation suffixe et pr´efixe :

— X = I++ passe d’abord la valeur de I `a X et incr´emente apr`es.

— X = I−− passe d’abord la valeur de I `a X et d´ecr´emente apr`es.

— X = ++I incr´emente d’abord et passe la valeur incr´ement´ee `a X.

— X = −−I d´ecr´emente d’abord et passe la valeur d´ecr´ement´ee `a X.

Exemple

Supposons que la valeur de N est ´egal `a 5 :

— X = N++ ; R´esultat : N=6 et X=5.

— X = ++N ; R´esultat : N=6 et X=6.

(13)

Les op´erateurs d’affectation compos´es

Ces op´erateurs compos´es permettent d’associer une op´eration math´ematique binaire avec une op´eration d’affectation. Pour, par exemple, augmenter la valeur de x de 5, il faut ajouter 5 `a x et stocker le r´esultat dans la variable x :

x = x + 5 ;

L’op´erateur compos´e permet d’´ecrire : x += 5 ;

Les op´erateurs d’affectation compos´es ont la syntaxe suivante (op repr´esente un op´erateur bi- naire) :

exp1 op= exp2 ;

qui est l’´equivalent de : exp1 = exp1 op exp2 ;

Nous pouvons cr´eer un op´erateur compos´e `a partir des cinq op´erateurs math´ematiques binaires.

Le Tableau suivant donne quelques exemples :

Expression Equivalent´ x *= y x = x * y a /= b a = a / b x += y / 8 x = x + y / 8

y %= 3 y = y % 3

Comme pour toutes les autres instructions d’affectation, ce type d’instruction est une expression dont la valeur est affect´ee `a la variable situ´ee `a gauche. Si vous ex´ecutez l’instruction suivante, les deux variables x et z auront la valeur 14 :

x = 12 ; z = x += 2 ;

Les op´erateurs de comparaison

Les op´erateurs de comparaison sont utilis´es pour comparer des expressions en posant des questions du type«x est-il plus grand que 100 ?»ou «y est-il ´egal `a 0 ?». Leur syntaxe est

expression-1 op expression-2

Les deux expressions sont ´evalu´ees puis compar´ees. La valeur rendue est de type int ; elle vaut 1 si la condition est vraie, et 0 sinon.

Op´erateur Symbole Question pos´ee Exemple

Egal´ == La premi`ere composante est-elle ´egal `a la seconde ? x == y Sup´erieur > Le premi`ere composante est-elle plus grand que la seconde ? x>y

Inf´erieur < La premi`ere composante est-elle plus petit que la seconde ? x<y Sup´erieur ou ´egal >= La premi`ere composante est-elle sup´erieur ou ´egal `a la seconde ? x>= y

Inf´erieur ou ´egal <= La premi`ere composante est-il inf´erieur ou ´egal `a la seconde ? x<= y Diff´erent != La premi`ere composante est-elle diff´erente de la seconde ? x != y

Exemples d’utilisations des op´erateurs de comparaison

Expression Signification Valeur

5 == 1 La valeur 5 est-elle ´egale `a 1 ? 0

5> 1 5est-elle plus grande que 1 ? 1

5 != 1 La valeur 5 est-elle diff´erente de 1 ? 1 (5 + 10) == (3 * 5) L’expression (5 + 10) est-elle ´egale `a (3 * 5) ? 1

(14)

Attention :

— Il faut Comprendre que le langage C interpr`ete une expression vraie comme ayant la valeur 1 et une expression fausse comme ayant la valeur 0.

— Attention `a ne pas confondre l’op´erateur de test d’´egalit´e == avec l’op´erateur d’affecta- tion=.

Les op´erateurs logiques

Les op´erateurs logiques de C permettent de v´erifier si plusieurs conditions sont vraies :

Expression Valeur

(exp1 && exp2) Vraie si exp1 et exp2 vraies. Sinon faux

(exp1 || exp2) Vraie si exp1 vraie ou exp2 vraie. Faux si les deux expressions sont fausses.

( !exp1) Faux si exp1 est vraie. Vraie si exp1 est fausse.

Exemples

Expression Valeur

(5 == 5) && (6 != 2) Vraie, car les deux composantes sont vrais (5> 1)|| (6 <1) Vraie, car un composant est vrai (2 == 1) && (5 == 5) Faux, car un composant est faux

!(5 == 4) Vrai, car le composant est faux

Comme pour les op´erateurs de comparaison, la valeur retourn´eee par ces op´erateurs est un int qui vaut 1 si la condition est vraie et 0 sinon.

l’´evaluation se fait de gauche `a droite et s’arrˆete d`es que le r´esultat final est d´etermin´e. Par exemple dans :

int i ; float p=12 ;

if ((i>= 0) && (i<= 9) && !(p == 0)) ...

la derni`ere clause ne sera pas ´evalu´ee si i n’est pas entre 0 et 9.

1.4.3 Expression

Une expression est une suite de composants ´el´ementaires syntaxiquement correcte, par exemple : i =0

i++

printf(” Bonjour !\n”) a=(5*x+10*y)*2 (a+b)>=100 position !=limite

Les constantes et les variables sont des expressions. Les expressions peuvent ˆetre combin´ees entre elles par des op´erateurs et former ainsi des expressions plus complexes.

La valeur d’une constante litt´erale est sa propre valeur. La valeur d’une constante symbolique est celle qui a ´et´e d´efinie au niveau de l’instruction #define. La valeur courante d’une variable est celle qui lui a ´et´e attribu´ee par le programme.

(15)

En C toutes les expressions sont ´evalu´ees et retournent une valeur comme r´esultat : (3+2==5) retourne la valeur 1 (vrai)

A=5+3 retourne la valeur 8

Quand une expression contient plusieurs op´erateurs, son ´evaluation d´epend de l’ordre dans lequel les op´erations sont effectu´ees. Ce concept de hi´erarchie est expliqu´e plus loin dans le cha- pitre.

Une instruction est une expression suivie d’un point-virgule. Le point-virgule signifie en quelque sorte «´evaluer cette expression».

1.4.4 Priorit´ e et associativit´ e des op´ erateurs

Lors de l’´evaluation des diff´erentes parties d’une expression, les op´erateurs respectent certaines lois depriorit´e et d’associativit´e :

— Les exrpressions sont ´evalu´ees en fonction de l’ordre de priorit´e des op´erateurs.

— Dans une expression, les parehth`eses forcent la priorit´e. Elles permettent aussi une meilleure lisibilit´e des expressions.

— Les op´erateurs de plus grande priorit´e sont ´evalu´es en premier.

— En cas d’op´erateurs demˆeme priorit´e, c’est l’associativit´ede l’op´erateur qui d´etermine le sens d’´evaluation de l’expression.

— Un op´erateur a une associativit´e de droite `a gauche (←−) quand : a op b op c signifie a op ( b op c). (op= op´eration).

— Un op´erateur a une associativit´e de gauche `a droite (−→) quand : a op b op c signifie (a op b) op c.

Nous donnons ci-dessous le tableau des diff´erents op´erateurs avec leurs priorit´es class´es par ordre d´ecroissant, et leurs associativit´e.

Op´erateur Associativit´e

() [] -> . −→

! ˜ +(unaire) -(unaire) ++ −− ∗ & ←−

∗ / % −→

+(binaire) -(binaire) −→

<< >> −→

< <= > >= −→

== != −→

&(et bit-`a-bit) −→

ˆ −→

| −→

&& −→

|| −→

? : ←−

= += -= *= /= %= &= ˆ= |= <<= >>= ←−

, −→

Exemples :

— La multiplication a la propri´et´e sur l’addition, l’expression x+y ∗c est ´evalu´e comme x+(y*z).

(16)

— La multiplication et l’addition ont la priorit´e sur l’affectation.

— L’op´erateur + ´etant associatif de gauche `a droite, l’expression x+y+z est ´evalu´e comme (x+y)+z.

8/4*6 8*6/4 28/(3*4)

↓ ↓ ↓

2*6 48/4 28/12

↓ ↓ ↓

12 12 12

Les op´erateurs * et / se situent au mˆeme niveau de priorit´e. L’op´erateur le plus `a gauche dans l’expression est d’abord trait´e. Dans le troisi`eme exemple, les parenth`eses sont d’abord trait´ees car elles sont prioritaires. Ainsi, 8/4*6 ne signifie pas qu’on divise 8 par 4*6, autrement dit, 8 par 24. Il faut appliquer syst´ematiquement les r`egles de priorit´e, mˆeme dans les cas apparement simples.

Remarque :

Op´erateur Traduction Exemple R´esultat

+(unaire) Signe positif +x la valeur de x

-(unaire) Signe n´egatif -x la n´egation arithm´etique de x [] El´ement de tableau t[i] L’´element du tableau t d’indice i.

˜-> . & << >> Hors du programme SMC S4 Les op´erateurs conditionnels :

<expr1>? <expr2> : <expr3>

Si<expr1> fournit une valeur diff´erente de z´ero, alors la valeur de <expr2> est fournie comme r´esultat. Si<expr1>fournit la valeur z´ero, alors la valeur de<expr3>est fournie comme r´esultat.

1.4.5 Les fonctions arithm´ etiques standard

Le fichier d’en-tˆete<math.h>d´eclare des fonctions math´ematiques. Pour pouvoir les utiliser, le programme doit contenir la ligne :

#include<math.h>

Tous leurs param`etres et r´esultat sont de type double

(17)

Commande en C En math´ematiques

exp(X) eX

log(X) ln(X), X >0

log10(X) log10(X), X > 0

pow(X,Y) XY

sqrt(X) √

X, X >0

f abs(X) |X|

f loor(X) arrondir en moins int(X)

ceil(X) arrondir en plus

f mod(X,Y) reste rationnel de X/Y (mˆeme signe que X) pour X diff´erent de 0

sin(X) cos(X) tan(X) sinus, cosinus, tangente deX

asin(X) acos(X) atan(X) arcsin(X), arccos(X), arctan(X) sinh(X) cosh(X) tanh(X) sinus, cosinus, tangente hyperboliques de X

1.5 Les conversions de type

On appelle conversion de type de donn´ees le fait de modifier le type de donn´ee en une autre.

Elle a pour but de changer le type d’une valeur, sans changer cette valeur si c’est possible.

La grande souplesse du langage C permet de m´elanger des donn´ees de diff´erents types dans une expression. Avant de pouvoir calculer, les donn´ees doivent ˆetre converties dans un mˆeme type.

La plupart de ces conversions se passent automatiquement, sans l’intervention du programmeur, qui doit quand mˆeme pr´evoir leur effet. Parfois il est n´ecessaire de convertir une donn´ee dans un type diff´erent de celui que choisirait la conversion automatique ; dans ce cas, nous devons forcer la conversion `a l’aide d’un op´erateur sp´ecial (”cast”).

1.5.1 La conversion implicite ou automatique

Une conversion implicite consiste en une modification du type de donn´ee effectu´ee automati- quement par le compilateur.

Si on regroupe dans une mˆeme expression des types de donn´ees diff´erents, le compilateur proc`ede `a une conversion des types selon les r`egles suivantes :

— Le typeplus petit est converti eu type plus large.

— Ainsi un char en pr´esence d’un int sera converti en int ( la valeur correspondante sera alors le code ASCI du caract`ere correspondant), un int en pr´esence d’un float sera converti en float.

— Deux r´eel : il est choisit le plus large des deux types selon l’´echelle : float, double, long double.

— Il est aussi important de noter que dans une expression d’affectation le compilateur proc`ede `a une conversion implicite en changeant le type de la variable `a droite au type de la variable `a gauche.

— Les r`egles de conversion de types s’appliquent aussi aux op´erateurs conditionnels ? :Ainsi, pour un entier N du type int et un rationnel F du type float, l’expression

(N>0) ? N : F

va toujours fournir un r´esultat du type float, n’importe si N est plus grand ou plus petit que z´ero.

D´etaillons maintenant les r`egles de conversions automatiques lors d’une op´eration avec,

(18)

— deux entiers :

D’abord, les types char et short sont convertis en int. Ensuite, l’ordinateur choisit le plus large des deux types dans l’´echelle suivante :

int, unsigned int, long, unsigned long

— un entier et un rationnel : Le type entier est converti dans le type du rationnel.

— deux rationnels :

L’ordinateur choisit le plus large des deux types selon l’´echelle suivante : float, double, long double

— affectations et op´erateurs d’affectation :

Lors d’une affectation, le r´esultat est toujours converti dans le type de la destination. Si ce type est plus faible, il peut y avoir une perte de pr´ecision.

Exemples

int x ; x=8.324 ;

x contiendra apr`es affectation la valeur 8.

char a=’A’ ; int b=32 ;

Alors a+b sera un int contenant 97 car le char a ´et´e convertit en int.

int a=12 ;

float b=a ; // b sera ´egal `a 12.0

int c=b ; // c sera ´egale a 12 et la valeur d´cimale est enlev´ee.

— Consid´erons le calcul suivant : int I = 8 ;

float X = 12.5 ; double Y ; Y = I * X ;

Pour pouvoir ˆetre multipli´e avec X, la valeur de I est convertie en float (le type le plus large des deux). Le r´esultat de la multiplication est du type float, mais avant d’ˆetre affect´e a Y, il est converti en double. Nous obtenons comme r´esultat : Y = 100.00.

— Lors de l’appel d’une fonction, les param`etres sont automatiquement convertis dans les types d´eclar´es dans la d´efinition de la fonction. Par exemple, au cours des expressions suivantes, nous assistons `a trois conversions automatiques :

int A = 200 ; int RES ;

RES = pow(A, 2) ;

A l’appel de la fonction pow, la valeur de A et la constante 2 sont converties en double, parce que pow est d´efinie pour des donn´ees de ce type. Le r´esultat (type double) retourn´e par pow doit ˆetre converti en int avant d’ˆetre affect´e `a RES.

(19)

1.5.2 La conversion explicite ou forc´ ee

Nous avons vu que le compilateur proc`ede `a une conversion quand cette lui paraˆıt logique : int−→float par exemple.

Cependant il est tout `a fait possible de proc´eder `a la conversion d’un float en un int par exemple. Cette conversion est dite une conversion forc´ee ou explicite. On peut changer le type d’une variable vers un autre type en utilisant l’op´erateurcast(type) en le mettant devant l’iden- tificateur de variable `a convertir, la syntaxe d’un castest la suivante :

(type souhait´e) expression Exemple

Nous divisons deux variables du type entier. Pour avoir plus de pr´ecision, nous voulons avoir un r´esultat de type rationnel. Pour ce faire, nous convertissons l’une des deux composant en float.

Automatiquement C convertira l’autre composant en float et effectuera une division rationnelle : char A=3 ;

int B=4 ; float C ;

C = (float)A/B ;

La valeur de A est explicitement convertie en float. La valeur de B est automatiquement convertie en float. Le r´esultat de la division (type rationnel, valeur 0.75) est affect´e `a C. R´esultat : C=0.75.

Attention : Les contenus de A et de B restent inchang´es ; seulement les valeurs utilis´ees dans les calculs sont converties.

(20)

Les fonctions d’affichage et de saisie

Dans ce chapitre nous verrons une partie des fonctions qui concernent la lecture de donn´ees clavier et les affichages `a l’´ecran. Pour pouvoir utiliser ces fonctions il faut mettre au d´ebut du programme#include<stdio.h>, car toutes ces fonctions sont d´eclar´ees dans le fichierstdio.h.

2.1 L’affichage de donn´ ees

2.1.1 Afficher des caract` eres

Pour afficher un caract`ere on peut utiliser la fonction putchar : putchar(’A’) ; /* Affiche un ’A’*/

putchar(65) ; /* Affiche aussi un ’A’*/

Il y a une mani`ere simple d’afficher un message, par la fonctionputs : puts(”coucou !”) ;

La fonction puts va automatiquement `a la ligne apr`es l’affichage. Pour afficher un message sans aller `a la ligne, on peut utiliser printf :

printf(”coucou !”) ;

2.1.2 Afficher des donn´ ees : printf

La fonction printf permet d’afficher sur la fenˆetre de l’´ecran : du texte, des valeurs de variables ou des r´esultats d’expressions. Le format d’affichage est d´efini par le programmeur. Sa syntaxe g´en´erale est :

printf(”format”, arg 1, arg 2, ..., arg n) ;

o`u format repr´esente un message (plac´ee entre guillements ””) qui contient :

— du texte`a afficher ;

— dess´equences d’´echappementappel´es aussiordres de contrˆolequi commence par un antislash (\) suivi d’un caract`ere.

— des sp´ecifications de format (autant que de param`etres arg i) qui indiquent comment afficher les variables arg 1, ..., arg n fournies en param`etre.

(21)

Les s´equences d’´echappement : sont g´en´eralement utilis´ees pour sp´ecifier des actions telles que les retours chariot/ligne, les tabulations,... sur la fenˆetre de l’´ecran.

S´equence d’´echappement Signification

\n nouvelle ligne

\t tabulation horizontale

\v tabulation verticale (descendre d’une ligne)

\a sonnerie

\b curseur arri`ere

\r retour au d´ebut de ligne

\f saut de page

\\ trait oblique (back-slash)

\? point d’interrogation

\’ apostrophe

\” guillemets

\0 fin de chaˆıne

Les sp´ecifications de format : on pour but d’annoncer le format des donn´ees `a visulaser :

— Indiquent la mani`ere dont les valeurs des expressions arg 1, arg 2, ..., arg n sont affich´ees.

— La partie ”<format>” contient exactement un sp´ecificateur de format pour chaque expres- sion arg 1, arg 2, ..., arg n.

— Les sp´ecificateurs de format commencent toujours par le symbole % et se terminent par un ou deux caract`eres qui indiquent le format d’affichage.

Les sp´ecificateurs de format pour printf sont donn´ees dans le tableau suivant :

Symbole Type Description

%d ou %i int entier relatif

%u unsigned int entier naturel non sign´e (≥0)

%o int entier exprim´e en octal

%x int entier exprim´e en hexad´ecimal

%c int caract`ere

%f double rationnel en notation d´ecimale

%e double rationnel en notation scientifique

%ld Long int Long entier

%lu unsigned long Long entier non sign´e

%lf Long double Long r´eel

Exemples 1)

#include<stdio.h>

main() {

printf(”Bonjour\n tout\n le monde”) ; }

va afficher sur l’´ecran le r´esultat :

(22)

Bonjour tout le monde 2)

#include<stdio.h>

main() {

int i=10 ;

float x=3.14159 ; char b=’A’ ;

printf(”%d Bonjour %f %c\n”,i,x,b) ; }

va afficher sur l’´ecran le r´esultat :

10 Bonjour 3.141590 A 3)

#include<stdio.h>

main() { int i ; i=23 ;

printf(”i(dec)=%d\n”,i) ; printf(”i(octal)=%o\n”,i) ; prientf(”i(hex)=%x\n”,i) ; }

va afficher sur l’´ecran le r´esultat :

i(dec)=23 i(octal)=27 i(hex)=17

Par d´efaut, les entiers sont affich´es sans espaces avant ou apr`es. Les flottants sont affich´es avec six chiffres apr`es le point (aussi bien pour le code e que f). Pour agir sur l’affichage on peut placer un nombre apr`es % et qui pr´ecise le nombre caract`ere minimum `a utiliser. Si le nombre peut s’´ecrire avec moins de caract`eres, printf le fera pr´ec´eder d’un nombre suffisant d’espaces ; en revanche, si le nombre ne peut s’afficher convenablement (taille plus grande), printf utilisera le nombre de caract`eres n´ecessaires.

Exemples

Notez que le symbole ˆ repr´esente un espace.

(23)

printf (”%3d”, n) ;

n = 20 ˆ20

n = 3 ˆˆ3

n = 2358 2358

n = -5200 -5200

printf (”%f, x) ;

x = 1.2345 1.234500 x = 12.3456789 12.345679 printf (”%10f”, x) ;

x = 1.2345 ˆˆ234500

x = 12.345 ˆ12 .345000

x = 1.2345E5 123450.000000 printf (”%e”, x) ;

x = 1.2345 1.234500e+000

x = 123.45 1.234500e+002

x = 123 .456789E8 1.234568e+010 x = -123.456789E8 -1.234568e+010

Pour les flottants, on peut pr´eciser un nombre de chiffres apr`es le point d´ecimal : printf (”%10.3f”, x) ;

x = 1.2345 ˆˆˆˆˆ1.235

x = 1.2345E3 ˆˆ1234.500

x = 1.2345E7 12345000.000

2.2 Lecture au clavier

2.2.1 La fonction de saisie scanf

La fonction scanf permet de r´ecup´erer les donn´ees saisies au clavier, dans le format sp´ecifi´e.

Ces donn´ees sont stock´ees aux adresses sp´ecifi´ees par les arguments de la fonction scanf.

La syntaxe est la suivante :

scanf(”<format>”,<AdrVar1>,<AdrVar2>, ...)

”format” indique le format dans lequel les donn´ees lues sont converties. Elle ne contient pas d’autres caract`eres (notamment pas de\n).

<AdrVar1>,... : adresses des variables auxquelles les donn´ees seront attribu´ees.

— La fonction scanf re¸coit ses donn´ees `a partir du fichier clavier.

— Format d´etermine comment les donn´ees re¸cues doivent ˆetre interpr´et´ees.

— Les donn´ees re¸cues correctement sont m´emoris´ees successivement aux adresses indiqu´ees par <AdrVar1>,...

— L’adresse d’une variable est indiqu´ee par le nom de la variable pr´ec´ed´e du signe &.

La fonction scanf permet de lire des donn´ees avec les formats suivants (liste non exhaustive) :

(24)

— %d pour le type int ;

— %u pour le type unsigned int ;

— %f pour le type float ;

— %lf pour le type double ;

— %c pour le type char ; Exemples

int nombre ; float f1 ; double f2 ;

Puts(”Tapez un nombre entier :”) scanf(”%d”, &nombre) ;

printf(”Vous avez tap´e %d, bravo !\n Essayons encore”, nombre) ; printf(”\n Tapez deux nombres r´eels \n”) ;

scanf(”%f %lf”, &f1, &f2) ;

printf(”Vous avez tap´e : %f et %f. Est-ce bien cela ?\n”, f1, f2) ;

Dans ce dernier scanf, l’utilisateur peut saisir un espace ou bien un retour chariot (touche

«Entr´ee») entre la saisie des deux nombres r´eels.

2.2.2 La fonction getchar

La fonctiongetcharpermet la r´ecup´eration d’un seul caract`ere `a partir du clavier. La syntaxe d’utilisation degetchar est la suivante :

c=getchar() est ´equivalente `a scanf(”%c”,&c);

La fonctiongetchar retourne un int correspondant au caract`ere lu (un entier entre 0 et 255).

Exemple char c ;

printf(”Entrer un caract`ere :”) ; c=getchar() ;

printf(”Le caract`ere entr´e est %c\n”,c) ;

(25)

Les structures de contrˆ ole

Par d´efaut, l’ordre d’ex´ecution d’un programme C se fait de haut en bas (top-down). L’ex´ecu- tion commence avec la premi`ere instruction de la fonction main(), et se poursuit, instruction par instruction, jusqu’`a la derni`ere. Le langage C contient de nombreusesinstructions de contrˆole qui permettent de modifier cet ordre d’ex´ecution.

3.1 Structures conditionnelles

Les structures conditionnelles vont permettre de n’ex´ecuter que certaines instructions que sous certaines conditions.

3.1.1 Instruction if

if - else :

if ( <expression> )

<bloc d’instructions 1>

else

<bloc d’instructions 2>

— Si l’<expression> fournit une valeur diff´erente de z´ero, alors le <bloc d’instructions 1>

est ex´ecut´e.

— Si l’<expression>fournit la valeur z´ero, alors le <bloc d’instructions 2> est ex´ecut´e.

La partie <expression> peut d´esigner :

— une variable d’un type num´erique,

— une expression fournissant un r´esultat num´erique.

La partie <bloc d’instructions>peut d´esigner :

— un (vrai) bloc d’instructions compris entre accolades,

— une seule instruction termin´ee par un point-virgule.

Remarques :

— L’expression doit ˆetre entre parenth`ese.

— ne pas mettre un point-virgule `a la fin de l’instruction if (apr`es expression).

— Un bloc qui comprend plusieurs instructions doit ˆetre d´elimit´e par des accolades.

(26)

— le symbole (point virgule ;) n’est pas utlis´e pour terminer une accolade mais, termine une instruction.

— La formulation d’une expression se fait souvent `a l’aide des op´erateurs de comparaison.

Exemple 1 : if (salaire> 45.000) taxe = 0.30 ;

else

taxe = 0.25 ; Exemple 2 : if (A-B)

printf(”A est diff´erent de B\n”) ; else

printf(”A est ´egal `a B\n”) ; if sans else

if ( <expression>)

<bloc d’instructions ou une seule instrucution>

Si le r´esultat de l’´evaluation de <expression> est diff´erent de z´ero, <bloc d’instructions ou une seule instrucution>est ex´ecut´ee. Dans le cas contraire, l’ex´ecution du programme se poursuit avec l’instruction qui suit<bloc d’instructions ou une seule instrucution>.

Exemple :

#include <stdio.h>

#include <stdlib.h>

main() {

int x, y ;

/* Lecture des deux valeurs `a tester */

printf(”\nEntrez une valeur enti`ere pour x : ”) ; scanf(”%d”, &x) ;

printf(”\n Entrez une valeur enti`ere pour y : ”) ; scanf(”%d”, &y) ;

/* Test des valeurs et affichage des r´esultats */

if (x == y)

printf(”x est ´egal `a y\n”) ; if (x >y)

printf(”x est plus grand que y\n”) ; if (x <y)

printf(”x est plus petit que y\n”) ; }

Entrez une valeur enti`ere pour x : 100 Entrez une valeur enti`ere pour y : 10 x est plus grand que y

Entrez une valeur enti`ere pour x : 10 Entrez une valeur enti`ere pour y : 100 x est plus petit que y

(27)

Entrez une valeur enti`ere pour x : 10 Entrez une valeur enti`ere pour y : 10 x est ´egal `a y

if - else - ... - else

En combinant plusieurs structures if - else en une expression nous obtenons une structure qui est tr`es courante pour prendre des d´ecisions entre plusieurs alternatives :

if - else - ... - else : if ( <expr1>)

<bloc1>

else if (<expr2>)

<bloc2>

else if (<expr3>)

<bloc3>

...

else if (<exprN>)

<blocN>

else <blocN+1>

Les expressions <expr1>... <exprN> sont ´evalu´ees du haut vers le bas jusqu’`a ce que l’une d’elles soit diff´erente de z´ero. Le bloc d’instructions y li´e est alors ex´ecut´e et le traitement de la commande est termin´e.

Exemple 1 : if (age <18) printf(”mineur”) ; else if (age <65) printf(”adulte”) ; else

printf(”personne ag´ee”) ;

3.1.2 switch

Le switch permet de distinguer plusieurs cas selon les valeurs d’une variable. Sa syntaxe est la suivante :

switch (Variable) { case Valeur1 :

Liste d’instructions (1) ; break ;

case Valeur (2) :

Liste d’instructions2 ; break ;

...

case Valeur (n) :

Liste d’instructions (n) ; break ;

(28)

default :

Liste d’instructions par defaut ; }

Si variable prend la valeur valeur1 alors on ex´eecute la liste des instructions (1) , si elle prend la valeur valeur(2) on ex´ecute la liste des instructions (2), etc. Par d´efaut (c’est `a dire, si aucune des valeurs ci-dessus ne correspond `a la variable), alors on ex´ecute la liste des instructions par defaut.

Attention : Une fois l’ex´ecution des instructions commenc´ee `a partir d’un ”case” les autres instructions sont ex´ecut´ees s´equentiellement y compris celles des ”case” suivants jusqu’`a rencontrer l’instruction break qu’il ne faut donc surtout pas oublier.

Exercice : Ecrire un programme qui demande `a l’utilisateur de taper un chiffre entier≤9 et qui l’´ecrit ensuite en toute lettre `a l’´ecran. Par exemple, si l’utilisateur tape le chiffre 9, le programme affichera neuf

#include <stdio.h>

main () {int nb ;

printf (”Tapez un chiffre entre 0 et 9 :\n”) ; scanf (”%d”, &nb) ;

switch (nb){

case 0 : printf (”zero\n”) ; break ;

case 1 : printf (”un\n”) ; break ;

case 2 : printf (”deux\n”) ; break ;

case 3 : printf (”trois\n”) ; break ;

case 4 : printf (”quatre\n”) ; break ;

case 5 : printf (”cinq\n”) ; break ;

case 6 : printf (”six\n”) ; break ;

case 7 : printf (”sept\n”) ; break ;

case 8 : printf (”huit\n”) ; break ;

case 9 : printf (”neuf\n”) ; break ;

default : printf (”Erreur, vous n’avez pas tap´e un chiffre\n”) ; }

}

(29)

Exercice : refaire ce mˆeme exercice en utlisant l’instruction{if-else if- else}

3.2 Structures r´ ep´ etitives

Les structures r´ep´etitives vont permettre de r´ep´eter des instructions un certain nombre de fois, sous certaines conditions.

En langage C, les structures r´ep´etitives peuvent ˆetre exprim´ees par :

— L’instruction : while

— L’instruction : do · · · while

— L’instruction : for

3.2.1 Instruction while

La syntaxe de structure while en C est : while (<expression>)

<bloc d’instructions>

— Tant que l’<expression>fournit une valeur diff´erente de z´ero, le<bloc d’instructions>est ex´ecut´e.

— Si l’<expression>fournit la valeur z´ero, l’ex´ecution continue avec l’instruction qui suit le bloc d’instructions.

— Le <bloc d’instructions> est ex´ecut´e z´ero ou plusieurs fois.

La partie <expression> peut d´esigner :

— une variable d’un type num´erique,

— une expression fournissant un r´esultat num´erique.

La partie <bloc d’instructions> peut d´esigner :

— un (vrai) bloc d’instructions compris entre accolades,

— une seule instruction termin´ee par un point-virgule.

Exemple 1 :

/* Afficher les nombres de 0 `a 9 */

int I = 0 ; while (I<10)

{

printf(”%i\n”, I) ; I++ ;

}

Exemple 2 :

/* Afficher les nombres de 10 `a 1 */

int I=10 ; while (I)

printf(”%i\n”, I−−) ;

(30)

3.2.2 Instruction do-while

La structure do - while est semblable `a la structure while, avec la diff´erence suivante :

— while ´evalue la condition avant d’ex´ecuter le bloc d’instructions,

— do - while ´evalue la condition apr`es avoir ex´ecut´e le bloc d’instructions. Ainsi le bloc d’instructions est ex´ecut´e au moins une fois.

La syntaxe do - while en C do

<bloc d’instructions>

while (<expression>) ;

Le<bloc d’instructions>est ex´ecut´e au moins une fois et aussi longtemps que l’<expression>

fournit une valeur diff´erente de z´ero.

En pratique, la structure do - while n’est pas si fr´equente que while ; mais dans certains cas, elle fournit une solution plus ´el´egante. Une application typique de do - while est la saisie de donn´es qui doivent remplir une certaine condition :

float N ; do {

printf(”Introduisez un nombre entre 1 et 4 :”) ; scanf(”%f”, &N) ;

}

while (N<1 ||N>4) ;

3.2.3 Instruction for

L’instruction for permet d’ex´ecuter un certain nombre de fois un bloc d’une ou plusieurs instructions. On l’appelle quelquefois la boucle for, parce que l’ex´ecution du programme boucle sur ces instructions plus d’une fois. La syntaxe de la boucle for a la structure suivante :

for (initial ; condition ; incr´ement)

<boloc d’instructions>

Initial, condition et incr´ement sont des expressions ; <boloc d’instructions> repr´esente une instruction simple ou compos´ee. La boucle for fonctionne de la fa¸con suivante :

1. L’expression initial est ´evalu´ee. Il s’agit en g´en´eral d’une instruction d’affectation qui ini- tialise une valeur particuli`ere.

2. L’expression condition est ´evalu´ee. condition est souvent une expression de comparaison.

3. Si condition est fausse (valeur 0), l’instruction for se termine et l’ex´ecution reprend `a la premi`ere instruction qui suit <boloc d’instructions>.

4. Si condition est vraie (valeur diff´erente de 0), les instructions de <boloc d’instructions>

sont ex´ecut´ees.

5. L’expression incr´ement est calcul´ee et l’ex´ecution reprend `a l’´etape 2.

Exemple 1 int I ;

for (I=0 ; I<=20 ; I++)

(31)

printf(”Le carr´e de %d est %d\n”, I, I*I) ; Exemple 2

int n, tot ;

for (tot=0, n=1 ; n<101 ; n++) tot+=n ;

printf(”La somme des nombres de 1 `a 100 est %d\n”, tot) ;

Exercice : Ecrire un programme qui affiche la valeur en degr´´ es Celsius correspondant aux valeurs 0, 10, 20,..., 300 degr´es Fahrenheit. On utilisera la formule de conversion :

C = 5

9(F −32) Solution :

#include<stdio.h>

main() { int i ;

for (i = 0 ; i<= 300 ; i = i + 10) {

printf(”%d degr´es Fahrenheit donnent %.2f degr´es Celsius\n”, i, (5 * (i - 32.0) / 9.0)) ; }

}

(32)

Les Tableaux

Un tableau permet de m´emoriser plusieurs donn´ees du mˆeme type. Contrairement aux va- riables, les tableaux permettent de stocker des donn´ees nombreuses en m´emoire. Dans ce chapitre nous allons ´etudier :

— La d´efinition d’un tableau `a une dimension

— La d´eclaration, l’initialisation et l’acc´es `a aux ´el´ements d’un tableau

— Les tableaux `a deux dimensions

4.1 Les tableaux ` a une dimension

Un tableau `a une dimension est une suite d’´el´ements simples de mˆeme type et de mˆeme taille, situ´ees dans un espace contigu (voisin) en m´emoire.

4.1.1 D´ eclaration

On d´eclare un tableau par

typeElements nomTableau[NOMBRE ELEMENTS] ;

o`u typeElements est le type des ´el´ements du tableau, nomTableau est le nom du tableau, et NOMBRE ELEMENTS est une constante indiquant le nombre d’´el´ements du tableau.

Par exemple, pour d´eclarer un tableau de 100 entiers appel´e tab : int tab[100] ;

Pour d´eclarer un tableau de 150 caract`eres appel´e chaine ; char chaine[150] ;

Dans une telle d´eclaration, le nombre d’´el´ements du tableau doit ˆetre obligatoirement une constante. Le nombre d’´el´ements du tableau peut ˆetre d´efini dans une directive #define ce qui augmente la souplesse du programme (on peut alors changer le nombre d’´el´ements en changeant au niveau du #define).

4.1.2 Initialisation

Comme les autres types de variables, les ´el´ements du tableau peuvent ˆetre initialis´es lors de la d´eclaration du tableau. On met pour cel`a les valeurs des ´el´ements entre accolades {} s´epar´es par des virgules. La syntaxe :

(33)

typeElements nomTableau[NOMBRE ELEMENTS]={C1,C2,. . .,Cn}

O`u C1,C2,. . .,Cn sont des constantes dont le nombre ne doit pas d´epasser le nombre d’´el´ements du tableau (NOMBRE ELEMENTS).

— Si la liste de constantes ne contient pas assez de valeurs pour tous les ´el´ements, les ´el´ements restantes sont initialis´ees `a z´ero.

— Il est ´egalement possible de ne pas indiquer le nombre d’´el´ements et dans ce cas, le com- pilateur r´eserve automatiquement la m´emoire n´ecessaires.

Exemples :

int A[5] = {10, 20, 30, 40, 50};

float B[4] = {-1.05, 3.33, 87e-5, -12.3E4}; int C[10] = {1, 0, 0, 1, 1, 1, 0, 1, 0, 1};

int A[] ={10, 20, 30, 40, 50}; /* Si la dimension n’est pas indiqu´ee explicitement lors de l’initia- lisation, alors l’ordinateur r´eserve automatiquement le nombre d’octets (m´emoire) n´ecessaires.*/

4.1.3 Acc` es aux ´ el´ ements d’un tableau

Les ´el´ements d’un tableau sont comme des cases rang´ees successivement dans la m´emoire centrale. Les ´el´ements d’un tableau sont num´erot´es par des indices. Par exemple la d´eclaration et l’initialisation suivante :

short A[5] ={1200, 2300, 3400, 4500, 5600}; comporte 5 ´el´ements ayant des indices 0,1,. . .,4 :

A[0] A[1] A[2] A[3] A[4]

1200 2300 3400 4500 5600

Pour acc´eder `a un ´el´ement du tableau, il suffit donc de donner le nom du tableau, suivi de l’indice de l’´el´ement entre crochets :

nomTableau[indice]

— Un indice est toujours positif

— L’indice du premier ´el´ement du tableau est 0.

— L’indice du dernier ´el´ement du tableau est ´egal au nombre d’´el´ements -1 Par exemple, on acc`ede au 5i`eme ´el´ement du tableau en ´ecrivant : nomTableau[4].

L’indice peut ˆetre une valeur, une variable ou une expression arithm´etique donnant finalement lieu `aun entier.

Exemple : int i=3 ; tab[i]=2 ; tab[i*2-1]=7 ;

(34)

Attention : Les indices des ´el´ements d’un tableau commencent `a 0 et non pas `a 1. Par cons´e- quent, les ´el´ements d’un tableau `a N ´el´ements ont leurs indices allant de 0 `a N -1. L’acc`es `a un

´el´ement d’indice sup´erieur ou ´egal `a N provoquera syst´ematiquement un r´esultat faux, et g´en´era- lement une erreur m´emoire (erreur de segmentation). On parle de d´epassement de tableaux.

Remarques

— Un ´el´ement du tableau peut ˆetre manipul´e exactement comme une variable, on peut donc effectuer des op´erations sur des ´el´ements de tableau.

D´efinissons un tableau de 10 entiers : int Tab[10] ;

Pour affecter la valeur 6 au huiti`eme ´el´ement, on va ´ecrire : Tab[7]=6 ;

Pour affecter au 10`eme ´el´ement le r´esultat de l’addition des ´el´ements 1 et 2, on est : Tab[9]=Tab[0]+Tab[1] ;

— Il est donc possible d’utiliser une boucle qui va permettre d’initialiser successivement cha- cun des ´el´ements grˆace `a un compteur qui servira d’indice.

int Tab[10] ; int Indice ;

for (Indice=0 ; Indice <=9 ; Indice++) {

Tab[Indice]=0 ; }

— Pour initialiser un tableau Tab1 par les ´el´ements d’un autre tableau Tab2, on peut par exemple ´ecrire :

for(i=0 ;i<=taille tableau ;i++) Tab1[i]=Tab2[i] ;

— Il est possible d’utiliser une boucle for pour afficher et saisir les valeurs d’un tableau.

#include<stdio.h>

main() { int i ;

int Tab[4]={1,4,5,8}; for(i=0 ;i<4 ;i++)

printf(”Tab[%d]=%d\n”,i,Tab[i]) ;

/*Le contenu de Tab[i] sera affich´e sur ´ecran*/

}

4.2 Les tableaux ` a deux dimensions

Un tableau `a plusieurs dimensions poss`ede plusieurs index. Un tableau `a deux dimensions en a deux, un tableau `a trois dimensions en a trois, etc. En langage C, il n’y a pas de limite au nombre de dimensions qu’un tableau peut avoir. On se contereras dans cette section aux tableaux `a deux dimension, aussi appeler matrice.

(35)

4.2.1 D´ eclaration

Avant de montrer la syntaxe d’un tableau `a deux dimensions, il nous semble essentiel d’en rappeler le principe. Deux dimensions signifient qu’on a deux entr´ees dans notre tableau, c’est-`a- dire des lignes et des colonnes. La syntaxe :

Type Nom du Tableau[Nombre ligne][Nombre colonne] ; Exemple

int T[3][4] ;

On peut repr´esenter un tel tableau de la mani`ere suivante :

T[0][0] T[0][1] T[0][2] T[0][3]

T[1][0] T[1][1] T[1][2] T[1][3]

T[2][0] T[2][1] T[2][2] T[2][3]

4.2.2 Initialisation

Lors de la d´eclaration d’un tableau, on peut initialiser les composantes du tableau, en indiquant la liste des valeurs respectives entre accolades. A l’int´erieur de la liste, les composantes de chaque ligne du tableau sont encore une fois comprises entre accolades. Pour am´eliorer la lisibilit´e des programmes, on peut indiquer les composantes dans plusieurs lignes.

Exemples

int A[3][10] = { { 0,10,20,30,40,50,60,70,80,90}, {10,11,12,13,14,15,16,17,18,19}, {1,12,23,34,45,56,67,78,89,90} }; float B[3][2] = { {-1.05, -1.10 },

{86e-5, 87e-5}, {-12.5E4, -12.3E4}};

Lors de l’initialisation, les valeurs sont affect´ees ligne par ligne en passant de gauche `a droite.

Nous ne devons pas n´ecessairement indiquer toutes les valeurs : Les valeurs manquantes seront initialis´ees par z´ero. Il est cependant interdit de d´epasser le nombre limite de colonnes ou de lignes r´es´erv´es pour un tableau.

Exemples

int C[4][4] = {{1,0,0,0}, {1,1,0,0}, {1,1,1,0}, {1,1,1,1}};

=⇒ C :

1 0 0 0

1 1 0 0

1 1 1 0

1 1 1 1

int C[4][4] = {{1,1,1,1}}; =⇒ C :

1 1 1 1

0 0 0 0

0 0 0 0

0 0 0 0

(36)

int C[4][4] = {{1},{1},{1},{1}}; =⇒ C :

1 0 0 0

1 0 0 0

1 0 0 0

1 0 0 0

int c[4][4]={{1,1,1,1,1}}; =⇒ Erreur :On a d´epass´e le nombre limite de colonnes r´eserv´es.

Si le nombre de lignes L n’est pas indiqu´e explicitement lors de l’initialisation, l’ordinateur r´eserve automatiquement le nombre de lignes n´ecessaires.

Exemple

int C[][4] = {{1,0,0,0}, {1,1,0,0}, {1,1,1,0}, {1,1,1,1}};

=⇒ C :

1 0 0 0

1 1 0 0

1 1 1 0

1 1 1 1

4.2.3 Acc` es aux ´ el´ ements

On acc`ede `a un ´el´ement du tableau par l’expression :

Nom tableau[ligne][colonne]

Attention : Consid´erons un tableau A de dimensions L et C.

— les indices du tableau varient de 0 `a L-1, respectivement de 0 `a C-1.

— la composante de la Ni`eme ligne et Mi`eme colonne est not´ee : A[N-1][M-1]

Lors du travail avec les tableaux `a deux dimmensions, nous utiliserons en g´en´eral deux indices (par exemple i et j), et la bouclefor pour parcourir les lignes et les colonnes des tableaux.

Exemple

#include<stdio.h>

main() {

short tab[3][2]={{1,2},{14,15}, {10,20}}; int i,j ;

for(i=0 ;i<2 ;i++) {

for(j=0 ;j<3 ;j++)

printf(”tab[%d][%d]=%d\n”,i,j,tab[i][j]) ; }

}

On vient de d´efinir la matrice :

1 2

14 15 10 20

(37)

Les Fonctions

Lorsqu’un programme comprend de nombreuses lignes de code, il est difficile, voire impossible de mettre toutes les instructions les unes `a la suite des autres dans le programme principal main. Le programme serait illisible, comprendrait trop de variables, etc. Pour cette raison, on d´ecompose les probl`emes en sous-probl`emes et le programme en sous-programmes qui r´esolvent les sous- probl`emes. En langage C, l’outil pour cr´eer des sous-programmes est la notion de fonction.

L’utilisation de quelques fonctions a d´eja ´et´e vue, par exemple avec celle pr´ed´efinie dans des biblioth`eques standard comme printf de< stdio >, sqrt de < math >, et main qui est un cas particulier de fonctions.

5.1 Qu’est-ce qu’une fonction ?

5.1.1 D´ efinition

Unefonctionest un bloc de code C ind´ependant, r´ef´erenc´e par un nom, qui r´ealise une tˆache pr´ecise et qui peut renvoyer une valeur au programme qui l’a appel´ee. Examinons cette d´efinition :

— Une fonction est r´ef´erenc´ee par un nom. Ce nom est unique et en l’introduisant dans le code source de votre programme, vous pouvez ex´ecuter le code de la fonction. Une fonction peut ˆetre appel´ee par une autre fonction.

— Une fonction est ind´ependante. Une fonction peut effectuer sa tˆache avec ou sans

´

echanges avec une autre partie du programme.

— Une fonction r´ealise une tˆache particuli`ere. La tache est l’unit´e de base du travail r´ealis´e par le programme. Cela peut ˆetre un tri, ou le calcul d’une racine carr´ee, d’une moyenne...

— Une fonction peut renvoyer une valeur au programme appelant. Quand ce pro- gramme appelle la fonction, le code de cette fonction est ex´ecut´e. Ces instructions peuvent renvoyer une information au programme.

Les fonctions sont donc des sous-programmes qui permettent d’effectuer un ensemble d’instruc- tions par simple appel de la fonction dans le corps du programme principal. Elles ont plusieurs avantages :

— Permettent d’organiser le codeet am´eliorer la lisibit´e des programmes.

— Facilitent la maintenance du code (il suffit de modifier une seule fois).

— Ces fonctions peuvent ´eventuellement ˆetre r´eutilis´ees dans d’autres programmes.

(38)

5.1.2 D´ eclaration d’une fonction

Une fonction doit ˆetre d´efinie avant d’ˆetre utilis´ee programme. La d´efinition d’une fonction s’appelled´eclaration. Le format g´en´eral d’une d´eclaration de fonction est de la syntaxe suivante :

type de donn´ee Nom De La Fonction(type1 argument1, type2 argument2,· · ·) {

liste d’instructions }

Quelques remarques compl´ementaires :

— type de donn´ee repr´esente le type de l’identificateur du param`etre de sortie.

— Si la fonction ne renvoie aucune valeur, on la fait alors pr´ec´eder du mot-cl´e void.

— Si aucun type de donn´ee n’est pr´ecis´e, le type int est pris par d´efaut.

— Le nom de la fonction suit les mˆemes r`egles que les noms de variables.

— Si une fonction n’a pas d’arguments, on peut d´eclarer la liste des arguments comme (void) ou simplement comme ().

Exemple :

#include<stdio.h>

/* Fonction affichant un caract`ere */

void affiche car(char car) {

printf(”%c”, car) ; }

int main() {

char c ; int i ;

printf(”Veuillez entrer un caract`ere :”) ; c=getchar() ;

for(i=0 ;i<100 ;i++) affiche car(c) ; }

5.1.3 Appel des fonctions

L’appel d’une fonction se fait en ´ecrivant son nom, suivit d’une paire de parenth`eses contenant

´eventuellement une liste d’arguments effectifs.

Nom De La Fonction(argument effectif 1, argument effectif 2, · · ·) ;

L’ordre et le type des param`etres effectifs de la fonction doivent concorder avec ceux donn´es dans l’en-tˆete de la fonction. Les param`etres effectifs peuvent ˆetre des expressions. La virgule qui s´epare deux param`etres effectifs est un simple signe de ponctuation ; il ne s’agit pas de l’op´erateur virgule.

Cela implique en particulier que l’ordre d’´evaluation des param`etres effectifs n’est pas assur´e et d´epend du compilateur. Il est donc d´econseill´e, pour une fonction `a plusieurs param`etres, de faire figurer des op´erateurs d’incr´ementation ou de d´ecr´ementation (++ ou −−) dans les expressions d´efinissant les param`etres effectifs.

(39)

5.1.4 Prototype d’une fonction

On peut se contenter de d´eclarer le prototype d’une fonction (sans le corps) :

type de donn´ee Nom De La Fonction(type1 argument1, type2 argument2,· · ·) ; Le prototype d’une fonction est une description d’une fonction qui est d´efinie plus loin dans le programme. On place donc le prototype en d´ebut de programme (avant la fonction principale main()).

Contrairement `a la d´efinition de la fonction, le prototype n’est pas suivi du corps de la fonction (contenant les instructions `a ex´ecuter).

Le prototype est une instruction, il est donc suivi d’un point virgule. Voici quelquesexemples de prototypes :

void fonction1( int x, float y) ;

La fonction (qui s’appelle ”fonction1”) admet deux arguments : le premier de type entier et le second de type r´eel. Elle ne retourne aucune valeur.

float fonction2(int a, double c) ;

La fonction ”fonction2” admet deux arguments (tous deux entiers) et retourne un r´eel.

Si on veut laisser la d´eclaration (d´efinition) de la fonction `a la fin du programme, il faut absolument d´eclarer le prototype de la fonction avant main().

5.1.5 Renvoi d’une valeur par une fonction

Toute fonction qui n’est pas de type void, son corps doit obligatoirement comporter une instruction return. La g´en´eration du retour de fonction est provoqu´ee par l’appel de l’instruction return.

On utlise l’instructionreturn sous l’une des deux formes suivantes : return expression ;

return (expression)

— La valeur d’expression correspond `a la valeur que retourne la fonction et doit donc ˆetre de type type de donn´ee.

— Plusieurs instructions return peuvent apparaˆıtre dans une fonction. Le retour au pro- gramme appelant sera alors provoqu´e par le premier return rencontr´e lors de l’ex´ecution.

Exemple 1 :

/* Renvoit le produit de 2 entiers*/

int produit(int a, int b) {

return(a*b) ; }

Exemple 2 :

/* Renvoit le minimum de deux entiers*/

float min(float a, float b) {

if (a<b) return a ; else

Références

Documents relatifs

[r]

Entourer dans les deux algorithmes (1. et 2.) la/les instructions qui ont été modifiées2. Quelle est la valeur contenue dans la variable P en fin d’exécution

Un signal peut avoir une valeur moyenne nulle et une valeur efficace non-nulle. La valeur efficace d’un signal continu U

Attention : une variable n'est jamais initialisée avec une valeur par défaut, elle prend la valeur qui se trouvait là avant dans la mémoire, et cette valeur peut être n'importe

En prenant pour indice de base 100 la valeur de l’action au mois de janvier, l’indice de la valeur de l’action au mois d’aoˆ ut est de

En prenant pour indice de base 100 la valeur de l’action au mois de janvier, l’indice de la valeur de l’action au mois d’aoˆ ut est de

Sortie : Afficher.. Fin

L4 U prend la valeur.. L4 U prend