You are on page 1of 50

I.

Prsentation
Le langage C est un langage de programmation destin aux machines ayant une mmoire et un processeur. Il permet laccs et le traitement de donnes que manipulent ces machines (entiers, rels, boolens, caractres, chanes de caractres,). Il a t conu pour lcriture de systmes dexploitation et de logiciels de base. En effet, plus de 90% du noyau du systme UNIX est crit en langage C. Le compilateur C lui-mme est crit en grande partie en langage C ou partir doutils gnrant du langage C. Il en est de mme pour les autres outils de la chane de compilation (assembleur, diteur de liens, pr-processeur). De plus, tous les utilitaires du systme sont crits en C (shell, outils). Il est cependant suffisamment gnral pour permettre de dvelopper des applications varies de type scientifique ou encore pour laccs aux bases de donnes. Par le biais des bases de donnes, il est utilis dans les applications de gestion. De nombreux logiciels du domaine des ordinateurs personnels, tels que MicrosoftWord ou Microsoft Excel, sont euxaussi crits partir de langage C ou de son successeur orient objet : C++ [Str86]. Bien quil peut tre considr de bas niveau, le langage C supporte les structures de base ncessaires la conception des applications structures. Cette caractristique le classifie dans la catgorie des langages de haut niveau. Il est aussi un des premiers langages offrant des possibilits de programmation modulaire, cest--dire quun programme de langage C peut tre constitu de plusieurs modules (fichier source, fonctions). Bien quune machine ne comprenne que le systme binaire (1 ou 0), le langage C intgre ce quon appelle un compilateur. Ce dernier est conu afin de traduire le programme crit par lutilisateur en un ensemble de donnes et instructions dans le systme binaire (gnralement en langage assembleur). La figure suivante illustre la compilation dun programme C.

Programme C (crit en langage C : langage plus simple utiliser par ltre humain, syntaxe plus significative, comprhensible)

Compilation = traduction en langage machine (binaire)

Programme binaire (crit en langage binaire : langage trs compliqu, suite de codes binaires correspondant aux instructions, moins significatif)
Figure 1 : schma illustrant la traduction dun programme C en langage machine grce au compilateur

Et donc il ncessaire que le programmeur prenne toujours en compte cette notion quand il crit son programme, exemple : La machine ne comprend pas une formule mathmatique, elle lexcute. La machine ne comprend pas un texte mis dans une instruction daffichage, elle affiche seulement. Par consquent, la machine nest l que pour nous aider rsoudre des programmes qui sont compliqus raliser dans la vie pratique, par exemple les calculs mathmatiques trop durs ou trop longs du fait que ltre humain peut s y tromper.

Chapitre I : Syntaxe

Ce chapitre introduit les premiers concepts indispensables la comprhension dun programme C, savoir les rgles qui constituent la syntaxe de base du langage. Ces rgles sont utilises par les compilateurs pour dterminer si une srie de caractres correspond un mot rserv, un nom ou une constante. Les diffrents lments de la syntaxe seront abords au fur et mesure dans les chapitres futurs de ce document.

I.1 Mise en page


Le format du texte est libre. La mise en page na aucune signification pour le compilateur. Elle est importante pour la lisibilit du programme. Les lignes de directives de compilation commencent par un #.

I.1.1 Identifiant
Les identifiants (noms de variables dclares par lutilisateur, noms de fonctions) sont utiliss pour donner des noms aux diffrentes entits utiliss dans le langage. Un identifiant est construit selon le modle : - partir de lalphabet : a-z, A-Z, 0-9, _ ; - il peut avoir jusqu 31 caractres significatifs lintrieur dune unit de compilation. - il peut commencer par une lettre ou le soulign _.

I.1.2 Espaces lexicaux


Les diffrents identifiants dun programme en langage C sont classs dans des espaces lexicaux (nots sous forme de carr dans ce paragraphe) qui permettent disoler les noms des types selon leur signification. Les espaces lexicaux utiliss par un compilateur C sont les suivants : - le premier espace spare les types aux variables et aux fonctions, exemple : int a, char c - le second espace est rserv aux champs de donnes tels que les structures : struct nom_structure variable - dans le cas des oprations de calcul, les espaces peuvent tre mis titre facultatif. Cela permet une bonne lisibilit du programme : a+b ou a + b sont les mmes.

I.2 Mots rservs


Ce sont les mots prdfinis du langage C. Ils ne peuvent pas tre rutiliss pour des identifiants. Ils sont relatifs aux diffrents concepts du langage : type des donnes char const double float int long void volatile constructeurs (structures de donnes, classes dobjets) struct class instructions de boucle do for while slections case default else if switch ruptures de squence break continue goto return

I.3 Instructions
Une instruction est suite doprations qui dfinit un traitement donn (opration arithmtique, incrmentation, affectation, appel dune fonction, ). Elle peut tre : soit une instruction simple, exemple : c = a + b ; soit un instruction compose. Une instruction simple est toujours termine par un ;. Les instructions composes sont contenues entre deux accolades : {}.

Chapitre II : Types et variables

II.1 Types de base


Ce sont les types prdfinis du compilateur. Ils sont au nombre de six :

void

cest le type vide. Il a t introduit par la norme ANSI. Surtout utilis pour

prciser les fonctions sans argument ou sans retour.

int cest le type entier. Ce type se dcline avec des qualificatifs pour prciser sa taille (long ou short), et le fait quil soit uniquement positif (unsigned) ou positif et ngatif (signed). Le qualificatif signed est appliqu par dfaut, ainsi il ny a pas de diffrence entre une variable de type int et une variable de type signed int.

char

ce type est trs proche de loctet. Il reprsente un caractre sur huit bits. Sa

valeur peut voluer entre -128 et +127. Il est le support des caractres au sens commun du terme. Ces caractres sont reprsents par la table ASCII.

float

ce type sert pour les calculs avec des parties dcimales.

double

cest un type qui permet de reprsenter des valeurs ayant une partie

dcimale avec une plus grande prcision que le type float.

