Académique Documents
Professionnel Documents
Culture Documents
Un peu dhistoire
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 sur un DEC PDP-11. En 1978, Brian Kernighan et Dennis Richie publient la dfinition classique du C dans le livre The C Programming language [6]. Le C devenant de plus en plus populaire dans les annes 80, plusieurs groupes mirent sur le march des compilateurs comportant des extensions particulires. En 1983, l'ANSI (American National Standards Institute) dcida de normaliser le langage ; ce travail s'acheva en 1989 par la dfinition de la norme ANSI C. Celle-ci fut reprise telle quelle par l'ISO (International Standards Organization) en 1990.
Les dangers de C
C est un langage prs de la machine, donc dangereux et bien que C soit un langage de programmation structur, il ne nous force pas adopter un certain style de programmation (comme p.ex. Pascal). Dans un certain sens, tout est permis mme la commande goto , si redoute par les puristes ne manque pas en C. Le programmeur a donc beaucoup de liberts, mais aussi des responsabilits: il doit veiller lui-mme adopter un style de programmation propre, solide et comprhensible.
Facult dlectronique & dinformatique Module ALGO L2-ACAD (S3) { <dclarations> <instructions> } b) Les identificateurs
Les identificateurs sont les noms propres du programme. Les noms des fonctions et des variables en C sont composs d'une suite de lettres et de chiffres. Le premier caractre doit tre une lettre. Le symbole '_' est aussi considr comme une lettre. * L'ensemble des symboles utilisables est donc: {0,1,2,...,9,A,B,...,Z,_,a,b,...,z} * Le premier caractre doit tre une lettre (ou le symbole '_') * C distingue les majuscules et les minuscules, ainsi: NOM est diffrent de nom * La longueur des identificateurs n'est pas limite, mais C distingue seulement les 31 premiers caractres. * Les mots cls du C doivent tre crits en minuscules c) Les commentaires Un commentaire commence toujours par les deux symboles '/*' et se termine par les symboles '*/'. Il est interdit d'utiliser des commentaires imbriqus. Exemples :
/* Ceci est un commentaire correct */ /* Ceci est /* videmment */ dfendu */
d) Utilisation des bibliothques de fonctions Pour pouvoir les utiliser, il faut inclure des fichiers en-tte (header files - extension .H) dans nos programmes. L'instruction #include insre les fichiers en-tte indiqus comme arguments dans le texte du programme au moment de la compilation.
Exemple : 4
Nous avons crit un programme qui fait appel des fonctions mathmatiques prdfinies. Nous devons donc inclure le fichier en-tte correspondant dans le code source de notre programme l'aide de linstruction: #include <math.h>
entier standard -2147483648 2147483647 entier long -2147483648 2147483647 0 65535 65535 4294967295
entier standard 0 0
sizeof(short)<=sizeof(int)<=sizeof(long) Dans certaines machines on a short 2 int 2 long4 dans dautres on a short 2 int 4 long4 b) Les rels En C, nous avons le choix entre deux types de rels: float, double
dfinition prcision mantisse float double simple double 6 15 domaine min domaine max 3.4 * 10-38 1.7 * 10-308 3.4 * 1038 1.7 * 10308 nombre d'octets 4 8
La mantisse : Les chiffres significatifs du rel sans la virgule Exemple : 123.4 ou 1234e -1 mantisse1234 c) Les caractres Le type char (provenant de langlais character) permet de stocker la valeur ASCII dun caractre, c'est--dire un nombre entier !
Par dfaut les nombres sont signs, cela signifie quils comportent un signe. Pour stocker linformation concernant le signe (en binaire), les ordinateurs utilisent le 5
complment deux . Une donne de type char est donc signe, cela signifie bien sr pas que la lettre possde un signe mais tout simplement que dans la mmoire la valeur codant le caractre peut tre ngative.
dfinition char unsigned char description Caractre Caractre domaine min domaine max nombre d'octets -128 0 127 255 1 1
d) La dfinition des constantes : Une constante est un objet auquel on attribue une valeur la dclaration et que lon ne peut pas changer tout au long du programme. On dfini des constantes en utilisant la directive define ou le mot cl const. Syntaxe : #define <idf> valeur ou bien Exemple : ... e) La dclaration des variables : <Type> <NomVar1>, <NomVar2>,..., <NomVarN>; Exemples : int compteur,X,Y; float hauteur,largeur; double M; char C; f) Initialisation des variables En C, il est possible d'initialiser les variables lors de leur dclaration: int MAX = 1023; float X = 1.05; Remarque : En C il n'existe pas de type spcial pour les variables boolennes. Si l'utilisation d'une variable boolenne est indispensable, on utilisera une variable du type int. Les oprations logiques en C retournent toujours des rsultats du type int : 0 pour faux et 1 pour vrai g) Convertions de type automatique 6 #define max 100 ou bien const <idf> = valeur
const max=100
En gnral on converti des types plus petits en des types plus larges de cette faon on ne perd pas en prcision. Lors de laffectation, la donne droite du signe dgalit est convertie dans le type gauche du signe dgalit. Dans ce cas il peut y avoir une perte de prcision si le type de la destination est plus faible que celui de la source. Exemple : int i=8 ; float x=12.5 ; double y ; y=i*x;i est converti en float i*x est converti en double affecter le rsultat y
1.3
Exemples ; int A[25] ; long B[25] ; float F[100] ; double D[100] ; char ch[30] ; b. Initialisation : 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};
Remarque : Il faut videmment veiller ce que le nombre de valeurs dans la liste corresponde la dimension du tableau. Si la liste ne contient pas assez de valeurs pour toutes les composantes, les composantes restantes sont initialises par zro.
Exemples :
Si la dimension n'est pas indique explicitement lors de l'initialisation, alors l'ordinateur rserve automatiquement le nombre d'octets ncessaires. Exemple : int A[ ] = {10, 20, 30, 40, 50}; ==> Rservation de 5*taille dun entier (Si un entier occupe 2 octets donc pour ce tableau seront rservs10 octets) c. Accs aux composantes En dclarant un tableau par: int A[5]; Nous avons dfini un tableau A avec 5 A[0], A[1], ... , A[4] composantes, auxquelles on peut accder par: 1.3.2 Les tableaux deux dimensions a. Dclaration : <TypeSimple> <NomTabl> [<DimLigne>] [<DimCol>] ; Exemples : int A[10][10] ; long B[10][10] ; float F[10][10] ; double D[10][10] ; char ch[15][30] ; b. Mmorisation :
Les composantes d'un tableau deux dimensions sont stockes ligne par ligne dans la mmoire.
Facult dlectronique & dinformatique Module ALGO L2-ACAD (S3) c. Initialisation : 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} }; d. Accs aux composantes : <NomTableau> [<Ligne>] [<Colonne>] ; En dclarant un tableau par: int M[5][3]; Nous avons dfini un tableau (matrice) M avec 5 lignes et chaque ligne contient 3 composantes, auxquelles on peut accder par: M[0][0], M[0][1], ... , M[4][0],,M[4][2]
a.
Exemples : char NOM [20]; char PRENOM [20]; char PHRASE [300]; Remarque : Lors de la dclaration, nous devons indiquer l'espace rserver en mmoire pour le stockage de la chane. La reprsentation interne d'une chane de caractres est termine par le symbole '\0' (NUL). Ainsi, pour un texte de n caractres, nous devons prvoir n+1 octets. b. Les chanes de caractres constantes Les chanes de caractres constantes sont indiques entre guillemets. La chane de caractres vide est alors: "" "x" est un tableau de caractres qui contient deux caractres: la lettre 'x' et le caractre NUL: '\0' est cod dans deux octets 'x' est un caractre et est cod dans un octet
1.3.4 Tableaux de chanes de caractres Un tableau de chanes de caractres correspond un tableau deux dimensions du type char, o chaque ligne contient une chane de caractres. a. Dclaration : La dclaration char JOUR[7][9]; Rserve l'espace en mmoire pour 7 mots contenant 9 caractres (dont 8 caractres significatifs). b. Initialisation : char JOUR[7][9] = {"dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"}; c. Accs aux chanes : Il est possible d'accder aux diffrentes chanes de caractres d'un tableau, en indiquant simplement la ligne correspondante : JOUR[3] "mercredi" Exemple rcapitulatif : Initialisation de chane de caractre : Lesquelles des chanes suivantes sont initialises correctement ? Corrigez les dclarations fausses. a) char a[ ] = "un\ndeux\ntrois\n" ; b) char b[12] = "un deux trois" ; c) char c[] = 'abcdefg' ; d) char d[10] = 'x' ; e) char e[5] = "cinq" ; f ) char f[] = "Cette " "phrase" "est coupe"; g) char g[2] = { 'a', '\0' }; h) char h[4] = { 'a', 'b', 'c' } ;
10
Solution a) char a[] = "un\ndeux\ntrois\n"; Dclaration correcte b) char b[12] = "un deux trois"; Dclaration incorrecte, la chane d'initialisation dpasse le bloc de mmoire rserv. Correction: char b[14] = "un deux trois"; ou mieux: char b[] = "un deux trois"; c) char c[] = 'abcdefg'; Dclaration incorrecte: Les symboles ' et encadrent des caractres; Pour initialiser avec une chane de caractres, il faut utiliser les guillemets (ou indiquer une liste de caractres). Correction: char c[] = "abcdefg"; d) char d[10] = 'x'; Dclaration incorrecte: Il faut utiliser une liste de caractres ou une chane pour l'initialisation. Correction: char d[10] = {'x', '\0'} ou mieux: char d[10] = "x"; e) char e[5] = "cinq"; Dclaration correcte ; f) char f[] = "Cette ", "phrase", "est coupe"; Dclaration incorrecte ; On ne peut affecter plusieurs chanes spares ainsi. g) char g[2] = {'a', '\0'}; Dclaration correcte ; h) char h[4] = {'a', 'b', 'c'}; Dclaration incorrecte: Dans une liste de caractres, il faut aussi indiquer le symbole de fin de chane. Correction: char h[4] = {'a', 'b', 'c', '\0'};
1.4
Affectation :
11
Remarque : Loprateur
sont des entiers, en effet 5/2 donne comme rsultat 2. Si lon dsire obtenir un rsultat rel, on va forcer le type en faisant se que lon appelle un cast comme suit : float(5/2) donnera comme rsultat 2.5. Et bien sur si lun des deux oprandes est un rel (ou les deux) le rsultat sera un rel (5.0/2 2.5). Oprateurs d'affectation
+= -= *= /= %= X = i++ X = i-X = ++i X = --i ajouter diminuer de multiplier par diviser par modulo passe d'abord la valeur de i X et incrmente aprs passe d'abord la valeur de i X et dcrmente aprs incrmente d'abord et passe la valeur incrmente X dcrmente d'abord et passe la valeur dcrmente X
Pour la plupart des expressions de la forme: expr1 = (expr1) op (expr2) Il existe une formulation quivalente: expr1 op= expr2 Laffectation i = i + 2 peut scrire i + = 2
12
Facult dlectronique & dinformatique Module ALGO L2-ACAD (S3) Les priorits des oprateurs
Priorit 1 (la plus forte): Priorit 2: Priorit 3: Priorit 4: Priorit 5: Priorit 6: Priorit 7: Priorit 8: Priorit 9 (la plus faible): () ! ++ -*/% +< <= > >= == != && || = += -= *= /= %=
Exemple rcapitulatif : main() { int i, j=2 ; float x=2.5 ; i=j+x ; x=x+i ; } main() { float x=3/2 ; /* ici x=1 division entire */ x=3/2. /* ici x=1.5 resultat rel */ int a=3, b, c ; b=++a ; /* a=4 , b=4 car on a a=a+1 ; b=a */ c=b++; /* c=4, b=5 car on a c=b; b=b+1; */ int a=3, b=4; float c; c=a/b; /* c=0 division entire */ c=(float)a/b ; /* c=0.75 */ float a=3, b=4, c ; c=a/b; /* c=0.75 */ /* ici x=6.5 (et non 7) car dans i=j+x j+x a t convertie en int */
c=(int)a/b; /* c=0 */ }
13
La partie "<format>" est une chane de caractres qui peut contenir du texte, des squences d'chappement, des spcificateurs de format. Les spcificateurs de format indiquent la manire dont les valeurs des expressions sont affiches et commencent toujours par % et se terminent par un ou deux caractres. La partie "<format>" contient exactement un spcificateur de format pour chaque expression. - Spcificateurs de format pour printf %d ou %i int %u %c %l %f %e %s int int long entier relatif entier naturel (unsigned) caractre entier long
double rationnel en notation dcimale double rationnel en notation scientifique char* chane de caractres
Exemples : (1) La suite d'instructions: Va afficher sur l'cran: (2) int A = 12; int B = 5; printf("%i fois %iest %i\n", A, B, A*B); 12 fois 5 est 60 char JOUR[7][9]= {"dimanche","lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"}; int i = 4; printf("Aujourd'hui, c'est %s !\n", JOUR[i]); Affichera la phrase : Aujourdhui, c'est jeudi ! 14
Facult dlectronique & dinformatique Module ALGO L2-ACAD (S3) - Les squences d'chappement
\a \b \t \n \r \0
\\ \? \' \"
tabulateur vertical
b) scanf() :
scanf("<format>",<AdrVar1>,<AdrVar2>, ...) ;
La chane de format dtermine comment les donnes lues doivent tre interprtes. Les donnes lues correctement sont mmorises successivement aux adresses <AdrVar1>,... L'adresse d'une variable est indique par le nom de la variable prcd du signe &. Exemples : (1) int Jour, Mois, Annee; scanf("%i %i %i", &Jour, &Mois, &Annee); Lit trois entiers relatifs et les valeurs sont attribues respectivement aux trois variables Jour, Mois et Annee. (2) #inlude<stdio.h> main() { int a, b, res ; printf(" Donner 2 valeurs entires\n ") ; scanf("%d %d",&a,&b); res=a*b ; printf("%d fois %d = %d",a,b,res); } espace
15
b) if sans else if ( <expression> ) <bloc d'instructions> ; Exemple : i) if (N>0) if (A>B) MAX=A; else MAX=B; Pour N=0, A=1 et B=2, * dans la premire interprtation (i), MAX reste inchang, * dans la deuxime interprtation (ii), MAX obtiendrait la valeur de B. En C le else est toujours li au dernier if. Pour viter des confusions, il est recommand d'utiliser des accolades { }. Exemple Pour forcer la deuxime interprtation de l'expression ci-dessus, nous pouvons crire: if (N>0) { if (A>B) else MAX=B; MAX=A; } (ou bien) ii) if (N>0) if (A>B) MAX=A; else MAX=B;
16
Facult dlectronique & dinformatique Module ALGO L2-ACAD (S3) c) if - else if - ... - else if ( <expr1> ) <bloc1>; <bloc3>; <blocN>; else if (<expr2>) <bloc2>; else if (<expr3>) else if (<exprN>)
else <blocN+1> ;
Les oprateurs conditionnels : expr1> ? <expr2> : <expr3> ; * Si <expr1> fournit une valeur diffrente de zro, alors la valeur de <expr2> est le rsultat * Si <expr1> fournit la valeur zro, alors la valeur de <expr3> est le rsultat Exemple : if (A>B) MAX=A; else MAX=B; MAX = (A > B) ? A : B; Peut tre remplace par:
1.5.2.2 Linstruction switch switch (expression) { case constante-1 : <instruction-1>;break; case constante-2 : <instruction-2>;break; case constante-n : <instruction-n>;break; default: <instruction n+1>; } Remarque : break permet de sortir du switch Exemple : switch (operateur) { case + : s=a+b ; break ; case - case * case / : s=a-b; break; : s=a*b; break; : if (b!=0) s=a/b; else printf(division par zero); break; default } : printf(erreur);
17
- while:
while ( <expression> ) { <bloc d'instructions> ; }
Exemple /* Afficher les nombres de 0 9 */ int i = 0; while (i<10) { printf("%d \n", i); i++; }
- do while
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 { <bloc d'instructions>; } while ( <expression> );
18
Facult dlectronique & dinformatique Module ALGO L2-ACAD (S3) do { x=y; y=(x+A/x)/2; } while (fabs(y-x)>0.000001); printf(La racine carre de %d = %f, A, y); }
- for :
for ( <expr1> ; <expr2> ; <expr3> ) { <bloc d'instructions>; } <expr1> est value une fois avant le passage de la boucle. Elle est utilise pour initialiser les donnes de la boucle. <expr2> est value avant chaque passage de la boucle. Elle est utilise pour dcider si la boucle est rpte ou non. <expr3> est value la fin de chaque passage de la boucle. Elle est utilise pour rinitialiser les donnes de la boucle. Exemples : (1) int i; /* Calcul et affichage du carr des 20 premiers nombres */ for (i=1 ; i<=20 ; i++) printf("Le carr de %d est %d \n", i, i*i); (2) /* Affichage et Lecture des lments dun tableau une dimension */ main() { int A[5]; int i; /* Compteur */ for (i=0; i<5; i++) scanf("%d", &A[i]); for (i=0; i<5; i++) printf("%d ", A[i]); ou bien printf("%d\t", A[i]); /* tabulateur */ }
19
(3) /* Affichage des lments dun tableau deux dimensions (Matrice) */ main() { long A[10][20]; int i,j; /* Pour chaque ligne ... */ for (i=0; i<10; i++) { for (j=0; j<20; j++) /* considrer chaque composante*/ printf("%d", A[i][j]); printf("\n"); /* Retour la ligne */ } } 1.5.3 Les fonctions puts et gets Comme nous l'avons dj vu, la bibliothque <stdio> nous offre des fonctions qui effectuent l'entre et la sortie des donnes. A ct des fonctions printf et scanf que nous connaissons dj, nous y trouvons les deux fonctions puts et gets, spcialement conues pour l'criture et la lecture. puts : puts est idale pour crire une chane constante ou le contenu d'une variable . Syntaxe: puts( <Chane> ) puts crit la chane de caractres dsigne par <Chane> sur lcran et provoque un retour la ligne. puts(TXT); est quivalent printf("%s\n",TXT);
Exemples char TEXTE[ ] = "Voici une premire ligne."; puts(TEXTE); puts("Voici une deuxime ligne.");
20
gets gets est idal pour lire une ou plusieurs lignes de texte (p.ex. des phrases) termines par un retour la ligne. Syntaxe: gets( <Chane> ) gets lit une ligne de caractres chane '\0'. Exemple : int MAXI = 1000; char LIGNE[MAXI]; gets(LIGNE); Important : scanf avec le spcificateur %s permet de lire un seul mot. Exemples : char LIEU[25]; int JOUR, MOIS, ANNEE; printf("Entrez lieu et date de naissance : \n"); scanf("%s %d %d %d", LIEU, &JOUR, &MOIS, &ANNEE); Remarque : La fonction scanf a besoin des adresses de ses arguments: Les noms des variables numriques (int, char, long, float, ...) doivent tre marqus par le symbole '&', Comme le nom d'une chane de caractres est le reprsentant de l'adresse du premier caractre de la chane, il ne doit pas tre prcd de l'oprateur adresse '&' ! et la copie l'adresse indique par
21
Facult dlectronique & dinformatique Module ALGO L2-ACAD (S3) 1.5.5 Quelques bibliothques de fonctions : a. Les fonctions de <math.h>
exp(X) log(X) log10(X) fonction exponentielle logarithme naturel logarithme base 10 fabs(X) floor(X) ceil(X)
valeur absolue de X arrondir en moins arrondir en plus reste rationnel de X/Y (mme signe que X)
fmod(X,Y)
asin(X) acos(X) atan(X) arcsin(X), arccos(X), arctan(X) sinh(X) cosh(X) tanh(X) sinus, cosinus, tangente hyperboliques de X
b. Les fonctions de <string.h> Dans le tableau suivant, <n> reprsente un nombre du type int. Les symboles <s> et <t> peuvent tre remplacs par : une chane de caractres constante le nom d'une variable dclare comme tableau de char un pointeur sur char
fournit la longueur de la chane sans compter le '\0' final copie <t> vers <s> ajoute <t> la fin de <s> compare <s> et <t> lexicographiquement et fournit un rsultat: ngatif zro positif strncpy(<s>, <t>, <n>) copie au plus <n> caractres de <t> vers <s> si <s> prcde <t> si <s> = <t> si <s> suit <t>
strncat(<s>, <t>, <n>) ajoute au plus <n> caractres de <t> la fin de <s>
22
c. Les fonctions de <stdlib.h> La bibliothque <stdlib> contient des dclarations de fonctions pour la conversion de nombres en chanes de caractres et vice-versa. Conversion de chanes de caractres en nombres atoi(<s>) retourne la valeur numrique reprsente par <s> comme int atol(<s>) retourne la valeur numrique reprsente par <s> comme long atof(<s>) retourne la valeur numrique reprsente par <s> comme double (!) Rgles gnrales pour la conversion: - Les espaces au dbut d'une chane sont ignors - Il n'y a pas de contrle du domaine de la cible - La conversion s'arrte au premier caractre non convertible - Pour une chane non convertible, les fonctions retournent zro Conversion de nombres en chanes de caractres itoa (<n_int>, <s>, <b>) ltoa (<n_long>, <s>, <b>) ultoa (<n_uns_long>, <s>, <b>) d. Les fonctions de <ctypes> Les fonctions de classification suivantes fournissent un rsultat du type int diffrent de zro, si la condition respective est remplie, sinon zro. La fonction: retourne une valeur diffrente de zro, isupper(<c>) si <c> est une majuscule ('A'...'Z') islower(<c>) si <c> est une minuscule ('a'...'z') isdigit(<c>) si <c> est un chiffre dcimal ('0'...'9') isalpha(<c>) si islower(<c>) ou isupper(<c>) isalnum(<c>) si isalpha(<c>) ou isdigit(<c>) isxdigit(<c>) si <c> est un chiffre hexadcimal ('0'...'9' ou 'A'...'F' ou 'a'...'f') isspace(<c>) si <c> est un signe d'espacement (' ', '\t', '\n', '\r', '\f') Les fonctions de conversion suivantes fournissent une valeur du type int qui peut tre reprsente comme caractre; la valeur originale de <c> reste inchange:
23
tolower(<c>) retourne <c> converti en minuscule si <c> est une majuscule toupper(<c>) retourne <c> converti en majuscule si <c> est une minuscule
24