Académique Documents
Professionnel Documents
Culture Documents
Introduction
Un programme est un texte constitu dun ensemble de directives appeles instructions, qui reprsentent une suite dactions lmentaires que lordinateur doit accomplir sur des donnes en entre, afin datteindre le rsultat recherch.
nombre limit doprations codes en binaire (langage machine). Les premiers programmes taient crits en binaire; Ctait une tache trs difficile et exposs aux erreurs. Par la suite, pour faciliter le travail, on a utilis des codes mnmoniques pour dfinir les oprations (ADD, DIV, SUB, MOVE ) ses symboles sont traduit en langage machine par un programme appel assembleur.
langage qui permet dexploiter au maximum les ressources de la machine. Mais programmer en assembleur reste tout de mme une tache fastidieuse et prsente en plus un problme de portabilit.
tre humain d'crire un code source. qui sera analys par un ordinateur. Le code source subit ensuite une transformation ou une valuation dans une forme exploitable par la machine, ce qui permet d'obtenir un programme.
galement tre traduits en langage machine pour tre excuts. La conversion se fait de deux manires: la compilation et linterprtation. La compilation consiste traduire dans un premier temps lensemble du programme en langage machine. Dans un deuxime temps, le programme est excut. Linterprtation consiste traduire chaque instruction du programme en langage machine avant lexcuter
Dmarche de programmation
La faon d'crire un programme est intimement lie
au langage de programmation que l'on a choisi, mais la dmarche programmation se droule gnralement en deux tapes:
Dabord on identifie les donnes du problme, les rsultats recherchs et par quel moyen on peut obtenir ces dernier partir des donnes. Cest ltape danalyse qui aboutit un procd de rsolution appel algorithme .
Un algorithme, cest une suite dinstructions, qui une fois excute correctement, conduit au rsultat recherch. Un algorithme doit donc contenir uniquement des instructions comprhensibles par celui qui devra lexcuter. Dans un deuxime temps, on traduit dans le langage de programmation choisi lalgorithme tabli dans la phase prcdente. Si lalgorithme est bien crit, sans faute logique, ltape suivante ne doit normalement poser aucun problme conceptuel. Cest une simple traduction que vous devez effectuer.
Initiation au language C
Historique
Le C a t conu en 1972 par Dennis Richie et Ken Thompson, chercheurs
aux Bell Labs, afin de dvelopper un systme d'exploitation UNIX. groupes mirent sur le march des compilateurs comportant des extensions particulires.
normaliser le langage ; ce travail s'acheva en 1989 par la dfinition de la norme ANSI C. Organization) en 1990.
Celle-ci fut reprise telle quelle par l'ISO ( International Standards C'est ce standard, ANSI C, qui est dcrit dans le prsent document
0 1
2
Les identificateurs
Un identificateur permet de nommer une variable, une pseudo
constante ou une fonction. Ils doivent tre crits selon les rgles suivantes : - 32 caractres maximum (certains systmes ne tiennent compte que des 8 premiers). - le premier caractre doit obligatoirement tre soit une lettre - les autres caractres peuvent tre indiffremment des lettres (a-z), des chiffres ou le soulign. - le signe '-', l'espace, les caractres accentus ainsi que tous les caractres non cits au paragraphe prcdent sont interdits. - en rgle gnrale, le nom des variables est crit en lettres minuscules et celui des pseudo-constantes en majuscules (Conventions des programmeurs). - le compilateur C fait la diffrence entre majuscules et minuscules
Les sparateurs
Les diffrents sparateurs reconnus par le compilateur
Les commentaires
Les commentaires permettent de porter des remarques afin de faciliter la lecture d'un programme source. Chaque commentaire est dlimit par les combinaisons suivantes :
/* dbut de commentaire */ fin de commentaire Les commentaires ne peuvent pas tre imbriqus.
Les commentaires ne sont pas pris en compte par le compilateur et n'augmentent donc pas la taille des
programmes excutables.
type n'a pas de sens. Cette notion n'a t introduite que par les langages de haut niveau dans le but de rendre les programmes plus rationnels et structurs. Mais mme parmi les langages de haut niveau, on distingue ceux qui sont dits fortement typs (qui offrent une grande varit de types), comme le Pascal par exemple, de ceux qui sont dits faiblement ou moyennement typs (et plus proches de la machine) comme le C par exemple.
grandes catgories en fonction de la nature des informations quils permettent de reprsenter : Les entiers int entier short entier court long entier long
Les caractres
float double
Les entiers
Ce sont des variables de type simple dont la taille et les
unsigned int ent; /* dclaration de la variable ent de type entier non sign */
Les entiers
Tous les int nont pas la mme taille sur toutes les machines !
Frquemment, deux des trois mots-cls correspondent une mme taille (par exemple, sur PC, short et int correspondent 16 bits, tandis que long correspond 32 bits).
titre indicatif:
32 767 Avec 32 bits, on peut couvrir les valeurs allant de -2 147 483 648 2 147 483 647.
Les caractres
Le mot-clef char dsigne un objet de type caractre. Un char peut contenir n'importe quel lment du jeu de
caractres de la machine utilise. La plupart du temps, un objet de type caractre est cod sur 8 bits ( un octet ) et dclar entre ' '. Un caractre peut tre dclar non sign, dans ce cas, la plage des valeurs ASCII sera de 0 255. Exemple:
main() { char c = 'A'; printf("%c", c + 1); }
Type
Longueur UNIX int Entier 4 short Entier court 2 unsigned short Entier court non sign 2 long Entier long 4 unsigned long Entier long non sign 4 char Caractre 1 unsigned char Caractre non sign 1
Dnomination
Longueur DOS 2 2 2 4 4 1 1
Valeurs limites
-32 768 32 767 0 65535 -2 147 483 648 2 147 483 647 0 4 294 967 295 -128 127 0 255
approche, une partie des nombres rels. Les flottants sont gnralement stocks en mmoire sous la reprsentation de la virgule flottante normalise. Plus prcisment, un nombre rel est reprsent en flottant en dterminant deux quantits M (mantisse) et E (exposant) telles que la valeur:
E M.B
Le C prvoit trois types de flottants correspondant des tailles diffrentes : float, double et long double.
Longueur 4 8 10
Comme dans la plupart des langages, les constantes flottantes peuvent scrire indiffremment suivant lune des deux notations : dcimale, exponentielle.
simple, se fait de la manire suivante : <type> variable; Par exemple : int n; int a, b, c; Une dclaration de variable de la forme : int i = 0, j, n = 10; double x, y, z = 0.5; est appele une dclaration avec initialisation. Ce n'est pas la mme chose que : int n; n = 0; qui est une dclaration suivie d'une instruction d'affectation.
Une instruction est une expression qui doit tre suivie d un point-virgule (fin de linstruction
Plusieurs instructions peuvent tre rassembles par des accolades { } et forme une instruction compose ou bloc, par exemple :
if (x !=0) { z = y / x; t = y % x; }
Une instruction compose d un spcificateur de type et d une liste d identificateurs spars par une virgule est une dclaration, par exemple :
int a; int b = 1, c; char message[80];
Affectation :
variable = expression expression est valu et est affecte variable.
de l'expression est convertie dans le type du terme de gauche. est convertit dans le type du terme gauche. main() { int i, j = 2; float x = 2.5; i = j + x; x = x + i; printf("\n %f \n",x) }
conversion dajustement de type . Une telle conversion ne peut se faire que suivant une hirarchie qui permet de ne pas dnaturerla valeur initiale
int -> long -> float -> double -> long double si n est de type int, p de type long et x de type float, lexpression : n*p+x sera value suivant ce schma :
OPRATEUR <
SIGNIFICATION infrieur <= infrieur ou gal > suprieur >= suprieur ou gal == gal != diffrent de C se distingue de la plupart des autres langages sur deux points :
(on dit aussi logique) prenant lune des deux valeurs vrai ou faux, mais un entier valant : 0 si le rsultat de la comparaison est faux, 1 si le rsultat de la comparaison est vrai. Ainsi, la comparaison ci-dessus devient en fait une expression de type entier. Cela signifie quelle pourra ventuellement intervenir dans des calculs arithmtiques ; les expressions compares pourront tre dun type de base quelconque et elles seront soumises aux rgles de conversion prsentes dans le paragraphe prcdent. Cela signifie quau bout du compte on ne sera amen comparer que des expressions de type numrique.
valeur retourne par ces oprateurs est un int qui vaut 1 si la condition est vraie et 0 sinon.
Par exemple : (a<b) && (c<d) prend la valeur 1 (vrai) si les deux expressions a<b et c<d sont
toutes deux vraies (de valeur 1), et prend la valeur 0 (faux) dans le cas contraire. (a<b) || (c<d) prend la valeur 1 (vrai) si lune au moins des deux conditions a<b et c<d est vraie (de valeur 1), et prend la valeur 0 (faux) dans le cas contraire. ! (a<b) prend la valeur 1 (vrai) si la condition a<b est fausse (de valeur 0) et prend la valeur 0 (faux) dans le cas contraire. Cette expression est quivalente : a>=b.
BIT
Le langage C dispose doprateurs permettant de travailler directement sur le motif binaire dune valeur. Ceux-ci lui procurent ainsi des possibilits traditionnellement rserves la programmation en langage assembleur.
Exemple:
+=
-=
*=
/=
&=
^= |= <<= <<= Pour tout oprateur op : expression1 op= expression2 quivaut expression1 = expression1 op expression2 expression1 n'est valu qu'une seule fois
I++ ou ++I pour l'incrmentation (augmentation d'une unit) I-- ou --I pour la dcrmentation (diminution d'une unit)
vaut:
vaut:
1 0
Oprateur virgule
Une expression peut tre constitue d'une suite d'expressions spares par des virgules :
expression1 , expression2 , expression 3
Cette expression est gale expression-1 si condition est satisfaite, et expression-2 sinon.
Exemples:
x>=0 ? x : -x; correspond la valeur absolue m = ((a>b) ? a : b); affecte m le maximum de a et b a = (v == 2) ? 1 : 2; affecte la variable a la valeur 1 si v vaut 2, sinon affecte la variable a la valeur 2.
utiliser, le programme doit contenir la ligne: #include <math.h> Type des donnes Les arguments et les rsultats des fonctions arithmtiques sont du type double.
COMMANDE C
EXPLICATION fonction exponentielle logarithme naturel logarithme base 10 X exposant Y racine carre de X valeur absolue de X arrondir en moins arrondir en plus reste rationnel de X/Y
LANG. ALGORITHMIQUE
|X| int(X)
sin(X) cos(X) tan(X) sinus, cosinus, tangente de X asin(X) acos(X) atan(X) arcsin(X), arccos(X), arctan(X) sinh(X) cosh(X) tanh(X) sinus, cosinus, tangente hyperboliques de X
Lecture criture
La bibliothque standard <stdio> contient un ensemble de fonctions qui assurent la communication de la machine avec le monde
extrieur. Les plus importantes sont: printf() criture formate de donnes scanf() lecture formate de donnes putchar() criture d'un caractre getchar() lecture d'un caractre
des valeurs de variables ou des rsultats d'expressions vers le fichier de sortie standard stdout (par dfaut l'cran). La syntaxe est la suivante: printf ( format, liste dexpressions ) "<format>" format de reprsentation <liste des expressions>,...variables et expressions dont les valeurs sont reprsenter
peut contenir: du texte, des squences d'chappement, des spcificateurs de format. Les spcificateurs de format indiquent la manire dont les valeurs des expressions <Expr1..N> sont imprimes. * La partie "<format>" contient exactement un spcificateur de format pour chaque expression <Expr1..N>. * Les spcificateurs de format commencent toujours par le symbole % et se terminent par un ou deux caractres qui indiquent le format d'impression. * Les spcificateurs de format impliquent une conversion d'un nombre en chane de caractres. Ils sont encore appels symboles de conversion.
printf("%i fois %i est %li\n", A, B, (long)A*B); va afficher sur l'cran: 1234 fois 567 est 699678
printf ("%10f", x) ; /* notation dcimale - gabarit mini 10 */
/* (toujours 6 chiffres aprs point) */ x = 1.2345 ^^1.234500 x = 12.345 ^12.345000 x = 1.2345E5 123450.000000
/* (6 chiffres aprs point) */ x = 1.2345 1.234500e+000 x = 123.45 1.234500e+002 x = 123.456789E8 1.234568e+010 x = -123.456789E8 -1.234568e+010
calage gauche signe moins -
printf("%-10.3f", x)); x = 1.2345 1.235 ^^^^^ le caractre * dans le gabarit ou dans la prcision signifie que la valeur effective est fournie dans la liste des arguments de printf. printf("%8.*f",n,f); n = 1 f = 99.12345 ^^^^99.1
putchar
Lexpression :
char A = 225; putchar('x'); /* afficher la lettre x */ putchar('?'); /* afficher le symbole ? */ putchar('\n'); /* retour la ligne */ putchar(65); /* afficher le symbole avec */ /* le code 65 (ASCII: 'A') */ putchar(A); /* afficher la lettre avec */ /* le code 225 (ASCII: '') */
principe le clavier du poste de travail) est scanf( format , adresse1 , adresse2 , ... adressen ) Largument format est une chane qui indique la manire de convertir les caractres qui seront lus ; adresse1, adresse2, ... adressen indiquent les variables devant recevoir les donnes lues. Ce sont des sorties de la fonction scanf, par consquent il est essentiel que ces arguments soient des adresses de variables lire.
La fonction scanf est la fonction symtrique printf; elle nous offre
Exemples:
scanf("%d%d",&n,&p);
45^23@ ===> n = 45 p = 23 45@@23@ ===> n = 45 p = 23 int JOUR, MOIS, ANNEE; scanf("%i %i %i", &JOUR, &MOIS, &ANNEE); les entres suivantes sont correctes et quivalentes: 12 4 1980 ou 12 004 1980 ou 12 4 1980
scanf("%d%c",&n,&c);
45^a
===> n = 45 c =
getchar
getchar() est quivalent scanf("%c",c)
La fonction getchar permet la rcupration d'un seul caractre partir du
clavier. La syntaxe d'utilisation de getchar est la suivante: variable=getchar(); Il faut noter que variable doit tre de type char et les parenthses aprs getchar.
#include <stdio.h>
int main() { char c; c = getchar(); /* le programme suspend son fonctionnement jusqu'a ce que l'utilisateur tape*/ /* au moins un caractre puis la touche <return> */ putchar(c); } L'utilisateur tape par exemple la touche <a> puis la touche <return>. Il a tap deux caractres car le <return> est un caractre en fait c'est le caractre '\n' (NL). On obtient l'affichage : a a
Les tableaux
Les tableaux permettent de grer un ensemble de variables de
mme type. Un tableau est une zone mmoire constitue de cases contigus o sont ranges des donnes de mme type. Les cases ont donc une taille identique. Un tableau possde un nombre fix de cases qui doit tre connu quand il est cr. La zone mmoire possde donc un dbut et une fin. Pour accder une case, nous utilisons un indice qui repre le numro de la case laquelle on fait rfrence. L'indice d'un tableau est un index, il y a ainsi un lien troit entre tableau et pointeur comme nous allons le voir dans ce chapitre. Comme toute variable, une case d'un tableau doit tre initialise avant d'tre utilise.
Dclaration:
La syntaxe de dclaration d'une variable de type tableau un
indice est la suivante : type identificateur [N]; o : - type est le type de variable contenu dans de chaque case du tableau - identificateur est le nom donn au tableau - N est une valeur entire qui donne le nombre total de cases du tableau La valeur de N doit tre connue la compilation, il n'est pas possible d'utiliser des tableaux de taille variable. Par contre, nous pouvons dcider de n'utiliser qu'une partie des cases d'un tableau.
Exemples: - int tab1[5]; Les cinq lments du tableau sont identifiables individuellement par tab1[0], tab1[1], tab1[2], tab1[3] et tab1[4]. - #include <stdio.h> int main() { float tableau[2] = {6, 16}; printf ("Premiere valeur du tableau : %f\n", tableau[0]); printf ("Seconde valeur du tableau : %f\n", tableau[1]); return 0; }
Soit une tableau t(5,3) un tableau de 5 lignes et de 3 colonnes. En C t est dclar par t[5][3]; Le rangement en mmoire des lments de t est:
liste des valeurs respectives entre accolades. Exemple: 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}}; #define N 10 ... int tab[5] = { 2*N-1, N-1, N, N+1, 2*N+1}
ligne dun tableau a deux dimensions ne sont pas indiqus explicitement, lors de l'initialisation, l'ordinateur rserve automatiquement le nombre d'octets ncessaires. Exemples: int tab[] = { 10, 20, 5, 0, 3 } ; int A[][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[][2] = {{-1.05, -1.10 }, {86e-5, 87e-5 }, {-12.5E4, -12.3E4}};
LA STRUCTURE ALTERNATIVE
Le test simple : permet de raliser un choix parmi deux
possibilits (Ex :Boolenne : vrais ou faux)
dans tous les langages (avec une syntaxe diffrente...). Elle permet d'excuter une srie d'instructions si jamais une condition est ralise. La syntaxe de cette expression est la suivante : if (condition ralise) { liste d'instructions;
}
Exemple: int main () { long x = 5; long y = 3; /* si x est suprieur y */ if ( x > y) printf("X est superieur a Y") return 0; }
If.. else.
si condition = vraie alors
Opration 1 Opration 2
opration 1
sinon
opration 2
La structure alternative en C
if ( <expression> ) <bloc d'instructions 1> else <bloc d'instructions 2> * Si l'<expression> fournit une valeur diffrente de zro, alors le <bloc d'instructions 1> est excut * Si l'<expression> fournit la valeur zro, alors le <bloc d'instructions 2> est excut
Exemples:
instruction if pouvaient tre absolument quelconques. En particulier, elles peuvent leur tour renfermer des instructions if .Or, compte tenu de ce que cette instruction peut comporter ou ne pas comporter de else il existe certaines situations o une ambigut apparat.
Exemple
If(n>0)
If.. Elseif
En algorithmique: si .. Sinon si. La forme la plus gnrale est celle-ci :
if (expression-1 ) instruction-1 else if (expression-2 ) instruction-2 ... else if (expression-n ) instruction-n-1 else instruction-n
Exemple:
int a, b; printf("Ce programme compare deux nombres.\n"); printf("Entrez la valeur de a : "); scanf("%d", &a); printf("Entrez la valeur de b : "); scanf("%d", &b); if (a < b) printf("a est plus petit que b.\n"); else if (a > b) printf("a est plus grand que b.\n"); else printf("a est egal a b.\n"); return 0; }
pour une expression. Syntaxe : switch (expression) { case val1 : ... squences dinstructions break ; case val2 : ... squences dinstructions break ; ... ... default : ... squences dinstructions }
Le fonctionnement de cette instruction est le suivant : 1. Lexpression est dabord value (a peut tre un entier, un flottant,... mais pas une chane de caractres). 2. Si le rsultat vaut val1, alors la squence dinstructions qui suit est excute. 3. Sinon, si le rsultat vaut val2, alors la squence dinstructions qui suit est excute. 4. Sinon, si le rsultat vaut val3, etc., etc. 5. Enfin, si aucun des cas nest bon, on excute ce qui suit default :..
Exemples: Excutons le programme suivant: #include <stdio.h> main() { int n ; printf ("donnez un entier : ") ; scanf ("%d", &n) ; switch (n) { case 0 : printf ("nul\n") ; break ; case 1 : printf ("un\n") ; break ; case 2 : printf ("deux\n") ; break ; } printf ("au revoir\n") ; }
Et excutons le programme suivant: #include <stdio.h main() { int n ; printf ("donnez un entier : ") ; scanf ("%d", &n) ; switch (n) { case 0 : printf ("nul\n") ; case 1 : printf ("un\n") ; case 2 : printf ("deux\n") ; } printf ("au revoir\n") ; }
Attention:
Lorsquil y a branchement russi un case, toutes les instructions qui le suivent sont excutes, jusqu la fin du bloc ou jusqu une instruction de rupture (break).
Les boucles
En C, on dispose de trois structures qui nous permettent la
While:
La structure tant que en langage algorithmique
Exemples:
1- /* Afficher les nombres de 0 9 */ int I = 0; while (I<10) { printf("%i \n", I); I++; } 2- /* Afficher les nombres de 10 1 */ int I=10; while (I) printf("%i \n", I--);
Do-while
La structure tant que en langage algorithmique
faire
(<bloc dinstructions>) tant que(<expression logique>) La structure do - while est semblable la structure while, avec la diffrence suivante : - while value la condition avant d'excuter le bloc d'instructions, - do - while value la condition aprs avoir excut le bloc d'instructions. Ainsi le bloc d'instructions est excut au moins une fois.
do
Exemples:
- do
} while ( printf("vous avez fourni %d", n), n<= 0 ) - float N; do { printf("Introduisez un nombre entre 1 et 10 :"); scanf("%f", &N); } while (N<1 || N>10);
Le boucle for
Linstruction for en C est
for ( [ expression_1 ] ; [ expression_2 ] ; [ expression_3 ] ) Instruction Cette instruction est quivalente : expression_1 ; while (expression_2) { instruction expression_3 ; }
Exemples:
- f or( i = 0; i < 5; i++) { printf("boucle for : "); printf(" %d fois \n", i + 1 ); } - int n, tot; for (tot=0, n=1 ; n<101 ; n++) tot+=n; printf("La somme des nombres de 1 100 est d\n", tot);
en un emplacement
Les fonctions
Comme dans la plupart des langages, on peut en C
dcouper un programme en plusieurs fonctions. Une seule de ces fonctions existe obligatoirement ; c'est la fonction principale appele main. Cette fonction principale peut, ventuellement, appeler une ou plusieurs fonctions secondaires. De mme, chaque fonction secondaire peut appeler d'autres fonctions secondaires ou s'appeler elle-mme (dans ce dernier cas, on dit que la fonction est rcursive).
Une fonction est un sous-programme qui reoit ventuellement des arguments en entre (ces arguments sont toujours des valeurs) et qui retourne ventuellement une valeur d'un certain type vers la fonction appelante. Dfinition de fonction la syntaxe d'une fonction: [type-de-retour] nom-de-fonction( liste des arguments) { [dclarations de variables locales] liste d'instructions }
Les arguments d'une fonction sont simplement des variables locales qui sont initialises par les valeurs obtenues lors de l'appel.
fonction se nomment des arguments muets , ou encore arguments formels ou paramtres formels Leur rle est de permettre, au sein du corps de la fonction, de dcrire ce quelle doit faire. Les arguments fournis lors de lutilisation (lappel) de la fonction se nomment des arguments effectifs (ou encore paramtres effectifs ). La fonction se termine par l'instruction return : return(expression); expression du type de la fonction return; fonction sans type
Exemple de fonction :
int imax(int n, int m) { int max; if (n>m) max = n; else max = m;
Dclaration de la fonction
Variable locale
de la liste des valeurs donner aux paramtres entre parenthses. Un appel de fonction est considre comme une expression du type du rsultat de la fonction et la valeur de cette expression est le rsultat de l'excution de la fonction.
Exemple de fonction :
Variables effectives int main() { int x,y; scanf("%d%d",&x,&y); imax(x, y); getch(); return 0; }
Lors de lappel, il est souvent ncessaire dchanger des informations entre la procdure et le programme ou le module appelant. Cest le rle des paramtres.
void permet de spcifier que la fonction n'a aucun argument : int fonction(void) { ... } L'appel une fonction sans argument se fait de la manire suivante : { ... i = fonction(); Ne pas oublier les parenthses !!! ... }
La rcursivit
La rcursivit est une technique de programmation
alternative litration qui permet de trouver, lorsquelle est bien utilise, des solutions trs lgantes un certain nombre de problmes. Une procdure ou fonction est dite rcursive si son corps contient un ou plusieurs appels elle-mme : Procdure Precur(paramtres) Dbut Precur(valeurs) Fin
fonctions. Celle-ci peut prendre deux aspects : rcursivit directe : une fonction comporte, dans sa dfinition, au moins un appel elle-mme, rcursivit croise : lappel dune fonction entrane celui dune autre fonction qui, son tour, appelle la fonction initiale (le cycle pouvant dailleurs faire intervenir plus de deux fonctions). Exemple: Ecrivons une fonction rcursive qui calcule le produit factoriel dun nombre
1- Fonction non rcursive: long fact (int n) { int i,f; f=1; for(i=1; i<=n; i++) { f=f*i; } return }
2- Fonction rcursive: long fac (int n) { if (n>1) return (fac(n-1)*n) ; else return(1) ; }
main() { Int a, b; printf("Donnez deux entiers\n"); scanf("%d %d", &a, &b); printf("Le pgcd de %d et de %d est %d\n", a, b, pgcd(a, b)); }
Les structures
En plus des types de base (entiers, rels, caractres, etc.), il est
possible dans la plupart des langages de programmation de dfinir ses propres types. Il sagit en fait de rassembler dans un enregistrement une ou plusieurs variables, qui peuvent tre de types diffrents, et de les regrouper sous un seul nom afin de les manipuler plus facilement. Cette enregistrement est appele en C Structure. Un enregistrement peut tre dfini par une dclaration de type contenant une liste de champs prcde par le mot struct
correspondra une structure contenant trois variables, de types que vous demandez.
Exemple:
struct { char nom[8] ; int num ; char mois[8] ; int an } jour [366] ; Les 366 structures ainsi dfinies appeles jour regroupent chacune une chane de 8 caractres pour le nom du jour, un entier pour son numro, une autre chane de longueur 8 pour le mois et un entier pour l'anne.
Ensuite, pour utiliser cette variable struct, et les
Exemples:
Nom de la structure
struct Etudiant { char nom[41]; long CNE; long CIN; int grp; float note_TP; float note_CC; float note_CT; int Numero_Poste; };
lments de la structure
2-
struct complex { double reel; /* partie reelle */ double imag; /* partie imaginaire */ }; Les lignes suivantes initialisent un complexe la valeur (2 + 3i): struct complex a;
a.reel = 2; a.imag = 3;
Exemple
struct point { double x ; double y ; }; point p1 = {2, 1}, p2 = {8, 5} ;
y 5 4 3 2 1 0
p2
p1
0 1 2 3 4 5 6 7 8 9
/* Voici un petit programme qui calcule le milieu de 2 points: */ struct Point { double x,y; }; int main() { Point A,B,C; A.x = 3.2; A.y = 6.4;
printf("Tapez l'abscisse de b : "); scanf("%lf", &B.x); printf("Tapez l'ordonne de b : "); scanf("%lf", &B.y); C.x = (B.x + A.x) / 2; C.y = (B.y + A.y) / 2; printf("Abscisse de c : %lf \n", C.x); printf("Ordonne de c : %lf\n", C.y); return 0; }
Tableaux de structures
Une dclaration de tableau de structures se fait selon le
mme modle que la dclaration d'un tableau dont les lments sont de type simple. Supposons que l'on ait dj dclar la struct Etudiant, si on veut dclarer un tableau de 100 structures de ce type, on crira : struct Etdiant t[100]; Pour rfrencer le nom de la personne qui a l'index i dans t on crira : t[i].nom.
Supposons que l'on ait fait la dclaration suivante : struct date { int jour,mois,annee; }; une fonction de comparaison de deux dates pourra s'crire : enum {AVANT, EGAL, APRES}; int cmp_date( struct date d1, struct date d2) { if (d1.annee > d2.annee) return(APRES); if (d1.annee < d2.annee) return(AVANT); ... /* comparaison portant sur mois et jour */ } et une utilisation de cette fonction pourra tre : struct date d1,d2; if (cmp_date(d1,d2) == AVANT)
dune structure au bit prs si ce champ est de type entier (int ou unsigned int). Cela se fait en prcisant le nombre de bits du champ avant le ; qui suit sa dclaration.
Exemples:
struct registre
Unions
Une union dsigne un ensemble de variables de types
diffrents susceptibles doccuper alternativement une mme zone mmoire., et de nutiliser que la taille du plus grand de tous ces lments. Une union est constitue de champs, qui peuvent tre de type lmentaire ou dfini par lutilisateur, y compris structure ou union Lorsque lon dfinit une variable correspondant un type union, le compilateur rserve lespace mmoire ncessaire pour stocker le plus grand des champs appartenant lunion.
Exemple:
- union Exemple { int entier; double flottant; char *s_chaine; } u; Ainsi, la variable u pourra contenir soit un int, soit un double, soit un pointeur sur char. La taille de u sera celle du plus grand de ses champs, et le compilateur fait ce qu'il faut pour que l'alignement soit compatible avec tous les types de l'union.
u.entier = 32;
printf("La valeur de u est %d\n", u.entier); u.flottant = 3.1415; printf("La valeur de u est %ld\n", u.flottant); u.s_chaine = "salut ami"; printf("La valeur de u est %s\n", u.s_chaine);
Exemple
enum typeDrapeau {ENTIER, REEL, CAR} ; typedef enum typeDrapeau TypeDrapeau ; union contenu { int val_entier ; float val_reel ; char val_car ; }; typedef union contenu Contenu ; struct element { TypeDrapeau drapeau ; Contenu val ; }; typedef struct element Element ;
Exemple
Ou :
void afficher_element (Element x) { switch (x.drapeau) { case ENTIER: printf("Valeur = %d\n", x.val.val_entier) ; break; case REEL: printf("Valeur = %g\n", x.val.val_reel) ; break; case CAR: printf("Valeur = %c\n", x.val.val_car) ; break; default: printf("Donne inconnue !\n"); } }
void afficher_element (Element x) { if (x.drapeau == ENTIER) printf("Valeur = %d\n", x.val.val_entier) ; else if (x.drapeau == REEL) printf("Valeur = %g\n", x.val.val_reel) ; else if (x.drapeau == CAR) printf("Valeur = %c\n", x.val.val_car) ; else printf("Donne inconnue !\n"); }
Exemple
enum typeDrapeau {ENTIER, REEL, CAR} ; typedef enum typeDrapeau TypeDrapeau ; union contenu { int val_entier ; float val_reel ; char val_car ; }; typedef union contenu Contenu ; struct element { TypeDrapeau drapeau ; Contenu val ; }; typedef struct element Element ;
RAM (Random Access Memory): 32 / 64 Mo Le disque dur: quelques Go La mmoire virtuelle: temps daccs 1000 fois plus
long.
Mmoire et excution
Code Donnes statiques Pile
Tas
int* a;
a
int* a = NULL;
malloc(3*sizeof(int));
a = NULL;
Dsallocation dynamique
a = (int*)realloc(4*sizeof(int));
Programme ??
bin a.out .exe
Excutable(s)
.so .lib
lib
Programme include
.o
.dll
But du Jeu
Problmes a rsoudre
Complexit, Cot de maintenance
taille
temps
Organisation et rutilisation
Organisation du code : En fonctions, structures, etc. En fichiers
Rutilisation
Programmes et librairies
En C : Excutable main()
Pour la rutilisation, on utilise des bibliothques (ou librairies) de fonctions : dune description de chaque fonction (dans des fichier .h den-tte, ou header), et du code compil correspondant (des .lib et .dll sous PC, des .so et .a sous UNIX)
La Compilation : Rsum
Fichiers den-tte C
.h Prprocesseur
Code source C
.c
Code pr-process
Compilateur
Librairies
.lib .so
Fichier(s) Objet
.o
Editeur de liens
excutable
a.out .exe
Introduction
Problme mtaphysique: Comment Organiser au Mieux lInformation dans un Programme ?
Tableaux int tab[10]; Structures struct Data_t { int index_; char* value_; } Data_t;
Structures de donnes
Les tableaux
Accs index (de 0 n-1 pour un tableau de n lments) Stockage compact Taille fixe, en gnral Rajustement de taille coteux en temps Insertion dlment onreuse en temps.
Tte
Noeud
Tte
Node_t
p_data p_next
List_t
Data_t
But du programme: construire et trier une liste dentiers par ordre croissant.
void push(Data_t*)
Data_t* pop(void)
Introduction la complexit
Annuaire avec noms et coordonnes
temps t t = a 2N t = a N2
t=aN
t = a logN
nombre dabonns N
Accs rapide
Tables : Associent une cl a un lment dans le conteneur.
F1
B4
B8
B5
B9 B10
B6
F3
F2
F4
B7
F5
F6
F7
F8
F9
F10
Arbres: Spcifications
Crer un arbre Parcours pre-order Parcours post-order Parcours in-order Ajout / retrait dun noeud Dtruire un arbre
Data_t
Tree.h
typedef struct TreeNode_t { struct TreeNode_t* p_parent_; struct TreeNode_t* p_first_child_; Data_t* p_data_; struct TreeNode_t* p_next_; } TreeNode_t;
Tree.h
TreeNode_t* tree_find_root( TreeNode_t* p_parent, Data_t* p_data );
Tree.h
void tree_inorder( TreeNode_t* p_root, void(* do_it)( Data_t* ) ); TreeNode_t* tree_delete_branch( TreeNode_t* branch );
N3 N9 N14 N18
Tableau entre Pour i de 1 n Faire: int j <- min_index(entree,i) Si j i Faire swap(entree[i],entree[j]) FinSi FinPour
Besoins
swap, comp
Tableau tab Booleen permute <- vrai int i <- 0 Tant que permute Faire permute = faux Pour j de n-1 i + 1 Faire Si tab[j-1] > tab[j] Faire swap( tab[j-1], tab[j] ) permute = vrai FinSi FinPour i++ Finttque
que Tri par slection 4 On spare le tableau en p ensembles. On cherche un minimum pour chaque sousensemble On prend le minimum de ces minima. On change cet lment avec le premier lment etc.
tri sous-table 1
... sous-table p
314632957182 312632957184 312132957684 212133957684 212133957684 11223 3957684 11223 457689 45768 9 45768 5768 678
Conclusion
References
Web Aho et al. Structures de donnees et algorithmes, Addisson-Wesley / InterEditions. 1989. Aho et Ullman. Concepts fondamentaux de linformatique, Dunod. 1993. Sedgewick. Algorithmes en C. AddissonWesley / InterEditions. 1991.
short carre( short v ) { return a * a; } void imprimer( int nb_elems, short (* function )( short ) ) { for( i = 0; i < nb_elems; ++i ) { printf( %d , (* function) ( tab[i] ) ); } }
int main() { for( i = 0; i < 10; i++ ) { tab[i] = n; } imprimer( 10, carre ); }