long double ce type est rcent, il permet de reprsenter des nombres avec parties dcimales qui ncessitent une trs grande prcision.

II.1.1 Types entiers


Les mots short et long peuvent tre utiliss seuls ou avec le mot int, donnant la possibilit davoir des dfinitions du type : short int ou long int. Ces dfinitions peuvent aussi scrire de manire abrge : short ou long. Le langage C considre les types char, short int, int et long int, comme des types entiers et permet de les mlanger lors des calculs. A priori, les types entiers sont signs, cest--dire quils peuvent contenir des valeurs positives ou ngatives. Par exemple, la valeur dune variable du type char peut voluer entre -128 et +127. Les types entiers peuvent tre qualifis laide du mot unsigned qui force les variables de ce type tre considres comme uniquement positives. Par exemple, la valeur

dune variable du type unsigned char ne peut voluer quentre 0 et 255. Le qualificatif signed permet dinsister sur le fait que la variable peut prendre des valeurs positives ou ngatives.

II.1.2 Types avec parties dcimales


Comme nous lavons dj dit, les types avec parties dcimales sont trois : - float ce type sert pour les calculs avec des parties dcimales. Il est souvent reprsent selon la norme ISO/IEEE 754. - double ce type de plus grande prcision permet de reprsenter des valeurs avec parties dcimales. Lui aussi est souvent bas sur la norme ISO/IEEE 754. - long double ce type est rcent et permet de reprsenter des nombres avec parties dcimales sur une trs grande prcision, si la machine le permet.

II.1.3 Chanes de caractres


Les constantes du type chane de caractres doivent tre mises entre guillemets ("chane de caractres"). Le compilateur gnre une suite doctets (tous les bits 0) termine par un caractre nul (\0) partir des caractres contenus dans la chane. Cette suite doctets peut tre place par le systme dans une zone de mmoire en lecture seulement. La zone correspondante est en fait un tableau de char. La chane est rfrence par ladresse du tableau. Par exemple, la chane de caractres "message" est gnre par le compilateur selon le schma suivant.

\0

Figure 2 : chane de caractres gnre par le compilateur

II.2 Tailles des types

Lespace quoccupent les diffrents types en mmoire dpend de la machine sur laquelle est implant le compilateur. Le choix est laiss aux concepteurs des compilateurs. Les seules contraintes sont des ingalits non strictes, savoir : sizeof(short) < sizeof(int) < sizeof(long) sizeof(float) < sizeof(double) < sizeof(longdouble) o sizeof est un oprateur qui donne la taille en nombre doctets du type dont le nom est entre parenthses. La taille de lentier est le plus souvent la taille des registres internes de la machine, cest par exemple 16 bits sur une machine de type ordinateur personnel et 32 bits sur les machines du type station de travail. La taille des variables ayant une partie dcimale est le plus souvent cadre sur la norme ISO/IEEE 754. Les machines supportant un type long double diffrent du type double sont assez rares. Le tableau de la figure 3 donne quelques exemples de tailles pour des machines dont les registres ont les tailles suivantes en nombre de bits : 16 (DEC PDP11, Intel 486), 32 (SUN Sparc, Intel Pentium) et 64 (DEC Alpha).

Machine Anne char short int long float double Long double

PDP11 1970 8 bits 16 bits 16 bits 32 bits 32 bits 64 bits 64 bits

Intel 486 1989 8 bits 16 bits 16 bits 32 bits 32 bits 64 bits 64 bits

Sparc 1993 8 bits 16 bits 32 bits 32 bits 32 bits 64 bits 64 bits

Pentium 1993 8 bits 16 bits 32 bits 32 bits 32 bits 64 bits 64 bits

Alpha 1994 8 bits 16 bits 32 bits 64 bits 32 bits 64 bits 128 bits

Figure 3 : longueur de types de bases sur quelques machines

II.3 Dfinition de variables

Nous appellerons identifiant soit un nom de fonction, soit un nom de variable. Pour complter ce que nous avons dit dans lintroduction de ce chapitre, voici comment les diffrents besoins associs la dfinition de variables sont assurs par le langage C : - dfinition du domaine de valeur de cette variable et les oprations lgales sur cette variable - rservation de lespace mmoire ncessaire au support de la variable lors de lexcution - initialisation de la variable laide dune constante dont le type correspond celui de la variable Exemple : int i ; /* dfinition de la variable i dans le domaine des entiers*/ /* dfinition de la variable c dans le domaine caractres*/ /* initialisation de la variable c par affectation du caractre a*/

char c ;

c = a ;

II.4 Types drivs des types de base


Un type driv est cr partir des types de base vus prcdemment pour lusage propre un programme. Les types drivs sont les tableaux, les structures et les pointeurs.

II.4.1 Tableaux
Les tableaux sont des paquets de donnes de mme type. Ils sont reconnus par la prsence de crochets ouvrants et fermants lors de la dclaration ou de la dfinition de lobjet. La taille du tableau est donne entre les crochets lors de la dfinition. Pour simplifier le travail du compilateur, le rang des lments du tableau ne peut voluer quentre 0 et la taille du tableau -1. Exemple : int t[10]; t est un tableau de 10 entiers, et les lments du tableau sont rfrencs par t[0] jusqu t[9].

1
t[0]

5
t[1]

23
t[2]

45
t[3]

6
t[4]

43
t[5]

7
t[6]

22
t[7]

56
t[8]

33
t[9]

II.4.2 Pointeurs
Le pointeur est une variable destine contenir une adresse mmoire. Le compilateur connaissant la taille de lespace adressable de la machine, il connat la taille ncessaire pour contenir un pointeur. Un pointeur est reconnu syntaxiquement par ltoile (symbole de la multiplication *) qui prcde son nom dans sa dfinition. Tout pointeur est associ un type dobjet. Ce type est celui des objets qui sont manipulables grce au pointeur. Ce type est utilis en particulier lors des calculs dadresse qui permettent de manipuler des tableaux partir de pointeurs. Prenons les dfinitions suivantes : int *ptint; char *ptchar; Dans cet exemple, ptint est une variable du type pointeur sur un entier. Cette variable peut donc contenir des valeurs qui sont des adresses de variables du type entier(int). De mme, ptchar est une variable du type pointeur sur un caractre. Elle peut donc contenir des valeurs qui sont des adresses de variables de type caractre (char).

