Documente Academic
Documente Profesional
Documente Cultură
Cadi Ayyad
Ecole Nationale des Sciences Appliquées
-Safi-
Algorithmique
&
langage C
AH ME D BE NTAJ ER
A . B E N T A J E R @ G M A I L .C O M
1 ER A NNÉ E CY CL E I NG É NI EUR
G. INF.
GTR
2 0 1 3 / 2 01 4
Plan du cours
Introduction
Compilation Assemblage
Ch1 : Env. et les Bibl. Les bibl. de fonctions
Bibl. de fonctions disponibles dans leur form
précompilé (.LIB)
Inclure des fichiers en-tête (Header files - .H) qui contiennent des prototypes
des fonctions définies dans les bibliothèques & créent un lien entre les fcts
précompilées et les programmes
à .C fichiers source
Stdio.lib Compiler
HELLO_WORLD en C
Int main()
/* Notre premier programme en C */ Commentaire
{
printf("hello, world\n"); Instructions
return 0;
}
Fonction
Ch2 : Notions de bases Les fonctions
// ceci est un commentaire qui ne peut s’étaler que sur une ligne
Contradiction de Shryer
Si le code et les commentaires se contredisent, les deux sont probablement faux.
Ch2 : Notions de bases Conventions d’écritures
d’un programme en C
aérer les lignes de programme en entourant par exemple les opérateurs avec
des espaces
bien commenter les listings
Ch2 : Notions de bases Discussion du
programme Hello World
Ch2 : Notions de bases Exercice
Les identificateurs
Hello World
Modifiez le programme 'hello world' de façon à obtenir le résultat suivant :
Ch2 : Notions de bases Exercice
Ci-dessous, un simple programme en C. Distinguer et de classifier les
éléments qui composent ce programme (commentaires, variables,
déclarations, instructions, etc.)
while (COMPTEUR < 4) {
/* Lire la valeur du nombre suivant */
#include <stdio.h>
/* printf("Entrez un nombre entier :");
Ce programme calcule la somme de 4 scanf("%i", &NOMBRE);
nombres entiers
introduits au clavier. /* Ajouter le nombre au résultat */
*/ SOMME += NOMBRE;
main()
{ /* Incrémenter le compteur */
int NOMBRE, SOMME, COMPTEUR; COMPTEUR++;
b1 …………………………. bn
1 Octet = 8 bits
Les types de base du langage C se répartissent en trois grandes catégories en
fonction de la nature des informations qu'ils permettent de représenter:
En toute rigueur, chacun des trois types (short, int et long) peut être nuancé par
l’utilisation du qualificatif unsigned (non signé). Dans ce cas, il n’y a plus de
bit réservé au signe et on ne représente plus que des nombres positifs.
Les types flottants permettent de représenter une partie des nombres réels
5 / 2 = 2
float Nb Octet : 4
double
Nb Octet : 8
Long double
Nb Octet : 10
Langage algorithmique En C
Arithmétique Logique
+ Addition && ET logique (AND)
- Soustraction || OU logique (OR)
/ Division ! Négation logique (NOT)
* Multiplication
% Reste de la division
Résultat du type int :
1 : correspond à la valeur
booléan TRUE.
Comparaison
== Égal à ( a == b) 0 : correspond à la valeur
booléan FALSE
!= Différent de (a != b)
<, <=, >, >= Strict inférieur, inférieur ou égal,…
Ch3 : Type de base, Opérateurs & expr. Les opérateurs
affection
+= a+=3 (a = a + 3) Comparaison
Soit N = 5 X = 5 et N = 6
X = N++
X= ++N X = 6 et N = 6
Ch3 : Type de base, Opérateurs & expr. La bibliothèque
math.h
#include <math.h>
COMMANDE
EXPLICATION
C
Operateur de conversation
(type) objet
int i = 3, j = 2;
printf("%f \n",(float)i/j);
Ch3 : Type de base, Opérateurs & expr. Operateur adresse
& objet
Operateur de conversation
(type) objet
int i = 3, j = 2;
printf("%f \n",(float)i/j);
Ch4 : Lire et écrire des données Intro
%s Chaine de caractère
Ch4 : Lire et écrire des données Putchar()
… …
char x; char x;
x = ‘a’; x = ‘a’;
putchar(x); printf(‘’%c’’, x);
… …
Ch4 : Lire et écrire des données scanf()
La fonction scanf() est la fonction symétrique de printf()
Langage algorithmique
lire <NomVariable1>,<NomVariable2>, ...
En C
scanf("<format>",<AdrVar1>,<AdrVar2>, ...)
L’@ ou va être stocké la valeur
Exemple :
int jour, mois, annee;
Détermine comment les données Printf(‘’Saisir votre jour de naissance : \n’’);
Seront interprétées scanf(‘’ %d’’, &jour);
Exemple :
int jour, mois, annee; Printf(‘’Saisir votre mois de naissance : \n’’);
Printf(‘’Saisir votre datede scanf(‘’ %d’’, &mois);
naissance : \n’’);
scanf(‘’ %d %d %d’’, &jour, Printf(‘’Saisir votre anneede naissance : \n’’);
&mois, $annee); scanf(‘’ %d’’, &annee);
Ch4 : Lire et écrire des données scanf()
SYMBOLE LECTURE D'UN(E)
%d ou %i entier relatif
%c caractère
%s chaîne de caractères
… …
char x; char x;
x = getchar(); x = scanf(‘’%c’’, &x);
putchar(x); putchar(‘’%c’’, x);
… …
Ch4 : Lire et écrire des données Exercice
Quelles seront les valeurs lues dans les variables net p(de type int), par
l’instruction suivante ?
scanf ("%4d %2d", &n, &p) ;
lorsqu’on lui fournit les données suivantes (le symbole ^ représente un espace
et le symbole @ représente une fin de ligne, c’est-à-dire une validation) ?
a) 12^45@
b) 123456@
c) 123456^7@
d) 1^458@
e) ^^^4567^^8912@
4.4 - Ecrire un programme qui permute et affiche les valeurs de trois variables
A, B, C de type entier qui sont entrées au clavier :
A ==> B , B ==> C , C ==> A
#include <stdio.h>
main() {
int A,B;
Char sexe = ‘m’
printf("Entrez deux nombres entiers :");
if (sexe == ‘m’) { scanf("%i %i", &A, &B);
printf(‘vous êtes un homme’’);
} if (A > B)
printf("%i est plus grand que %i\n", A, B);
If (sexe != ‘m’)
{ else if (A < B)
printf(‘vous êtes une femme’’); printf("%i est plus petit que %i\n", A, B);
}
else printf(‘’%i est egal a %i’’,A,B);
Else {
printf(‘euuuuh, J!!’’); return 0; }
}
Ch5 : La structure alternative Exercice
5.3 - Ecrivez un programme qui lit trois valeurs entières (A, B et C) au clavier
et qui affiche la plus grande des trois valeurs, en utilisant:
a) if - else et une variable d'aide MAX
b) if - else if - ... - else sans variable d'aide
SWITCH
Un booléan est une variable peut avoir deux état 1 (TRUE) ou 0 (FALSE)
Instruction
Instruction
Instruction
Instruction
Instruction
Ch5 : La structure répétitive While
Int nombre = 0;
While (nombre != 12) {
printf(‘’veuillez saisir 12 pour sortir de la boucle’’);
nombre = scanf(‘’%d’’,&nombre);
}
Ch5 : La structure répétitive Exemple
fflush(stdin);
Ch5 : La structure répétitive do .. while
do {
<bloc d'instructions>
}
while (<expression logique>)
#include <stdio.h>
#include <math.h>
main()
{
float N;
do {
printf("Entrer un nombre (>= 0) : ");
scanf("%f", &N);
}
while (N < 0);
printf("La racine carrée de %.2f est %.2f\n", N, sqrt(N));
return 0;
} Tester le même exemple avec int compteur = 0
Ch5 : La structure répétitive For
For ( <expr1> ; <expr2>; <expr3> )
{
<instruction>
}
<expr1> : est évaluée une fois avant le passage de la boucle. Elle est utilisée pour
initialiser les données de la boucle.
<expr2> : est évaluée avant chaque passage de la boucle. Elle est utilisée pour
décider si la condition de sortie de la boucle a été atteinte
<expr3> : st évaluée à la fin de chaque passage de la boucle. Elle est utilisée pour
réinitialiser les données de la boucle.
for (int i = 0; i<10; i++) { Int i ;
printf(‘’valeur de i : %d’’, i); i = 0;
} for ( ; i<10; i++) {
printf(‘’valeur de i : %d’’, i);
Int i ; }
i = 0;
for ( ; i<10; ) {
printf(‘’valeur de i : %d’’, i);
i++;
}
Ch5 : La structure répétitive Choix de la structure !!?
Si le bloc d'instructions doit être exécuté au moins une fois, alors utilisez do -
while
@ Valeur
1000 2
N
data data …. data data data
Déclaration : 2 * 12 = 24 Octet
Type Nom_Tableau [ TAILLE ] Utilisation de l’opérande sizeof()
Exemple :
61
3
56
70
1 6 …. 70 56 3
Ch5 : Les Tableaux Les tableaux à deux
dimensions
Un tableau à deux dimensions est interprété comme un tableau
unidemensionnel de dimension L dont chaque composante est un tableau
(uni-dimensionnel) de dimension C.
L : Nombre de ligne
L*C composantes
C : Nombre de colonne
C
Ch5 : Les Tableaux Les tableaux à deux
dimensions
Considérons un tableau NOTES à une dimension pour mémoriser les
notes de 10 étudiants dans un devoir
12 15 10 9 19 17 5 8 9 14
12 15 10 9 19 17 5 8 9 14
10 5 9 12 7 8 15 16 9 14
18 20 16 18 15 10 8 8 9 15
Ch5 : Les Tableaux Les tableaux à deux
dimensions
<Type> <NomTabl>[<DimLigne>][<DimCol>];
int A[10][10];
float B[2][20];
int C[3][3];
char D[15][40];
Mémorisation
Comme pour les tableaux à une dimension, le nom d'un tableau est le
représentant de l'adresse du premier élément du tableau (c.-à-d. l'adresse de la
première ligne du tableau).
short A[3][2] = {{1, 2 }, {10, 20 }, {100, 200}};
Ch5 : Les Tableaux Les tableaux à deux
dimensions
Initialisation et réservation automatique
1 0 0 0
1 1 0 0
1 1 1 0
1 1 1 1
char email[20];
Lors de la déclaration , on doit indiquer l’espace a réserver en mémoire pour le
stockage de la chaîne
Une chaine de char ne contient pas que des lettres, une chaine de char doit
impérativement contenir un char spécial \0 qui marque la fin de la chaine
b o n j o u r \0
La fonction strlen
La fonction strlen fournit en résultat la longueur de la chaine (nombre de char
trouvé depuis le début de la chaine jusqu’au premier char de fin de chaine le \0)
Ex :
int taille = strlen(‘’bonjour’’); //taille vaudra 7
Ou bien
Char txt[] = ‘’bonjour’’;
int taille = strlen(txt);
Ch8 : Les chaînes de caractères Travailler sur les char
Fonction de concaténation
#include <stdio.h>
strcat
#include <string.h>
main() Strcat, prend deux arguments arg1 et
{ arg2, et concatène la valeur de arg2
char ch1[50] = "bonjour" ; avec arg1
char ch2[50] = " monsieur" ;
printf ("avant : %s\n", ch1) ;
strcat (ch1, ch2) ;
printf ("après : %s", ch1) ;
}
#include <stdio.h>
strncat
#include <string.h>
main() Strncat(arg1,arg2,lgmax), prend 3
{ arguments arg1 et arg2 et lgmax offrant
char ch1[50] = "bonjour" ; en outre un contrôle sur le nombre de
char ch2[50] = " monsieur" ; caractères qui seront concaténés à la
printf ("avant : %s\n", ch1) ; chaîne d’arrivée (arg1)
strncat (ch1, ch2, 6) ;
printf ("après : %s", ch1) ;
}
Ch8 : Les chaînes de caractères Travailler sur les char
Fonction de comparaison
#include <stdio.h>
strcmp
#include <string.h> Strcmp, compare tous les caractères
main() s’ils sont identiques, elle renvoie 0. Si
{ les caractères de la ch1 sont supérieurs
char ch1[50] = "bonjour" ; à ceux de la ch2, la fonction renvoie
char ch2[50] = " monsieur" ; un nombre positif. Si c'est l'inverse, la
Int n = strcmp (ch1, ch2) ; fonction renvoie un nombre négatif.
}
#include <stdio.h>
strncmp stricmp ( chaîne1, chaîne2 )
#include <string.h>
strnicmp ( chaîne1, chaîne2, longeur )
main()
{
char ch1[50] = "bonjour" ;
char ch2[50] = " bon" ;
strncat (ch1, ch2, 2) ;
}
Ch8 : Les chaînes de caractères Travailler sur les char
Fonction de copie
#include <stdio.h>
strcpy
#include <string.h> Strcpy, copy le contenu de le chaine
main() ch2 dans ch1, ATTENTION à la
{ dimension de ch1
char ch1[50] = "bonjour" ;
char ch2[50] = " monsieur" ;
strcpy (ch1, ch2) ;
Printf(‘’%s’’,ch1);
}
#include <stdio.h>
strncpy limite la recopie au nombre de
#include <string.h>
caractères précisés par l’expression
main()
entière longeur (dans notre cas c’est 2)
{
char ch1[50] = "bonjour" ;
char ch2[50] = " monsieur" ;
strncat (ch1, ch2, 2) ;
}
Ch8 : Les chaînes de caractères Travailler sur les char
Fonction de recherche dans un chaine
strchr ( chaîne, caractère )
Char jour[7][10]
7
Chaînes
de
caractères
int I = 2;
printf("Aujourd'hui, c'est %s !\n", JOUR[I]);
Sol :
Utilisez la fonction strcpy à strcpy(JOUR[I], ‘’votre chaine’’);
Ch9 : Les pointeurs Introduction
Le nom d’une variable, permet d’accéder directement à la valeur de cette
variable
Int N; 5 ……………………
N=5
10E3 40A5
40A5 ….. 5
P N
Ch9 : Les pointeurs Les pointeurs
Un pointeur est une variable spéciale qui peut contenir l'adresse d'une autre
variable.
Lors du travail avec les pointeurs on aura besoin de :
• D’un opérateur ‘’adresse de : &’’; pour obtenir l’@ d’une variable
• D’un opérateur ‘’ contenu de * ‘’; pour accéder au contenue de l’@
• D’une syntaxe de déclaration pour pouvoir déclarer le pointeur
Exmple 1 : Exmple 2 :
Int n = 5; Int n = 5;
Printf (‘’ N vaut : %d’’, n) Printf (‘’ L’@ de N vaut : %d’’, &n)
P @
P @ P = &A;
B = *P;
P = &A A 20
5 *P = 20;
• P pointe sur A,
A 5
• le contenu de A (référencé par *P)
B 50
5
est affecté à B
• le contenu de A (référencé par *P)
est mis à 20.
Ch9 : Les pointeurs Les opérations élémentaires sur
pointeurs
Si un pointeur P pointe vers une variable A, alors *P désigne le contenue de la
case vers laquelle le pointeur P pointe (càd le contenue de A)
Si on a P = &X
Ch9 : Les pointeurs Excercice
A
B C P1 P2
Init. 1 2 3 / /
main() { A B C P1 P2
int A = 1; int B = 2; int C = 3; Init. 1 2 3 / /
P1=&A 1 2 3 &A /
int *P1, *P2;
P1=&A 1 2 3 &A /
P1=&A; P2=&C 1 2 3 &A &C
P2=&C; P2=&C
A=++*P2**P1; ++*P2
*P1-=*P2 3 2 2 &C &B
P1=&A;
*P2=*P1/=*P2; *P1*=*P2++*P2 3 3 2 &C &B
return 0; } A=++*P2**P1
*P1*=*P2 3 3 6 &C &B
P1=&A
Nous avons déjà utilisé des fonctions prédéfinies dans des bibliothèques
standard (printf de <stdio>, strlen de <string>, pow de <math>, etc.)
Pourquoi ?
Meilleurs lisibilité – Diminution des risques d’erreurs - possibilité de tests
sélectifs – Réutilisation – Simplicité d’entretien - …
Exemple :
Supposant qu’on veut réaliser un
programme qui affiche un rectangle
d’étoile de longueur L et hauteur H.
Ch10 : Les fonctions Les fonctions
Variable globale
Les variables déclarées au début de la fonction principale main
ne sont pas des variables globales, mais elles sont locales à main !
Ecrire une fonction MIN et une fonction MAX qui déterminent le minimum
et le maximum de deux nombres réels.
Ecrire un programme se servant des fonctions MIN et MAX pour déterminer
le minimum et le maximum de quatre nombres réels entrés au clavier.
introduction
Ch11 : Les fichiers
Un fichier est un ensemble structuré de données stocké en général sur un
support externe
Fichier Séquentiel
Dans des fichiers séquentiels, les enregistrements sont mémorisés
consécutivement dans l'ordre de leur entrée et peuvent seulement être lus
dans cet ordre
Comment pouvons-nous relier le nom d'un fichier sur un support externe avec les
1 - On appelleinstructions
la fonction d'ouverture
qui donnent de fichier
accès fopen qui
au contenu nous renvoie
du fichier ? un
pointeur sur le fichier.
4 -Une fois qu'on a terminé de travailler sur le fichier, il faut le fermer avec la
fonction fclose.
Le Type FILE*
Ch11 : Les fichiers
Pour pouvoir travailler avec un fichier, un programme a besoin d'un certain
nombre d'informations :
- adresse de la mémoire tampon,
- position actuelle de la tête de lecture/écriture,
- type d'accès au fichier: écriture, lecture, ...
- ….
Ces informations sont regroupées dans FILE
"a" : mode d'ajout. Vous écrirez dans le fichier. Si le fichier n'existe pas, il sera
créé.
"a+" : ajout en lecture / écriture à la fin. Vous écrivez et lisez du texte à partir de
la fin du fichier. Si le fichier n'existe pas, il sera créé.
Si un fichier existant est ouvert en écriture, alors son contenu est perdu.
Le Type FILE*
Ch11 : Les fichiers
Tester l’ouverture d’un fichier
if (fichier != NULL)
{
// On peut lire et écrire dans le fichier
}
else
{
// On affiche un message d'erreur
printf("Impossible d'ouvrir le fichier test.txt");
}
Le Type FILE*
Ch11 : Les fichiers
Tester l’ouverture d’un fichier
Le pointeur File_pointer devrait contenir l'adresse de la structure de
type FILE qui sert de descripteur de fichier. Celui-ci a été chargé en mémoire
par la fonction fopen().
FILE* fichier = NULL;
if (fichier != NULL)
{
}
else
{
// On affiche un message d'erreur
printf("Impossible d'ouvrir le fichier test.txt");
}
Tester la fermeture d’un fichier
0 : Si la fermeture a marché
int fclose(FILE* pointeurSurFichier);
EOF : Si la fermeture a échoué
Lire & Ecrire dans les
Ch11 : Les fichiers fichiers séquentiels
Ecrire dans un fichier
Nous pouvons utiliser quasiment les mêmes fonctions que pour l'écriture, le
nom change juste un petit peu :
• fgetc : lit un caractère ;
• fgets : lit une chaîne ;
• fscanf : lit une chaîne formatée.
Chaque fois que vous ouvrez un fichier, il existe en effet un curseur qui
indique votre position dans le fichier
ftell :
Cette fonction est très simple à utiliser. Elle renvoie la position actuelle du
curseur sous la forme d'un long, le nombre renvoyé indique donc la
position du curseur dans le fichier.
Se déplacer dans un
Ch11 : Les fichiers fichier
fseek :
Tout d'abord il faut savoir qu'il est préférable de créer une structure en dehors
d'une fonction car l'avantage des structures c'est qu'elles permettent un accès à
leurs attributs (= sous-variables qu'elles contiennent) qui s'étend sur toutes les
fonctions du programme.
Ainsi si vous créez une structure dans une fonction, seule celle-ci y'aura accès.
Ch12 : Les types avancées Structure
struct personne
{
char nom[20];
char prenom[20]; struct personne p = {« Bentajer", « Ahmed", 1234};
int no_employe;
} p1,p2;
Ch12 : Les types avancées Structure
Aucune comparaison n'est possible sur les structures, même pas les
operateurs == et !=.
Ch12 : Les types avancées Structure
Tableaux de structures
T[i].nom
Ch12 : Les types avancées Structure
P = &p1
Mais il faut savoir que les operateurs d’indirection (*) et de sélection (.) ont
eux aussi un ordre de priorité. (l’indirection a une priorité inferieur a celle
de la sélection)
struct date
{
int jour,mois,annee;
};
algorithme LIFO,
EMPILER DEPILER
1
Ch13 : Les Piles et Files Piles
Implémentation :
Traitement
Fonction PileVide(P){
if P[sommet] = 0;
return true;
else
return false;
}
algorithme FIFO,
EMFILER DEFILER
1
Ch13 : Les Piles et Files Files
Implémentation :
Les FILEs correspondent aux Files d’attente : 1er arrive 1er servi
Ch13 : Les Piles et Files Piles