ptint 00F01 00F02 00F03 ptchar 00F04 00F05

. 5 7 12 a b

Figure 4 : pointeurs ptint et ptchar sur une partie de mmoire contenant des variables avec adresses.

Le compilateur C vrifie le type des adresses mises dans un pointeur. Le type du pointeur conditionne les oprations arithmtiques sur ce pointeur. Les oprations les plus simples sur un pointeur sont les suivantes :

- affectation dune adresse au pointeur - utilisation du pointeur pour accder lobjet dont il contient ladresse Si lon dfinit les variables de la manire suivante : int in; int tabint[10]; char car; int *ptint; char *ptchar;

Un pointeur peut tre affect avec ladresse dune variable ayant un type qui correspond celui associ au pointeur. Comme nous le verrons dans la partie sur les oprateurs, le et-commercial & donne la valeur de ladresse du pointeur et qui peut changer au cours de lexcution du programme. Ainsi un pointeur peut tre initialis de la faon suivante : ptint = &in; ptchar = &car; Une fois ladresse est affecte au pointeur, ce dernier peut tre utilis pour accder aux cases mmoires correspondant la variable (valeur de la variable) : *ptint = 12; *ptc = a; La premire instruction met la valeur entire 12 dans lentier in. La deuxime instruction met le caractre a minuscule dans lentier car. Il est possible de raliser ces oprations en utilisant le pointeur pour accder aux lments du tableau. Ainsi, les lignes : ptint=tab; *ptint=4; affectent le pointeur ptint avec ladresse du premier lment du tableau tabint quivalent (voir) &tabint[0] ; puis le premier lment du tableau (tabint[0]) est affect avec la valeur 4.

II.5 Initialisation de variables


Linitialisation se dfinit comme laffectation dune valeur lors de la dfinition de la variable. Toute modification de valeur dune variable postrieure sa dfinition nest pas une initialisation mais une affectation. Vous devez donc les initialiser pour viter le risque dutiliser une variable sans en connatre la valeur initiale. Il est possible de raliser des initialisations selon trois techniques suivant le type de la variable : - dans le cas dune variable simple, il suffit de faire suivre la dfinition du signe gal (=) et de la valeur que lon veut voir attribue la variable. - dans le cas de tableaux, il faut faire suivre la dfinition du signe gal par une accolade ouvrante et de la srie de valeurs termine par une accolade fermante. Les valeurs sont spares par des virgules. Elles doivent correspondre aux lments du tableau. La norme prconise que lorsque le nombre de valeurs dinitialisation est infrieur au nombre dlments initialiser, les derniers lments soient initialiss avec la valeur nulle correspondant leur type. - les tableaux de caractres peuvent tre initialiss partir dune chane de caractres. Les caractres de la chane sont considrs comme constants. Exemple : int i = 10; Entier i initialis 10 int j = 12 ; entiers j initialis 12 k = 3, l; k initialis 3 et l non initialis. int *p1 = &i; Pointeur dentier initialis ladresse de i char d = x; Caractre initialis la valeur du retour chariot. float tf[10] = {3.1, 4.5, 6.4, 9.3 }; Tableau de dix flottants dont les quatre premiers lments sont initialiss 3.1 4.5 6.4 et 9.3, les autres sont initialiss 0.0 char t1[10] = "message"; Tableau de 10 caractres initialis avec les caractres m e s s a g e \0

Chapitre III : lments de base

Le langage C est un outil de programmation utilis dans un contexte interactif. C'est-dire que la plupart des programmes crits en langage C font des changes dinformation avec un utilisateur du programme. Un utilisateur de ce type de systme est connect via une voie dentre-sortie qui permet dchanger des caractres. Ces voies sont la plupart du temps relies un tltype (cran, clavier, avec sortie optionnelle sur papier). Les caractres sont crits sur lcran du terminal et lus partir du clavier. Ce modle cran clavier qui est repris par le systme UNIX est celui des interactions en langage C partir des fichiers standard dentre et de sortie. Les entre-sorties en langage C ne sont pas prises en charge directement par le compilateur mais elles sont ralises travers des fonctions de bibliothque. Le compilateur ne peut pas faire de contrle de cohrence dans les arguments passs ces fonctions car ils sont de type variable. Ceci explique lattention toute particulire avec laquelle ces oprations doivent tre programmes.

III.1 Fameux Bonjour


Le premier programme que toute nouvelle personne crit lorsquil apprend un nouveau langage rpond la question suivante : comment crire un programme principal qui affiche Bonjour ? En langage C, le programme est donn comme suit :

#include <stdio.h> main() { printf("bonjour"); }

Il est constitu de la manire suivante : la premire ligne (#include <stdio.h>) est une directive (commande) pour le processeur qui demande celui-ci de lire le fichier (stdio.h) reprsentant linterface standard des entres/sorties (clavier/cran). Cette premire ligne doit tre prsente dans tout

programme ou fonction faisant appel des fonctions dentres sorties et en particulier aux fonctions printf() et scanf(). La deuxime ligne (main()) est une fonction qui reprsente le programme principal excuter. printf("bonjour") est la fonction qui permet dafficher sur un cran un contenu pass dans son argument (entre parenthses). Cest le mot bonjour dans ce cas.

III.2 Lecture et criture


Les entres et sorties que lutilisateur manipule dans le langage C sont gres par deux fonctions : printf() et scanf(). La fonction printf permet dafficher une chane de caractres reprsentant un message lisible par lutilisateur et qui peut contenir aussi des valeurs de variables que ce dernier souhaite visualiser. Le schma suivant illustre le fonctionnement de cette fonction. printf("bonjour") ;

Bonjour_ cran

Dans le cas o lon souhaite afficher la valeur dune variable donne, il faudra passer le type de cette variable ainsi que son nom dans largument de la fonction printf. Syntaxe : printf("%code_type", nom_variable) ; le tableau suivant prsente les types usuelles ainsi que les codes correspondant mette dans la fonction printf(). type int float char Chane de caractres code d f c s

Exemple : #include <stdio.h> main() { int i = 5; float x = 2.3; char b = a; char t[10] = message; printf("%d", i); printf("%f", x); printf("%c", b); printf("%s", t); }

5 2.3 cran a message

La fonction printf peut afficher plusieurs variables en mme temps. Syntaxe printf("%code_type1%code_type2%code_typen",nom_variable1,nom_ variable2,,nom_variablen) ;

Exemple : #include <stdio.h> main() { int i = 5; float x = 2.3; char b = a; char t[10] = message; printf("%d %f %c %s", i,x,b,t); }

5 2.3 a message

cran

Quelques astuces pour la focntion printf() Dans un programme C, il est parfois possible dutiliser la fonction printf() plusieurs fois. Ceci peut engendrer quelques soucis daffichage et qui peuvent nuire la lisibilit des informations souhaites (toutes dans la mme ligne). Il est donc recommand damliorer ces affichages par des codes quon met avec la fonction printf() : \a : alert (sonnerie, BEL) ; \b : backspace (BS) ; \f : saut de page (FF) ; \n : saut de ligne (LF) ; \r : retour chariot (CR) ; \t : tabulation horizontale (HT) ; \v : tabulation verticale (VT) ; Ainsi sil on reprend lexemple prcdent avec un saut de ligne entre les variables

#include <stdio.h> main() { int i = 5; float x = 2.3; char b = a; char t[10] = message; printf("%d\n%f\n%c\n%s", i,x,b,t); }

Laffichage donnera : 5 2.3 cran a message

La fonction scanf() fait le contraire de la fonction printf(). Elle permet de lire les valeurs entres par lutilisateur (clavier), les convertir (selon le code du type) et les stocker dans les variables dclares dans le programme. Syntaxe : scanf("%code_type",&nom_variable) ;

le & commercial est obligatoire dans la fonction scanf() qui repre la variable grce son adresse puis stocke le contenu saisi dans cet emplacement. Exemple: #include <stdio.h> main() { int i; printf("entrer un entier"); scanf("%d", }

&i);

entrer un entier_ cran

Le curseur clignotant attend la valeur que lutilisateur saisira au clavier

Lutilisateur saisit titre dexemple la valeur 5

entrer un entier5 cran

Le curseur clignotant attend la valeur que lutilisateur saisira au clavier

Puis appuie sur la touche dentre. La valeur 5 est donc stocke dans la variable i. pareil pour la fonction printf(), la fonction scanf() peut lire une multitude de valeurs en une seule fois. Syntaxe : scanf("%code_type1%code_type2%code_typen",&nom_variable1,

&nom_variable2,, &nom_variablen)

Chapitre IV : Oprateurs et expressions

Le langage C est connu pour la richesse de ses oprateurs. Il apporte aussi quelques notions innovantes en matire doprateurs. En particulier, le langage C considre laffectation comme un oprateur normal alors que les langages qui lont prcd (par exemple FORTRAN, ADA) la considrent comme une opration privilgie. Cette richesse au niveau des oprateurs permet dcrire des expressions (combinaisons doprateurs et doprandes) parfois complexes. Les oprateurs sont les lments du langage qui permettent de faire du calcul ou de dfinir des relations. Ils servent combiner des variables et des constantes pour raliser des expressions.

IV.1 Oprateurs un-aires


Un oprateur un-aire agit sur un oprande qui peut tre une constante, une variable, ou une expression. Ainsi, loprateur un-aire - permet dinverser le signe et on peut crire : -2 o 2 est une constante ; -i o i est une variable ; -(i+2) o i+2 est une expression. Les oprateurs un-aires en langage C sont : & oprateur dadresse appel aussi de rfrencement * oprateur dindirection ou de drfrencement sur une adresse -- oprateur de dcrmentation ++ oprateur dincrmentation sizeof oprateur donnant la taille en octet ! ngation logique - moins unaire, inversion du signe + plus unaire ~ complment un

IV.1.1 Oprateur de rfrencement


Le & est loprateur de rfrencement, il retourne ladresse en mmoire (rfrence) de la variable dont le nom le suit. &variable donne ladresse en mmoire de la variable. Cette adresse peut tre utilise pour affecter un pointeur ( la condition que le pointeur soit dun type compatible avec le type de la variable).

IV.1.2 Oprateur de drfrencement ou indirection

Le * est loprateur dindirection. Il permet daccder une variable partir dune adresse (le plus souvent en utilisant la valeur contenue dans un pointeur). *&variable donne la valeur contenue dans la variable.

IV.1.3 Oprateurs dincrmentation et de dcrmentation


Les oprateurs -- et ++ permettent de dcrmenter et dincrmenter des variables de type entier. Dans une premire approche, nous pouvons considrer que : var-- : est quivalent var = var - 1, ce qui implique en partant dune variable var ayant une valeur de 8 que cette variable contient la valeur 7 une fois lexpression calcule var++ : est quivalent var = var + 1, ce qui implique en partant de var ayant une valeur de 8 que cette variable contient la valeur 9 la fin de lexcution de lexpression. Il est possible dutiliser les oprateurs un-aires dincrmentation et de dcrmentation derrire la variable (postfix) ou devant celle-ci (prfix). Ce qui permet de post-incrmenter, de pr-incrmenter, de post-dcrmenter ou de pr-dcrmenter. Lorsque loprateur est prfix, lopration est applique avant que la valeur correspondant lopration ne soit calcule. Dans le cas o lopration est post-fixe, la valeur de la variable avant lopration est utilise pour les autres calculs et ensuite lopration est applique. Prenons comme exemple, deux entiers i et j, et initialisons ces deux variables avec la valeur 0. int i=0, j=0; Si nous crivons j = ++i, cest une pr-incrmentation de la variable i. Cela signifie incrmenter i de 1 puis mettre la valeur de i dans j. la fin de cette opration i vaut 1 et j vaut 1. Si au contraire, nous crivons j = i++, cela signifie mettre la valeur de i dans j puis incrmenter i de 1. En partant des mmes valeurs, i valant 0 et j valant 0, la fin de cette instruction i vaut 1 et j vaut 0. Cette opration est quivalente : j=i, i = i+1,

IV.1.4 Oprateur de ngation logique

La ngation logique (non logique) sert inverser une condition en la faisant passer de vrai faux et rciproquement. En langage C, une expression est fausse si la valeur quelle retourne est gale 0, elle est vraie sinon. De plus, la norme spcifie que !0 vaut 1.

IV.1.5 Complment un
Loprateur ~ donne le complment un de lexpression entire qui le suit. Cest un oprateur utilis dans les calculs de masquage et nous le considrons comme un oprateur portant sur les bits de loprande associ. Soit i une variable de type entier initialise 10 (int i = 10 ;). En considrant quun entier est reprsent sur 16 bits, cette valeur est quivalente en binaire :
0000 0000 0000 0000 0000 0000 0000 1010

Le complment un de i (~ i) vaut:
1111 1111 1111 1111 1111 1111 1111 0101

IV.2 Oprateurs binaires


Type doprateur Arithmtique Oprateur + * % Masquage Dcalage Relation / | ^ << <= >= != || = , usage Addition, soustraction Multiplication, division Reste de la division entire et, ou, ou exclusif Vers la droite ou vers la gauche Infrieur, infrieur ou gal Suprieur, suprieur ou gal gal, diffrent Et logique, ou logique affectation succession

&
>> < > ==

Logique Affectation Succession

&&

IV.2.1 Oprateurs arithmtiques


Le langage C permet lutilisation des oprateurs de calcul mathmatique que lon trouve habituellement dans les autres langages, savoir : laddition, la soustraction, la multiplication et la division. Il utilise pour cela les symboles respectifs : + - * /. Syntaxe : Int a, b ; a + b; a b; a*b; a/b; /*addition*/ /*soustraction*/ /*multiplication*/ /*division*/

IV.2.2 Oprateurs de dcalage

Les oprateurs de dcalage (<< et >>) servent manipuler les valeurs contenues dans les variables de type entier en poussant les bits vers la gauche ou la droite. Ces oprateurs servent raliser des tests ou effacer certaines parties dune variable. Le dcalage peut se faire vers la gauche ou vers la droite. Le dcalage vers la droite peut tre sign si lexpression est signe, le rsultat est cependant dpendant de limplantation (ce qui veut dire que pour crire un programme portable il ne faut pas utiliser le dcalage droite sur une valeur ngative). De manire simple (en ne parlant pas des cas de dbordement), un dcalage vers la gauche dune position revient une multiplication par deux et un dcalage vers la droite correspond une division par deux.

IV.2.4 Oprateurs de relation


Les oprateurs de relation servent raliser des tests entre les valeurs de deux expressions. Comme nous le verrons plus tard, ces oprateurs sont surtout utiliss lintrieur des instructions de contrle. Les oprateurs de relation algbrique sont au nombre de six : (< <= > >= == !=). Ces oprateurs peuvent tre utiliss avec des variables de type entier ou des variables ayant une partie dcimale. Faudra faire attention en distinguant le double gal (==) pour le test du simple gal (=) qui dcrit laffectation. Les deux autres oprateurs de tests (&& ||) sont appels respectivement le et logique et le ou logique. Le et logique permet de dcrire quune condition constitue de deux parties est satisfaite si et seulement si les deux parties sont satisfaites. Le ou logique permet de dcrire quune condition constitue de deux parties est satisfaite ds lors quune des deux parties est satisfaite. Ces oprateurs servent donc dcrire des relations logiques du type ncessit de deux conditions (et logique) ou suffisance dune des deux conditions (condition ou). Ces oprateurs sappliquent des expressions que lon peut considrer comme de type entier et dont la valeur est teste comme pour le non logique savoir une expression est considre comme fausse si la valeur correspondant cette expression est gale 0. Ainsi, en langage C, pour tester si une variable de type entier j contient une valeur comprise entre deux bornes non strictes 12 et 143 il faut crire : j >= 12 && j <= 143. De mme, un test pour savoir si un caractre car contient un a ou un caractre b scrit : car == a || car == b.

IV.2.5 Oprateur binaire daffectation et de succession


En langage C, laffectation est un oprateur comme les autres. Ceci permet dcrire des expressions comme : i = j = k = 1 qui dtermine une affectation multiple. La virgule, quant elle, sert sparer deux expressions qui sont values successivement. La valeur associe sera la dernire valeur calcule. Une expression comme : i = (j=2, k=3) associe i la valeur 3 car : (j=2, k=3) signifie que j reoit 2, puis k reoit 3. Et comme k=3 sexcute aprs j=2, donc i = (j=2, k=3) signifie que i=3

IV.2.6 Oprateurs daffectation


Le langage C permet de construire des oprateurs binaires daffectation partir des oprateurs binaires arithmtiques, des oprateurs de masquage et des oprateurs de dcalage, en les faisant suivre dun gal (=). Lassociation dun oprateur arithmtique avec loprateur daffectation donne les oprateurs dcrits dans les exemples suivants : int i = 100,j = 5 ;. i += 10 donne i gal 110 car i = i + 10 ajoute 10 i i += j donne j gal 115 car i = i + j ajoute j i i -= 5 donne i gal 110 car i = i - 5 retranche 5 i i -= j donne i gal 105 car i = i - j retranche j i i *= 10 donne i gal 1050 car i = i * 10 multiplie i par 10 i *= j donne i gal 5250 car i = i * j multiplie i par j i /= 10 donne i gal 525 car i = i / 10 divise i par 10 i /= j donne i gal 105 car i = i / j divise i par j i %= 10 donne i gal 5 car i = i % 10 i reoit le reste de la division entire de i par 10

VI.2.7 Oprateur ternaire


Loprateur ternaire met en jeu trois expressions (ex1,ex2,ex3) et permet de construire une opration de test avec retour de valeur. La premire expression (ex1) joue le rle de condition. Si la condition est vrifie, lvaluation de la deuxime expression est ralise et le rsultat de cette expression est propag comme rsultat de lexpression globale.

Dans le cas contraire (le test est faux), lvaluation de la troisime expression est ralise et le rsultat de cette expression est propag comme rsultat de lexpression globale. Prenons pour exemple lexpression a == b ? c : d. Cette expression retourne la valeur contenue dans la variable c si la valeur contenue dans la variable a est gale celle de la variable b. Dans le cas contraire, lexpression retourne la valeur contenue dans la variable d. Lexpression a >= b ? a : b est value de la manire suivante : 1. si la valeur de a est suprieure ou gale la valeur de b, alors lexpression donne la valeur de a 2. sinon lexpression donne la valeur de b

IV.3 Expressions
Une EXPRESSION est : une suite syntaxiquement correcte doprateurs et doprandes. Cette suite doit donc avoir des oprandes cohrents en nombre et en type avec les oprateurs. Une expression ramne toujours une valeur, mme si la valeur nest pas utilise. Une expression est fausse si son rsultat est nul. Elle est vraie si son rsultat est non nul. Exemple : int i = 10, j , b =5; j = i + b; j = i / b; /* expression */ /* expression */

IV.4 Instructions
Maintenant que nous connaissons la notion dexpression nous pouvons introduire celle dinstruction. Une instruction est : soit une instruction simple, soit un bloc (ensemble dinstructions simples). Une instruction simple est : soit une instruction de contrle (voir chapitre suivant), soit une expression suivie de ;. Une instruction simple est toujours termine par un ;. Un bloc a la structure suivante : une accolade ouvrante "{" une liste de dfinitions locales de variables (optionnelle)

une suite dinstructions une accolade fermante "}".

Chapitre V : Instructions de contrle

Les instructions de contrle servent contrler le droulement de lenchanement des instructions lintrieur dun programme, ces instructions peuvent tre des instructions conditionnelles ou itratives.

V.1 Instructions conditionnelles


Les instructions conditionnelles permettent de raliser des tests, et suivant le rsultat de ces tests, dexcuter des parties de code diffrentes.

V.1.1 Test
Loprateur de test se prsente sous les deux formes prsentes comme suit : if( expression ) instruction1 else instruction2

Lexpression nest pas forcment un test qui retourne la valeur 0 ou 1. Ce peut tre un calcul ou une affectation, car, comme nous lavons dj dit dans la section 5.1.6 , il ny a pas de type boolen, et une expression est vraie si elle ramne un rsultat non nul. Elle est fausse si le rsultat est nul. Voici quelques exemples de tests en langage C :

if (a == b) usuel comme dans tous les autres langages int b = 1 ; if (a = b) vrai puisque b est gal 1 (donc non nul), attention car cela met la valeur de b dans a

Les tests sont souvent imbriqus pour tester si une variable contient une valeur. Lexemple suivant permet de tester si un nombre est pair ou impair et si il est suprieur 5 ou non.

#include <stdio.h>

main () { int i; scanf ("%d", &i); if (i > 5) { printf ("le nombre est superieur a 5"); } else { if (i % 2 == 0) printf ("le nombre est pair"); else printf ("le nombre est impair"); } }

V.1.2 Table de branchement


Pour viter les imbrications dinstructions if, le C possde une instruction qui cre une table de branchement : cest linstruction switch. La syntaxe du switch est rsume comme suit : switch (expression) { case valeur1 : { instruction(s) ; break ; } case valeur2 : { instruction(s) ; break ; } ... Case valeur n : { instruction(s) ;

break ; } default : { instruction(s); } }

Lexcution du switch est ralise selon les tapes suivantes : 1. lexpression est value comme une valeur entire 2. les valeurs des case sont values comme des constantes entires 3. lexcution se fait partir du case dont la valeur correspond

lexpression. Elle sexcute en squence jusqu la rencontre dune instruction break (sortir du switch) 4. les instructions qui suivent la condition default sont excutes lorsque aucune constante des case nest gale la valeur retourne par lexpression ; 5. lordre des case et du default nest pas prdfini par le langage mais par les besoins du programme 6. lexcution partir dun case continue sur les instructions des autres case tant quun break nest pas rencontr 7. plusieurs valeurs de case peuvent aboutir sur les mmes instructions 8. le dernier break est facultatif. Il vaut mieux le laisser pour la cohrence de lcriture, et pour ne pas avoir de surprise lorsquun case est ajout. Le programme suivant illustre un exemple dutilisation de larbre switch. Le programme offre 4 choix (a, b, c ou d) pour un caractre saisi et affiche le rsultat si ce caractre fait parti de ces derniers :

#include <stdio.h> main () { char c; printf("saisir un caractere"); scanf("%c", &c); switch(c) { case 'a' : { printf("le caractere saisi est un a"); break; } case 'b' : { printf("le caractere saisi est un b"); break; } case 'c' : { printf("le caractere saisi est un c"); break; } case 'd' : { printf("le caractere saisi est un d"); break; } default : printf("le caractere saisi ne correspond pas aux choix"); } }

V.2 Instructions itratives


Les instructions itratives sont commandes par trois types de boucles : le while le for le do while

V.2.1 while
Linstruction while est un bloc rptitif dune ou plusieurs instructions. Elle sexcute en continu tant quune expression est vraie. Si lexpression est fausse, on sort de la boucle. Syntaxe : While(expression) { Instruction(s); }

fausse expression Vraie Instruction(s)

Reprenons lexemple prcdent (4 choix de caractres) avec la boucle while. Le programme est le suivant :

#include <stdio.h> main () { int i = 0; char c; while(i==0) { printf("saisir un caractere");

scanf("%c", &c); if(c==a || c==b || c==c || c==d) { printf("le caractere saisi est %c", c); i = 1 ; } } }

V.2.2 for
Comme linstruction while, for est une instruction rptitive dune ou plusieurs instructions. Elle sexcute en continu tant que trois expressions sont vrifies. Syntaxe : for(expression1;expression2;expression3) { instruction(s); }
1.

lexpression1 est ralise une seule fois lors de lentre dans la boucle, nous

lappellerons expression dinitialisation 2. lexpression 2 est la condition dexcution de linstruction. Elle est teste chaque itration, y compris la premire. Tant que lexpression 2 est vraie, linstruction contrle par le for est excute, sinon la boucle se termine 3. lexpression 3 contrle lavancement de la boucle. Elle permet de manire gnrale de calculer la prochaine valeur avec laquelle la condition de passage va tre reteste, elle est excute aprs linstruction chaque itration avant le nouveau test de passage. Le for est quivalent un while plus une instruction dinitialisation et une instruction de contrle.

Expression 1

fausse Expression 2 Vraie Instruction(s)

Expression 3

Voici quelques exemples pratiques de la boucle for : 1. for (i = 0 ; i < 10 ; i++) 2. for (i = 0 , j = 10 ; i < j ; i++ , j--) Lexemple suivant montre un programme qui calcule la somme dune suite dentiers de 1 10 : #include <stdio.h> main () { int i,s=0; for(i=0;i<=10;i++) { s += i; } printf("la somme est %d", s); }

V.2.3 do while
La syntaxe du do while est donne comme suit : do instruction(s); while(expression); Cest une forme inverse de linstruction while. Elle permet cependant dexcuter lensemble des instructions mme si lexpression nest pas vrifie. Linstruction do while doit tre manipule avec beaucoup de prcaution !!!

V.2.4 Remarques sur les instructions itratives


Comme nous lavons vu auparavant, une instruction peut tre une instruction simple ou un bloc. Les diffrentes boucles peuvent tre imbriques et, comme nous le verrons plus tard, il faut sastreindre une certaine mise en page pour faciliter la lecture du programme.

V.3 Ruptures de squence


Dans le cas o une boucle commande lexcution dun bloc dinstructions, il peut tre intressant de vouloir sortir de cette boucle alors que la condition de passage est encore valide. Ce type dopration est appel une rupture de squence. Les ruptures de squence sont utilises lorsque des conditions multiples peuvent conditionner lexcution dun ensemble dinstructions. Les ruptures de squence sont ralises par quatre instructions qui correspondent leur niveau de travail : 1. continue 2. break

V.3.1 continue
Linstruction continue est utilise en relation avec les boucles. Elle provoque le passage litration suivante de la boucle en sautant la fin du bloc. Ainsi, cette instruction permet la non excution des instructions qui la suivent lintrieur du bloc. Reprenons lexemple des 4 choix de caractres avec la boucle while en ajoutant quelques instructions, par exemple (crire bonjour, crire une date). Le programme devient:

#include <stdio.h>

main () { int i = 0; char c; while(i==0) { printf("saisir un caractere"); scanf("%c", &c); if(c==a || c==b || c==c || c==d) { printf("le caractere saisi est %c ", c); printf("bonjour "); printf("la date est 2/3/2012"); i = 1 ; } } }

Lexcution du programme pour un caractre saisi a donne le rsultat suivant : le caractere saisi est a bonjour la date est 2/3/2012 maintenant si nous introduisons linstruction continue comme suit : printf("le caractere saisi est %c", c); continue ; printf("bonjour"); printf("la date est 2/3/2012");

Lexcution du programme ne sarrte pas mme si le bon caractre est saisi car la condition de sortie de la boucle (i=1) est saute par linstruction continue, ainsi que laffichage de bonjour et de la date.

V.3.2 break
Nous avons dj vu une utilisation du break dans le switch. Plus gnralement, il permet de sortir dun bloc dinstruction associ une instruction rptitive ou alternative contrle par les instructions if, for, un while ou un do while. Reprenons lexemple des choix de caractres. On pourra ainsi remplacer la condition de sortie (i=1) par linstruction break : #include <stdio.h> main () { int i = 0; char c; while(i==0) { printf("saisir un caractere"); scanf("%c", &c); if(c==a || c==b || c==c || c==d) { printf("le caractere saisi est %c ", c); break; } } }

Chapitre VI : Les fonctions

Les fonctions sont des parties de programme qui permettent de raliser le mme type de traitement plusieurs fois et/ou sur des variables diffrentes. Une fonction en langage C peut : modifier des donnes globales. Ces donnes sont dans une zone de mmoire qui peut tre modifie par le reste du programme. Une fonction peut dans ces conditions raliser plusieurs fois le mme traitement sur un ensemble de variables. communiquer avec le reste du programme par une interface. Cette interface est spcifie la compilation. Lappel de la fonction correspond un change de donnes travers cette interface, au traitement de ces donnes (dans le corps de fonction), et un retour de rsultat via cette interface. Ainsi, une fonction permet de raliser le mme traitement sur des ensembles de variables diffrents.

VI.1 Dfinition dune fonction


Lors de leur dfinition ou de leur utilisation, les fonctions sont distingues des variables par la prsence des parenthses ouvrantes et fermantes. La fonction est toujours dfinie avant le programme principal (main) de la manire suivante : type nom_fonction (variable1, variable2, , variablen) { Expressions ou instructions ; } le type de la fonction peut tre sans retour ou avec retour. les variables sont les variables usuelles du langage C : entiers, rels, caractres, tableaux, chanes de caractres etc

VI.1.1 Fonctions sans retour


Les fonctions sans retour sont des fonctions qui agissent sur les variables mais ne retournent pas de valeur utilisable dans le programme principal. Syntaxe :

void nom_fonction (type variable1, type variable2, , type variablen) { Expressions ou instructions ; }

Reprenons lexemple prcdent (4 choix) quon va transformer en fonction nomme choix : #include <stdio.h> void choix (char c) { if(c==a || c==b || c==c || c==d) printf("le caractere saisi est %c ", c); else printf("le caractere saisi ne correspond a aucun choix"); } main () { char c; printf("saisir un caractere"); scanf("%c", &c); choix(c) ; }

Ainsi nous pouvons utiliser la fonction choix plusieurs fois dans le programme principal. Exemple avec une boucle for qui se rpte 6 fois : #include <stdio.h> void choix (char c) { if(c==a || c==b || c==c || c==d) printf("le caractere saisi est %c ", c); else printf("le caractere saisi ne correspond a aucun choix"); } main () { int i ; char c; for(i=0;i<6;i++) {

printf("saisir un caractere"); scanf("%c", &c); choix(c) ; } } Nous remarquons le point fort des fonctions dans ce cas. Ca nous a permis dutiliser la mme fonctions plusieurs fois et donc allger lcriture du programme. Sinon, crire la mme partie du programme 6 fois !!!

V.1.2 fonctions avec retour


Les fonctions avec retour sont des fonctions qui traitent des variables et retournent des valeurs de mme type de fonction et qui sont tilisables dans le programme principal. La dclaration de ces fonctions est prcde par la spcification du type. Syntaxe : Type nom_fonction(type variable1, type variable2,, type variablen) { Expressions ou instructions ; Return variable; } Le type de la fonction correspond aux types usuels dans le langage C (int, float, char,). Exemple : int addition (int a, int b) { int c; c = a + b; return c; }

Programme complet : #include <stdio.h> int addition(int a, int b) { int c; c = a + b; return c; } main () { int a,b,i; printf("saisir le premier entier"); scanf("%d", &a); printf("saisir le deuxieme entier"); scanf("%d", &b); i = addition(a,b); printf("la somme est %d", i); }

Exercices rsolus

Exercice I
Ecrire un programme C qui saisit un tableau de 10 entiers, cherche et affiche le plus grand lment.

Solution
#include <stdio.h> main() { int t[10],i,a; for(i=0;i<10;i++) { printf("entrer l'element %d scanf("%d",&t[i]); } a=t[0]; for(i=0;i<10;i++) { if(t[i]>a) { a=t[i]; } } printf("le plus grand element du tableau est %d",a); } : ",i+1);

Exercice II
Ecrire un programme C qui saisit un entier puis vrifie si ce dernier est premier ou non

Solution
#include <stdio.h> main() { int i,N,a=0; printf("saisir l'entier souhaite : "); scanf("%d",&N);

for(i=1;i<N+1;i++) { if(N%i==0) { a++; } } if(a==2) printf("le nombre %d est un nombre premier\n",N); else printf("le nombre %d n'est pas un nombre premier\n",N); }

Exercice III
Rappel sur les tableaux bidimensionnels : Un tableau bidimensionnel est un tableau form de lignes et de colonnes. En dautres termes, cest un empilement de tableaux traditionnels. Exemple :

Tableau de 5 lments

Tableau bidimensionnel de 5 lignes et 5 colonnes La syntaxe utilise en langage C est la suivante : type nom_tableau[nombre_de_lignes][nombre_de_colonnes]; Exemple : int matrice[3][5]; Char liste[4][6];

Enonc de lexercice : A la rentre scolaire, une cole souhaite raliser un programme qui saisit une liste contenant les informations sur les tudiants : - Nom et prnom - Note des contrles ainsi que la moyenne pour une matire donne. Ecrire un programme C qui saisit cette liste et laffiche, sachant que la classe est forme de 5 lves et quil y a trois contrle.

Solution
#include <stdio.h> #include <string.h> main() { char liste[5][20]; /* dclare une matrice de 5 lignes (chanes
caractres) */ 20 de

int i,j; float notes[5][4]; /* declare une matrice de 5 lignes et 4 colonnes */ printf("Bonjour et bienvenue au programme : \n"); for(i=0;i<5;i++) { printf("saisir le nom et le prenom de l'etudiant %d : ", i+1); gets(liste[i]); /* saisie de la chane de caractres dordre i */ for(j=0;j<3;j++) { printf("saisir la note %d : ", j+1); scanf("%f",&notes[i][j]);
3 contrles */ /* boucle qui parcours les 3 premires

colonnes dune ligne i (grce au compteur j) afin de remplir les notes des

} notes[i][3] = (notes[i][0] + notes[i][1] + notes[i][2])/3;


/* La quatrime colonnes dune ligne i reoit la moyenne des 3 colonnes prcdentes */

} for(i=0;i<5;i++) { puts(liste[i]); /* affichage du nom et prnom dun tudiant dordre i */

printf("moyenne : %f\n", notes[i][3]);/* affichage de sa moyenne */ } }

Exercice 4
Reprendre lexercice prcdent en ajoutant une partie qui permet de trier les noms des tudiants par ordre croissant. Les notes correspondant doivent galement tre tris. #include <stdio.h> #include <string.h> main() { char liste[5][20],temp1[20],temp2[20]; int i,j,k; float notes[5][4],ftemp1[4],ftemp2[4]; printf("Bonjour et bienvenue au programme : \n"); for(i=0;i<5;i++) { printf("saisir le nom et le prenom de l'etudiant %d : ", i+1); gets(liste[i]); for(j=0;j<3;j++) { printf("saisir la note %d : ", j+1); scanf("%f",&notes[i][j]); notes[i][3] = (notes[i][0] + notes[i][1] + notes[i][2])/3; } } for(i=0;i<5;i++) { for(j=i+1;j<5;j++) { if(strcmp(liste[i],liste[j])>0) { strcpy(temp1,liste[i]); strcpy(temp2,liste[j]);

strcpy(liste[j],temp1); strcpy(liste[i],temp2); for(k=0;k<4;k++) { ftemp1[k]=notes[i][k]; ftemp2[k]=notes[j][k]; } for(k=0;k<4;k++) { notes[i][k]=ftemp2[k]; notes[j][k]=ftemp1[k]; } } } } for(i=0;i<5;i++) { puts(liste[i]); printf("moyenne : %f\n", notes[i][3]); } }

You might also like