Un
programme
• Un programmeinformatique est un ensemble d'opérations destinées à être exécutées
par un ordinateur pour réaliser en général trois choses :
1. Il lit des données en entrée.
2. Il effectue des calculs.
3. Il écrit des données en sortie.
• Il existe de nombreuses approches (paradigmes) de programmation. Parmi elles:
• La programmation procédurale (ou Impérative) est basé sur le principe de l'exécution étape par
étape des instructions.
• Exemple de langages de programmation: C, Pascal, Fortran, Cobol, etc.
• La programmation orientée objet est basé sur le principe de découpage de programme en
plusieurs modules isolés les uns des autres et l’introduction de la notion des objets qui contient
des variables et des fonctions en rapport avec un sujet ou un métier.
• Exemple de langages de programmation: Java, C++, C#, etc.
Prof. Y.BOUKOUCHI / AIAC
4
Introduction
4.
Un programme
• Unprogrammeur crée des programmes informatiques.
• Le programmeur doit pour cela expliquer à l’ordinateur dans un langage de programmation, quelles
sont les données et quelles sont les méthodes à appliquer pour traiter ces données.
• Une fois que le programmeur a écrit son programme, qui est du texte en langage C, il doit compiler
le programme pour créer un fichier exécutable(en binaire) par l’ordinateur.
• Un programme source est un code écrit par un programmeur dans un langage de programmation.
• Un programme binaire décrit les instructions à exécuter par un microprocesseur
sous
forme numérique..
Prof. Y.BOUKOUCHI / AIAC 5
Introduction
Un peu d’histoire
•Le langage C a été inventé aux Bells Labs en 1972 par Dennis Ritchie pour permettre l'écriture
du système d'exploitation UNIX, alors développé par Ken Thompson et Dennis Ritchie.
• Par la suite en 1978, Brian W. Kernighan documenta très activement le langage, pour finalement
publier avec Ritchie le livre de référence The C Programming Language
• En 1989, l'organisme national de normalisation des USA (ANSI) normalisa le C (C89)
Ken
Thompso
Brian
Kernigha
Denni
s
Prof. Y.BOUKOUCHI / AIAC 7
Le langage C
7.
Environnement de développement
•Il existe plusieurs outils pour réaliser un projet en C:
• DEV C++
• CodeLite
• Code::Blocks.
• Microsoft Visual C++.
• Xcode.
• Qt Creator
• Il existe aussi des sites en ligne:
• www.codechef.com/ide
• www.jdoodle.com/c-online-compiler
• www.ide.geeksforgeeks.org
Prof. Y.BOUKOUCHI / AIAC 8
Le langage C
8.
Structure d’un programme
C
Exemple1 : Afficher un mot
• #include <stdio.h>: c’est une
bibliothèque lié à la gestion des
entrées et sorties (STanDard Input
Output), elle contient, entre
autres, la déclaration de la
fonction printf permettant d'afficher
du texte formaté.
• main(): c’est la fonction
principale,
appelée au démarrage du programme.
• Le return 0 indique seulement que la
valeur 0 est retournée au système
(ce qui indique que le
programme se termine sans
erreur).
Prof. Y.BOUKOUCHI / AIAC 9
Le langage C
#include <stdio.h>
int main()
{ printf("Bienvenue à
l'AIAC"); return 0;
}
9.
Structure d’un programme
C
Exemple2 : Lire un nombre
1. int n est la déclaration d’une variable
n de type entier.
2. scanf permet la lecteur des données
au clavier.
3. Le format d’affichage et de lecture %d
correspond à des nombres entier
(type int).
4. Dans printf, lors de l’affichage, le %d
est remplacé par la valeur de n.
Prof. Y.BOUKOUCHI / AIAC 10
Le langage C
#include <stdio.h>
int main()
{ int n;
printf("Ve
uillez
entrer un
nombre
entier :");
scanf("%d
",&n);
printf("Vous avez tapé %d,
félicitation!", n); return 0;
}
10.
Structure d’un programmeC
Exemple 3 : Calculer et mémoriser le résultat
• Le symbole = de l’affectation signifie
qu’une variable prend la valeur du
résultat d’un calcul.
• Il correspond à une opération de
recopie d’une donnée.
• Les phrases comprises entre /∗ et
∗/ sont des commentaires.
Elles n’ont pas d’influence
sur le déroulement du programme.
Prof. Y.BOUKOUCHI / AIAC 11
Le langage C
#include <stdio.h>
int main() {
float x,y; /* déclaration de deux variables x et y */
printf("Veuillez entrer un nombre
réel:"); scanf("%f",&x); /* lecture au clavier de
la valeur de x */ y = 2*x; /* on met dans y le
double du contenu de x */
printf("Le double du nombre tapé vaut %f
n", y); return 0;
}
11.
/***************************/
/* Projet C– Auteur: Y.B. */
/* Date : 20/09/18 */
/***************************/
// commentaire
int main(void)
{
/* corps du programme*/
déclaration des variables;
instruction1 ;
instruction2 ;
….
}
begin
end
Prof. Y.BOUKOUCHI / AIAC 12
Le langage C
Structure d’un programme C
• "main" : Cela signifie "principale", ses instructions
sont
exécutées.
• void main(void): La fonction main ne prend
aucun paramètre et ne retourne pas de valeur.
• int main(void): La fonction main retourne une
valeur entière à l'aide de l'instruction return
(0 si pas d’erreur).
• int main(int argc, char *argv[]): On obtient
alors des programmes auxquels on peut
adresser des arguments au moment
où on
lance le programme.
• Entre accolades "{" et "}" on mettra la succession
d'actions à réaliser.(Bloc)
Prof. Y.BOUKOUCHI /AIAC 15
Les variables et les Types
Les variables
• Dans un programme, il apparaît des variables qui permettent de donner des noms à
des données.
• Chaque variable doit avoir un type (entier, réel, caractère, suite de caractères, ou
type plus complexe).
• Chaque variable doit avoir un identificateur unique qui est le nom de la variable.
• Une déclaration de variable a toujours sous la forme suivante :
type identificateur;
• ou bien la forme avec l’initialisation :
type identificateur = valeur;
• On peut aussi déclarer plusieurs variables d’un même type séparées par des
virgules. Exemple
• float x, y=2.0; /* nombres réels. y a pour valeur initiale 2.0 */
• int n; /* nombre entier */
15.
• Les typesfloat et double permettent de représenter des nombres réels avec une certaine
précision (suivant une représentation des nombres appelée virgule flottante ou nombre
flottant).
• Le type double (codé sur 8 octets) est plus précis que le type float (codé sur 4 octets).
• La valeur maximale d’un double est d’environ 10308 alors que celle d’un float est de l’ordre
de 1038
• La bibliothèque math.h contient les fonctions de calcul scientifique pow (puissance),
sqrt (racine carrée), cos, sin, tan, etc.
Prof. Y.BOUKOUCHI / AIAC 16
Les variables et les Types
Les types
• Type entier int
• est une représentation des nombres entiers.
• généralement codé sur 4 octets (32 bits).
• Types réels float ET double
16.
• Le typechar (character) est un type caractère codé sur 1 octet.
• C’est la plus petite donnée qui puisse être stockée dans une variable.
• Une variable de type char peut être considérée soit comme un nombre, soit comme un
caractère que l’on peut afficher.
• Pour désigner par exemple le caractère Z dans un programme:
• on peut soit écrire ’Z’ (entre quotes),
• soit écrire 90 qui est le code ASCII du caractère Z.
• Dans les deux cas, il s’agit du même caractère et de la même donnée qui peut être stockée dans
la
même variable de type char.
• LES TYPES unsigned
• Aux types int et char correspondent des types unsigned int et unsigned char qui
représentent uniquement des valeurs positives.
• Un unsigned int sur 4 octets va de 0 à 232− 1.
• Un unsigned char sur 1 octet va de 0 à 28− 1 (c’est-à-dire de 0 à 255).
Prof. Y.BOUKOUCHI / AIAC 17
Les variables et les Types
Les types
• Le type char:
17.
Les constantes
• Uneconstante est une valeur qui n’est pas susceptible de varier lors de
l’exécution d’un programme.
• On peut donner un nom à une constante par un #define au début du
programme.
Prof. Y.BOUKOUCHI / AIAC 18
Les variables et les Types
#define PI 3.14159265358979323846
#define G 9.81
#define H 4816
// Constante de type float
// Constante de type float
// Constante de type int
/* Voici aussi une constante de type chaîne de caractères : */
#define MESSAGE1 "Erreur, vous devez mettre le #define hors du main !"
18.
Les conversions
• Étantdonnées deux variables de même type, on peut recopier le contenu d’une
variable dans l’autre par une affectation (signe =).
• Plus généralement, on peut copier dans une variable la valeur de toute une
expression.
• Si les deux variables sont de types différents, l’opération d’affectation = va réaliser,
lorsque c’est possible, une conversion. Si la conversion n’est pas possible, le
compilateur affichera un message d’erreur.
int a;
a = 10;
int b = 0;
double val = 23.3;
char carac = 'G';
Prof. Y.BOUKOUCHI / AIAC 19
Les variables et les Types
Pas deproblèmes en descendant la pyramide, mais dans le sens
inverse :
Données tronquées
Exemple :
Explication :
int a = 8;
double b = a;// b = 8
float c = 0.32;
long d = c;// d = 0
Prof. Y.BOUKOUCHI / AIAC 21
Les variables et les Types
Les conversions
Les conversions implicites : Conversions d’un type à
l’autre
Affectation des valeur d’un type à des variables d’un autre :
unsigned long a = 65523;
unsigned char b = a; // b = 243
6552310 = 1111 1111 1111 00112
= 1111 00112
21.
Conversion explicite(cast)
int a = 10;
long b = a;
(typeSouhaité)donnée
char a = 10;
double b = (double)a;
• Toujours ,il y a une perte d’information.
• Le compilateur nous donne un message
d’avertissement (warning), à moins
que l’on effectue un cast,
appelé aussi conversion
explicite, en indiquant le type
souhaité entre parenthèses
Prof. Y.BOUKOUCHI / AIAC 22
Les variables et les Types
Les conversions
Les conversions explicite :
(Cast)
Conversion implicite
Une bibliothèque
• Unebibliothèque est un ensemble de fonctionnalités ajoutées à un langage de
programmation. Chaque bibliothèque a un thème.
• Par exemple (en langage C):
• la bibliothèque math.h contient les fonctions mathématiques de calcul numérique
et des constantes comme M_PI pour représenter le nombre π ;
• la bibliothèque time.h contient les types et fonctions permettant de gérer la durée
(date et heure, temps d’exécution du programme...) ;
• la bibliothèque float.h contient les limites et constantes des types float et double ;
• La bibliothèque (Standard Input Output) stdio.h contient les types et fonctions
permettant de gérer les entrées-sorties (saisies au clavier, affichage de texte,
mais aussi fichiers...).
• etc.
Prof. Y.BOUKOUCHI / AIAC 24
Entrées-Sorties : stdio.h
24.
l’affichage de données
Afficherdes caractères
a) Pour afficher un caractère on peut utiliser la fonction putchar :
• putchar(’A’); /* Affiche un ’A’*/
• putchar(65); /* Affiche aussi un ’A’*/
b) Pour afficher une chaine de caractères on peut utiliser la fonction puts :
• puts("coucou !");
c) La fonction puts va automatiquement à la ligne après l’affichage. Pour
afficher un message sans aller à la ligne, on peut utiliser printf:
• printf("coucou !");
Prof. Y.BOUKOUCHI / AIAC 25
Entrées-Sorties : stdio.h
25.
• %d
• %f
•%c
• %s
• %o
décimale
décimale avec virgule fixe
char caractère
chaîne de caractères
octale
hexadécimale
%d n p
Prof. Y.BOUKOUCHI / AIAC 26
Entrées-Sorties : stdio.h
l’affichage de données
Afficher d’autres données
• Pour afficher des nombres entier, réels, etc. il faut spécifier un format, c’est à dire qu’il
faut préciser comment le résultat doit être affiché.
• La fonction printf est une fonction d’affichage formatée, ce qui signifie que les
données sont converties selon le format particulier choisi.
• Sa syntaxe est
printf("chaîne de contrôle ",expression-1, ..., expression-n);
• La chaîne de contrôle contient le texte à afficher et les spécifications de format
correspondant à chaque expression de la liste.
26.
Prof. Y.BOUKOUCHI /AIAC 27
Entrées-Sorties : stdio.h
l’affichage de
données Un exemple
d’affichage #include
<stdio.h>
int main(void){
char caract='W';
printf("%cn",
caract); int
nombre=2018;
printf("%dn",
nombre); //
nombre
float
x=134000.12345678;
double
y=134000.12345678;
printf("%fn", x); //
float
printf("%lfn", y);
//float ou double avec
Caractères spéciaux utiles
'n' Nouvelle ligne
'r' Retour chariot
't' Tabulation horizontale
'0' Caractère nul
'' Backslash
''' Apostrophe
'"' Guillemet
27.
La lecture auclavier
• La fonction getchar permet de lire un caractère.
• La fonction scanf permet de saisir des données au clavier et de les stocker aux adresses
spécifiées par les arguments de la fonctions.
scanf("chaîne de contrôle",argument-1,...,argument-n)
• La chaîne de contrôle indique le format dans lequel les données lues sont converties.
décimale
• %d
• %o
• %f
• %x
• %c
• %s
octale
décimale avec virgule fixe
hexadécimale
char caractère
chaîne de caractères
• On peut lire plusieurs valeurs dans un même appel à scanf, en séparant les %d, %f,...
par des espaces.
• scanf("%f %lf", &f1, &f2);
• Attention: Utilisation d’un getchar pour manger un retour chariot.
%d &i
Prof. Y.BOUKOUCHI / AIAC 28
Entrées-Sorties : stdio.h
Les opérations
logiques
Opérateur Opération
==Egalité
!=
>
<
>=
Inégalité
Strictement supérieur
Strictement inférieur
Supérieur ou égal
<= Inférieur ou égal
Prof. Y.BOUKOUCHI / AIAC 34
Structures Conditionnelles
c = a == b relation fausse, c = 0
c = a != b relation vraie, c = 1
c = a > b relation vraie, c = 1
c = a < b relation fausse, c = 0
c = a >= b relation vraie, c = 1
c = a <= b relation fausse, c = 0
Exemples
int a = 10;
int b = 3;
int c;
34.
Opérateur Opération
&& Etlogique
||
!
Ou logique
Négation logique
Comme pour les opérateurs
comparaison, la valeur retournée
de
par
ces opérateurs est un int qui vaut 1 si
la condition est vraie et 0 sinon.
int
int
a
b
=
=
10;
3;
int c = (a != b && a > b);
// c = 1 car 10 != 3 ET 10 > 3
Les opérations
booléens
Prof. Y.BOUKOUCHI / AIAC 35
Structures Conditionnelles
C1 C2 C1 && C2
VRAI VRAI VRAI
VRAI FAUX FAUX
FAUX VRAI FAUX
FAUX FAUX FAUX
C1 C2 C1 || C2
VRAI VRAI VRAI
VRAI FAUX VRAI
FAUX VRAI VRAI
FAUX FAUX FAUX
C1 !C1
VRAI FAUX
FAUX VRAI
35.
Prof. Y.BOUKOUCHI /AIAC 36
Structures Conditionnelles
La structure if … else
• Lesstructures conditionnelles permettent de déterminer
quelles instructions seront exécutées et dans quel ordre.
• Pour qu'un programme soit capable de prendre des décisions, on utilise
dans le code source des conditions
• Ces conditions permettent de tester des variables.
• une condition est soit vraie, soit fausse
Syntaxe1:
if (condition)
operation;
Syntaxe2:
if (condition)
operation1;
else
operation2;
36.
Des accoladessont nécessaires pour associer un else à un if antérieur
Prof. Y.BOUKOUCHI / AIAC 37
Structures Conditionnelles
La structure if … else
• Un else se rapporte toujours au dernier if rencontré
37.
Prof. Y.BOUKOUCHI /AIAC 38
Structures Conditionnelles
La structure if … else
Condition imbriqué
Lorsqu'on a plusieurs cas à tester, on peut enchaîner les if ... else
38.
La condition switch… case
• Le switch permet de distinguer plusieurs cas selon les valeurs d’une variable alors
que permet de distinguer seulement deux cas.
• L'instruction switch ... case sert à traiter des choix multiples en fonction de la valeur
d'une expression entière.
• Ainsi, il permet de simplifier l'écriture de conditions qui testent plusieurs valeurs
possibles pour une même variable.
Prof. Y.BOUKOUCHI / AIAC 39
Structures Conditionnelles
39.
• Default àla fin correspond au else, elle s'exécute si aucun des tests précédents n'est vérifié.
• Switch ne permet de tester que l'égalité. Vous ne pouvez pas tester « Si le nombre d'enfants est
supérieur à 2 » avec switch : il faut dans ce cas utiliser if.
• Switch ne peut travailler qu'avec des nombres entiers (int, unsigned int, char). Il est impossible de
tester des nombres décimaux (double).
Prof. Y.BOUKOUCHI / AIAC 40
Structures Conditionnelles
La condition switch …
case
40.
Prof. Y.BOUKOUCHI /AIAC 41
Structures Conditionnelles
int main(void){
char choix;
puts("Menu : faites un choix:n");
puts("Afficher la liste des clients ----------> a");
puts("Afficher les données d’un client --> b");
puts("Saisir un client -------------------------> c");
puts("Quitter -----------------------------------> d");
choix = getchar();
switch(choix)
{
case 'a' : puts("Affichage de la liste des clients"); /* mettre ici le code d’affichage des clients */
break;
case 'b' : puts("Affichage des données d’un client"); /* mettre ici le code de saisie et d’affichage */
break;
case 'c' : puts("Saisie des données du client"); /* mettre ici le code de saisie des données */
break;
case 'd' :
break;
default : puts("Erreur de saisie du choix !");
}
return 0;
}
• Les boucles(les itérations) vous permettent de répéter les
mêmes instructions plusieurs fois dans votre programme.
• Les boucles sont répétées tant qu'une condition est vraie.
• Il existe 3 types de boucles à connaître :
• while (condition){};
• do ... while(condition) ;
• for(initialisation, condition, incrémentation).
• La boucle for est généralement utilisée lorsqu'on sait combien de fois on
souhaite répéter les instructions.
• tandis que while et do... while sont plutôt utilisées lorsqu'on
souhaite répéter des instructions jusqu'à ce qu'une condition spécifique soit
vérifiée.
Prof. Y.BOUKOUCHI / AIAC 44
Les boucles
44.
La boucle while
•Dans la boucle while, le programme répète un bloc d’instructions tant qu’une
certaine condition est vraie.
• Tout ce qui est entre accolades sera répété tant que la condition est vérifiée.
while (condition)
{
/* Instructions à répéter */
}
Prof. Y.BOUKOUCHI / AIAC 45
Les boucles
45.
La boucle do... while
• L'instruction est d'abord exécutée, puis l'expression est évaluée. Si elle est vraie,
on reboucle sur l'exécution de l'instruction.
• À la différence de la boucle while, l'instruction est toujours exécutée au moins
une fois
do
{
/* Instructions */
} while (condition);
Prof. Y.BOUKOUCHI / AIAC 46
Les boucles
46.
• une initialisation;
• une condition ;
• une incrémentation.
La boucle for
• Ce type de boucle, que l'on retrouve fréquemment, permet de condenser :
1. L'instruction1 est d'abord exécutée (initialisation ).
2. Puis, tant que l'expression est vraie, on exécute le bloc d’instructions.
3. puis l'instruction2 (instruction de progression).
for (instruction1; condition ; instruction2)
{
/* bloc d’instructions; */
}
Prof. Y.BOUKOUCHI / AIAC 47
Les boucles
Déclaration d’un tableau
•Un tableau permet de mémoriser plusieurs données du même type.
• Contrairement aux variables simples, les tableaux permettent de stocker des
données nombreuses en mémoire centrale.
• On déclare un tableau (statique) par
typeElements nomTableau[NOMBRE_ELEMENTS];
• Dans une telle déclaration, le nombre d’éléments du tableau est
obligatoirement une constante.
• exemple :
• int tab[100];
• char chaine[150];
• int tb1[10] ;
Prof. Y.BOUKOUCHI / AIAC 50
Les tableaux
50.
Accès aux éléments
•Les éléments d’un tableau sont comme des cases rangées successivement
dans la mémoire centrale.
• Les éléments d’un tableau sont numérotés par des indices (de 0 à N-1).
• Modification du contenu d’un élément :
tab[3] = 19 ;
Utilisation de la valeur d’un élément :
x = tab[3] + 1 ;
x = tab[3] + 1 ;
? ? ? 19 ? ? ? ? ? ?
9
8
7
6
5
4
0 1 2 3
Prof. Y.BOUKOUCHI / AIAC 51
Les tableaux
? ? ? ? ? ? ? ? ? ?
51.
Initialisation lors dela déclaration
Comme les autres types de variables, les éléments du tableau peuvent être initialisés lors de
la déclaration du tableau. On met pour celà les valeurs des éléments entre accolades {} séparés par
des virgules.
int tab[10] = { 21, 32, -4, 1, 37, 88, 9, -1, 0, 7} ;
0 1 2 3 4 5 6 7 8 9
21 32 -4 1 37 88 9 -1 0 7
21 32 -4 1 0 0 0 0 0 0
5
• Initialisation d’une partie du tableau :
0 1
2
3
4
21 32 -4 1
int tab[10] = { 21, 32, -4, 1} ;
6 7 8 9
• Initialisation sans spécifier la taille : int tab[ ] = { 21, 32, -4, 1} ;
0
1
Prof. Y.BOUKOUCHI / AIAC 52
Les tableaux
52.
• Le programmesuivant permet de
mémoriser différentes valeurs
saisies au clavier et de les
réafficher dans l’ordre où
elles ont été saisies.
• Le nombre de valeurs, ou nombre
d’éléments du tableau, est fixé à 5.
Nombre d’éléments
fixé
Prof. Y.BOUKOUCHI / AIAC 53
Les tableaux
#include <stdio.h>
#define NB_ELEM 5 /* Nombre d’éléments du tableau */
int main(void)
{ int i; /* indice
*/
float
tableau[NB_EL
EM]; /*
déclaration du
tableau */
for (i=0 ;
i<NB_ELEM ;
i++){
printf("Entrez
l’élément %d
: ", i);
scanf("%f",
&tableau[i]);
/* lecture
d’un
53.
• Le programmesuivant permet
aussi de lire des éléments au
clavier et de les réafficher,
mais cette fois le nombre
d’éléments est lu au
clavier.
• Ce nombre d’éléments doit
toutefois rester inférieur à une
valeur maximale constante
fixée (NB_ELEM_MAXI).
Nombre d’éléments variable
borné
Prof. Y.BOUKOUCHI / AIAC 54
Les tableaux
#include <stdio.h>
#define NB_ELEM_MAXI 100 /* Nombre maximum d’éléments du tableau */
int main(void){
int n, i; /* nombre d’éléments et indice */
float tableau[NB_ELEM_MAXI]; /* déclaration du tableau */
printf("Entrez le nombre d’éléments à taper : ");
/* lecture du nombre d’éléments au clavier (variable) */
scanf("%d", &n);
if (n > NB_ELEM_MAXI){ /* test d’erreur */
puts("Erreur, nombre trop grand !");
return 1; }
for (i=0 ; i<n ; i++){
printf("Entrez l’élément %d : ", i);
scanf("%f", &tableau[i]); /* lecture d’un
élément */ }
for (i=0 ; i<n ; i++){ }
printf("l’élément numéro %d vaut %fn", i, tableau[i]);
return 0;
}
54.
Les tableaux àplusieurs indices
• Comme tous les langages, C autorise
les tableaux à plusieurs indices (à
plusieurs dimensions).
• Déclaration :
type nomtab [N][M][P];
• Par exemple, la déclaration : int t[5][3]
réserve un tableau de 15 (5 x 3) éléments.
• Un élément quelconque de ce tableau
est repéré par leur indices : nomTab[i]
[j][k]…
• Déclaration et initialisation :
int tab [3] [4] =
{ { 1, 2, 3, 4 } , { 5, 6, 7, 8 }, { 9,10,11,12 } }
Prof. Y.BOUKOUCHI / AIAC 55
Les tableaux
#include <stdio.h>
int main(){
int tab[3][4]={{11,12,13,14},
{21,22,23,24},
{31,32,33,34}};
int i,j;
for(i=0;i<3;i++){
for(j=0;j<4;j++){
printf("tab[%d,%d]=%dn",i+1,j+1,tab[i][j]);
}
}
system("pause");
return 0;
}
tab[1,1]=1
1
tab[1,2]=1
2
tab[1,3]=1
3
tab[1,4]=1
4
tab[2,1]=2
1
tab[2,2]=2
2
tab[2,3]=2
3
tab[2,4]=2
4
tab[3,1]=3
1
tab[3,2]=3
2
tab[3,3]=3
3
tab[3,4]=3
4
Appuyez
sur une
touche
pour
continuer.
..
Définition
• Lorsqu’un programmecomprend de nombreuses lignes de code dans le programme
principal main, il serait illisible, comprendrait trop de variables, etc.
• Alors, on décompose les problèmes en sous-problèmes et le programme en sous-
programmes qui résolvent les sous-problèmes.
• En langage C, l’outil pour créer des sous-programmes est la notion de fonction.
• Définition d'une fonction
typeRetour nom-fonction ( type1 param1, …, typeN paramN)
{
/*déclarations de variables locales */
/* suite d'instructions */
}
• typeRetour désigne le type de la valeur qu'elle retourne, si la fonction ne renvoie
pas de valeur elle est de type void. Dans ce cas on parle de procédure.
• Si la liste des paramètres est vide ou void, la fonction ne prend pas de
paramètre.
Prof. Y.BOUKOUCHI / AIAC 58
Les fonctions
58.
Définition
• Fonctions avecarguments et retournant une valeur.
• type fonction(int x, int y, char ch)
• float somme(float x, float y, float z)
• int maxTab(int tab[])
• Fonctions sans arguments et ne
retournant pas de valeur.
• void fonction(void) ou void
fonction()
• void lireMessage()
• void afficheErreur()
• Fonctions avec arguments ne
retournant pas de valeur.
• void fonction(int x, int y, char ch)
• void afficherList(char list[])
Prof. Y.BOUKOUCHI / AIAC 59
Les fonctions
59.
Exemple
Prof. Y.BOUKOUCHI /AIAC 60
Les fonctions
Un programme qui lit un nombre x au
clavier et calcule f(x):
f (x) = (x3− 2x + 1) sin(3x + 1)
#include <stdio.h>
#include <math.h>
int main(void){
float x, y; /* on calcule y=f(x) */
puts("Veuillez taper une valeur de x :");
scanf("%f", &x);
y = (x*x*x-2*x+1)*sin(3*x+1);
printf("on a : f(%f) = %fn", x, y);
return 0;
}
#include <stdio.h>
#include <math.h>
float Lire(void) /* Fonction Lire, permet de lire une valeur */
{ float d; /* déclaration d’une variable locale d
*/ puts("Veuillez taper une valeur :");
scanf("%f", &d);
return d; /* on renvoie la valeur de d */
}
float CalculF(float x) /* Fonction CalculF, calcule
une valeur de la fonction */
{ return (x*x*x-2*x+1)*sin(3*x+1);
}
void Affiche(float y) /* Fonction Affiche, permet
d’afficher une valeur */
{ printf("La valeur calculée est %fn", y);
/* une fonction void ne retourne rien */
}
int main(){
float x, y; /* Fonction main, programme principal */
x = Lire(); /* appel de la fonction Lire */
y = CalculF(x); /* calcul de f(x) */
Affiche(y); /* appel de la fonction Affiche */
return 0;
60.
Les variables Localeset
Globales
Variables globale
• Sont des variables partagées par
plusieurs
fonctions;
• On dit que leur portée (leur espace de validité) est
limitée à la partie du programme source qui suit
leur déclaration
Variables locales
• Sont déclarées à l’intérieur de la définition d’une
fonction. On ne peut les utiliser qu’à l’intérieur de
cette fonction.
• Leur portée est donc limitée à cette fonction.
• Si l’on trouve une variable de même nom ailleurs
dans le programme, il ne s’agit pas de la même
variable, mais d’une variable homonyme.
Prof. Y.BOUKOUCHI / AIAC 61
Les fonctions
Exemple 2
int n ;
main()
{
int p ;
....
}
fct1 ()
{
int p ;
int n ;
}
Exemple 1
main()
{
....
}
int n ;
float x ;
fct1 (...)
{
....
}
fct2 (...)
{
....
}
P
o
r
t
é
e
N
P
P
61.
Prof. Y.BOUKOUCHI /AIAC 62
Les fonctions
Le prototype d’une fonction
Une déclaration de fonction est le prototype de cette fonction suivi d’un point virgule.
une déclaration peut être répétée plusieurs fois dans le programme.
Le prototype d’une fonction indique essentiellement :
• Le nom de la fonction,
• Les paramètres de la fonction et leur type,
• Le type de retournée par la fonction.
typeRetour nomFonction ( ListeParalétres);
Exemple:
• int puissance(int n, int p);
• Float moyenneNote(int tab[]);
Une définition de fonction est le prototype suivi du corps de la fonction entre accolades.
La définition apparaître une seule fois dans le programme.
typeRetour nomFonction ( ListeParalétres){
/*déclarations de variables locales */
/* suite d'instructions *
}
62.
Prof. Y.BOUKOUCHI /AIAC 63
Les fonctions
Exemple
Un programme qui lit deux nombres
x et p et calcule la puissance xp
#include <stdio.h>
/*Il est recommandé d’utiliser des déclarations globales pour
les prototypes*/
float puissance(float x, int p); // déclaré globale
int main(void){
// déclaré locale à main : float puissance(float x,
int p);
float x; int p;
printf("Taper une valeur de x :");
scanf("%f", &x);
printf("Taper une valeur de p :");
scanf("%d", &p);
printf("%.2f puissance %d = %.2fn",x,p,puissance(x,p));
return 0;
}
float puissance(float x, int p){
float r=1; int i;
for(i=0;i<p;i++)
r=r*x;
return r;
}
Taper une valeur de
x :4 Taper une valeur
de p :5
4.00 puissance 5 =
#include <stdio.h>
float puissance(float x, int p){
float r=1; int i;
for(i=0;i<p;i++) r=r*x;
return r;
}
int main(void){
float x; int p;
printf("Taper une valeur de x :");
scanf("%f", &x);
printf("Taper une valeur de p :");
scanf("%d", &p);
printf("%.2f puissance %d =
%.2fn",x,p,puissance(x,p));
return 0;
}
63.
Le mécanisme detransmission
d’arguments
Prof. Y.BOUKOUCHI / AIAC 64
Les fonctions
• Dans langage C les arguments d’une
fonction sont toujours transmis par
valeur - une copie de la valeur de
l’argument effectif.
• Impossible à une fonction de modifier la
valeur d’un objet reçu en argument.
• Pour contourner cette difficulté de modifie
la valeur d’un objet apparaissant en
argument (sauf s’il s’agit d’un tableau),
il
existe plusieurs possibilités:
• utiliser un pointeur sur l’objet à modifier;
• se servir de la valeur de
retour de la fonction;
• utiliser des variables globales.
#include <stdio.h>
void echange1(int x, int y);
int main(){
int a=5, b=10;
printf("Avant a=%d et b=%dn",a,b);
echange1(a,b);
printf("Apres a=%d et b=%dn",a,b);
}
void echange1(int x,int y){
int temp;
temp=x;
x=y;
y=temp;
}
Avant a=5 et
b=10 Apres a=5
et b=10
Appuyez sur une
touche pour
continuer...
64.
Le mécanisme detransmission
d’arguments
Prof. Y.BOUKOUCHI / AIAC 65
Les fonctions
#include <stdio.h>
int a,b;
void echange2(void);
int main(){
a=5; b=10;
printf("Avant a=%d
et b=%dn",a,b);
echange2();
printf("Apres a=%d
et b=%dn",a,b);
}
void echange2(){
int temp;
temp=a;
a=b;
b=temp;
} Avant a=5 et
b=10 Apres a=10
et b=5
Appuyez sur une
#include <stdio.h>
void echange1(int x, int y);
int main(){
int a=5,b=10;
printf("Avant a=%d et b=
%dn",a,b);
echange1(a,b);
printf("Apres a=%d et b=
%dn",a,b);
}
void echange1(int x,int y){
int temp;
temp=x;
x=y;
y=temp;
} Avant a=5 et
b=10 Apres a=5
et b=10
Appuyez sur une
Utilisation des
variables
globales
65.
Des fonctions
récursives
Prof. Y.BOUKOUCHI/ AIAC 66
Les fonctions
Le langage C autorise la récursivité des appels de
fonctions. Celle-ci peut prendre deux aspects :
• récursivité directe : une fonction
comporte,
dans sa définition, au moins un appel à elle-
même,
• récursivité croisée : l’appel d’une
fonction
entraîne celui d’une autre fonction qui, à son
tour, appelle la fonction initiale (le cycle
pouvant d’ailleurs faire intervenir plus de deux
fonctions).
#include <stdio.h>
int factorielle(int);
int main(){
int n=5,f;
f=factorielle(n);
printf("%d!=%dn",n,f);
}
int factorielle(int n){
int f=1;
if(n>0)
return n*factorielle(n-1);
else
return 1;
}
Mémoire centrale etadresses
• La mémoire centrale d’un ordinateur est
composée d’un très grand nombre d’octets.
Chaque octet est repéré par un numéro
appelé adresse de l’octet.
• Chaque variable dans la mémoire occupe des
octets contigus. Par exemple, un int occupe 4
octets qui se suivent.
• L’adresse de la variable est l’adresse de son
premier octet.
Prof. Y.BOUKOUCHI / AIAC 69
Adresses, pointeurs et passage par adresse
Variable Adresse Mémoire
Octet/8bits
c 1001000 ‘A’
1001001
i 1001002
2018
1001003
1001004
1001005
1001005
1001007
1001008
1001009
1001010
1001011
69.
Adresse d’une variable
•On peut connaître l’adresse d’une variable par
l’opérateur &.
• &i /* adresse de la variable x : adresse de son premier octet
*/
Prof. Y.BOUKOUCHI / AIAC 70
Adresses, pointeurs et passage par adresse
Variable Adresse Mémoire
Octet/8bits
c 1001000 ‘A’
#include <stdio.h> 1001001
int main(){
i 1001002
char c='A';
1001003
int i=2018;
float f=55.9; 2018
1001004
printf("la valeur de c est %c et son adresse est %dn",c,&c);
1001005
printf("la valeur de i est %d et son adresse est %dn",i,&i);
1001005
printf("la valeur de f est %.2f et son adresse est %dn",f,&f);
system("pause"); 1001007
return 0;
1001008
}
1001009
la valeur de c est A et son adresse est 2686791
1001010
la valeur de i est 2018 et son adresse est 2686784
la valeur de f est 55.90 et son adresse est 2686780
1001011
Appuyez sur une touche pour continuer...
70.
Variable de typepointeur
• L’adresse d’une variable peut être mémorisée dans
une variable.
• Les variables dont les valeurs sont des adresses
s’appellent des pointeurs.
• On déclare un type pointeur par l’opérateur *
• On déclare :
• un pointeur sur int par le type int*,
• un pointeur sur float par le type float*,
• Etc.
• On accède à la donnée pointée par un pointeur
(valeur de x dans l’exemple précédent) par
une étoile.
• int*p; /*on déclare le pointeur p qui pointe sut
int */
• p=&i; /* on affecte au pointeur p l’adresse de
Prof. Y.BOUKOUCHI / AIAC 71
Adresses, pointeurs et passage par adresse
Variable Adresse Mémoire
Octet/8bits
c 1001000 ‘A’
1001001
i 1001002
2018
1001003
1001004
1001005
1001005
1001007
1001008
p 1001009 1001002
1001010
1001011
71.
Variable de type
pointeur
Prof.Y.BOUKOUCHI / AIAC 72
Adresses, pointeurs et passage par adresse
Variable Adresse Mémoire
Octet/8bits
#include <stdio.h>
int main(){
int i=2;/* déclaration d’une variable i */
int *p; /* déclaration d’un pointeur p */
p = &i; /* p pointe sur i */
/* la valeur de p est l’adresse de i */
printf("la valeur de i :%dn",
*p); /* affichage de valeur de *p */
printf("Donner une valeur:");
scanf("%d", p); /* lecture de la valeur
de i au clavier */
printf("la nouvelle valeur de i:%dn", i); /* affichage de la nouvelle
valeur de i */
printf("la valeur de *p:%dn", *p); /* affichage de la valeur de *p
*/
system("pause
"); return 0;
}
c 1001000 ‘A’
1001001
i 1001002
2018
1001003
1001004
1001005
1001005
1001007
1001008
la valeur de i :2
Donner une
p 1001009 1001002
1001010
72.
Variable de typepointeur
• Attention:
• Ne pas confondre l’usage de l’étoile lors de la
déclaration d’une variable de type pointeur
avec l’usage de l’étoile qui permet d’accéder
à l’objet pointé par le pointeur.
• Ne pas confondre la valeur d’un pointeur p, qui est
une adresse, et la valeur de l’objet pointé par p,
qui n’est en général pas une adresse, par
exemple un int dans le cas d’un pointeur de type
int*.
• lorsque p pointe sur i, la valeur de p est l’adresse de
i, toute modification de *p modifie i et
toute modification de i modifie *p. La raison est
que *p et i sont sur le même
emplacement mémoire dans la mémoire
RAM.
Prof. Y.BOUKOUCHI / AIAC 73
Adresses, pointeurs et passage par adresse
Variable Adresse Mémoire
Octet/8bits
c 1001000 ‘A’
1001001
i 1001002
2018
1001003
1001004
1001005
1001005 *p
1001007
1001008
p 1001009 1001002
1001010
1001011
73.
Passage de paramètrepar valeur
• Lorsqu’on passe un paramètre à une fonction, la
fonction ne peut pas modifier la variable.
• La variable est automatiquement recopiée et la
fonction travaille sur une copie de la variable.
• La modification de la copie n’entraîne pas une
modification de la variable originale. C’est le
passage de paramètre par valeur.
Adresses, pointeurs et passage par adresse Prof. Y.BOUKOUCHI / AIAC
74
#include <stdio.h>
void permutation(int x, int y){
int z;
z=x;
x=y;
y=z;
printf(
"Au
cou
rs
de
per
mut
atio
n
a=
%d
et
b=
%d
n",x
Avant permutation a=2 et b=5
Au cours de permutation a=5 et
b=2 Après permutation a=2 et
b=5
Appuyez sur une touche pour
continuer...
Variable Adresse mémoire
a 2080090 2
b 2080094 5
Variable Adresse mémoire
x 2080100 2
y 2080104 5
z 2080108
Une Copie de la valeur
74.
variable.
Passage de paramètrepar adresse
• L’idée du passage par adresse est de passer en
paramètre non pas une copie de la valeur d’une
variable, mais un pointeur qui pointe sur cette
variable.
• Ainsi, Lorsqu’on modifie la mémoire à cette
adresse, la donnée est modifiée, car on travaille
bien sur l’emplacement mémoire de cette
Adresses, pointeurs et passage par adresse Prof. Y.BOUKOUCHI / AIAC
75
#include <stdio.h>
void permutation(int *x, int *y){
int z;
z=*x; // le contenu de l’adresse
*x=*y;
*y=z;
printf("Au cours de permutation
a=%d et b=%dn",*x,*y);
}
int main(){
int a=2;
int b=5;
printf("Avant permutation a=%d et b=%dn",a,b);
permutation(&a,&b);
printf("Après permutation a=%d et b=%dn",a,b);
system("pause");
return 0;
}
Avant permutation a=2 et b=5
Au cours de permutation a=5 et
b=2 Après permutation a=5 et
b=2
Appuyez sur une touche pour
continuer...
Variable Adresse mémoire
a 2080090 2
b 2080094 5
Variable Adresse mémoire
x 2080100 2080090
y 2080104 2080094
z 2080108
Une Copie de l’adresse
75.
Le pointeur NULL
•Il existe un symbole noté NULL , dont la valeur représente conventionnellement un pointeur
ne pointant sur rien,
• c’est-à-dire auquel n’est associée aucune adresse.
• Cette valeur peut être affectée à un pointeur de n’importe quel type, par exemple:
• int *pi= NULL;
• char *pc= NULL;
• double *pd= NULL;
• Etc.
• Exemples d’utilisation de NULL:
• Pour l’initialisation d’une variable pointeur
• Dans des listes chaînées
• En valeur de retour d’une fonction
Prof. Y.BOUKOUCHI / AIAC 76
Adresses, pointeurs et passage par adresse
76.
• L’allocation dynamiquede
mémoire
permet de créer des tableaux dont la
taille mémoire est variable en fonction
des besoins, et de libérer cette mémoire
après utilisation.
• La fonction malloc réserve des
octets pour une utilisation par le
programme.
• Le nombre d’octets est passé
en
paramètre à la fonction malloc.
• On utilise la fonction sizeof qui calcule le
nombre d’octets nécessaires
• La fonction malloc retourne l’adresse du
premier octet réservé (un pointeur).
• Après utilisation de la mémoire,
la
mémoire doit impérativement être
libérée avec la fonction free.
Les tableaux
dynamiques
Prof. Y.BOUKOUCHI / AIAC 77
Adresses, pointeurs et passage par adresse
#include <stdio.h>
#include <stdlib.h> /* pour utiliser malloc */
int main(void)
{ int nb,i;
int *tab; /* adresse du tableau (type pointeur) */
printf("Entrez la taille du tableau : ");
scanf("%d", &nb);
/* le nombre d’éléments connu, on alloue le tableau */
tab = (int*) malloc (nb * sizeof(int) ); /* allocation */
puts("Entrez les éléments du tableau :");
for (i=0 ; i<nb ; i++) // la saisie des éléments du tableau
scanf("%d", &tab[i]);
for (i=0 ; i<nb ; i++) // l’affichage du tableau
printf("tab[%d] = %dn", i, tab[i]);
free(tab); /* libération de mémoire obligatoire */
return 0;
}
Entrez la taille du tableau :
3 Entrez les ÚlÚments du
tableau :
29
10
2018
tab[0] = 29
tab[1] = 10
tab[2] = 2018
77.
lit le nombred’éléments d’un
tableau, réserve
mémoire pour des
de l’espace
float, lit
les
éléments du tableau au clavier et
retourne l’adresse du tableau.
• Le nombre d’éléments du tableau
doit être passé par adresse
pour être transmis au main.
Les tableaux dynamiques
• Exemple
• Ecrire la fonction RentrerTableau qui
Prof. Y.BOUKOUCHI / AIAC 78
Adresses, pointeurs et passage par adresse #include <stdio.h>
#include <stdlib.h> /* pour utiliser malloc */
/* fonction retournant un pointeur de type float* */
float* RentrerTableau(int *addrNbreElements)
{ int n, i; float *tab; /* adresse du tableau (type pointeur) */
printf("Entrez la taille du tableau : "); scanf("%d", &n);
*addrNbreElements = n; /* passage par adresse, renvoi de n */
/* le nombre d’éléments connu, on alloue le tableau */
tab = (float*) malloc ( n * sizeof( float ) ); /* allocation */
puts("Entrez les éléments du tableau :");
for (i=0 ; i<n ; i++)
scanf("%f", &tab[i] );
return tab; /* on retourne l’adresse du
tableau */
}
void Affichage(float *tab, int nb) /* affiche un tableau tab */
{ int i;
for (i=0 ; i<nb ; i++) printf("tab[%d] = %.2fn", i, tab[i]);
}
int main(void)
{ int nb; float *tab;
tab = RentrerTableau(&nb);/* on récupère l’adresse du tableau dans tab */
Affichage(tab, nb);
free(tab); /* libération de mémoire obligatoire */
return 0; }
Entrez la taille du tableau :
3 Entrez les ÚlÚments du
tableau : 14.55
18.75
13.25
tab[0] = 14.55
tab[1] = 18.75
tab[2] = 13.25
Représentation d’une chaine
•En langage C, il n’existe pas de véritable type chaîne.
• Une chaîne de caractères est un tableau de caractères se terminant par le
caractère spécial ’0’ .
• Le caractère ’0’ sert à repérer la fin de la chaîne, évitant d’avoir à connaître le
nombre de caractères de la chaîne.
• Cela signifie qu’une chaîne de n caractères occupe en mémoire un
emplacement de n+1 octets.
Prof. Y.BOUKOUCHI / AIAC 81
Les chaines de caractères
0 1 2 3 4 5 6 7
b o N j o u r 0
1
N
81.
Prof. Y.BOUKOUCHI /AIAC 82
Les chaines de caractères
Représentation d’une chaine
• Calculer la longueur d’une chaine de caractères
#include <stdio.h>
int longueur(char chaine[]); // int longueur(char *chaine);
int main()
{ char
nom[31]; int
Long;
printf("Veuillez
entrer votre
nom: ");
scanf("%s",
nom); /*
lecture de la
chaîne. pas de
& */
Long =
longueur( no
m);
for(i=0; chaine[i]!='0';i++);
return i;
}
Veuillez entrer votre nom:
BOUKOUCHI
Votre nom est :
BOUKOUCHI
Sa longueur est :
9
Appuyez sur une touche pour
82.
• char ch[20];
• ch = "bonjour"; //invalide
• ch est une constante
pointeur qui correspond
à l’adresse que le
compilateur a attribuée
au tableau ch ;
Initialisation de tableaux de
caractères
Prof. Y.BOUKOUCHI / AIAC 83
Les chaines de caractères
• C autorise à initialiser votre tableau de caractères à
l’aide d’une chaîne constante.
• char ch[20] = "bonjour" ;
• char ch[20] = { 'b','o','n','j','o','u','r','0' }
• char message[] = "bonjour" ;
• Initialisation de tableaux de pointeurs sur des
chaînes.
• char * jour[7] = { "lundi", "mardi", "mercredi",
"jeudi", "vendredi", "samedi", "dimanche" } ;
83.
Initialisation de tableauxde
caractères
Prof. Y.BOUKOUCHI / AIAC 84
Les chaines de caractères
#include <stdio.h>
main(){
char * jour[7]={"lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"};
int i ;
printf("donnez un entier entre 1 et 7 : ");
scanf("%d",&i);
printf("le jour numéro %d de la semaine
est %sn", i, jour[i-1]);
}
donnez un entier entre 1 et 7 : 4
le jour numÚro 4 de la semaine est jeudi
Appuyez sur une touche pour continuer...
84.
Lire et écriredes
chaînes
Prof. Y.BOUKOUCHI / AIAC 85
Les chaines de caractères
• Le langage C offre plusieurs possibilités de lecture ou d’écriture de chaînes :
• l’utilisation du code de format %s dans les fonctions printf et scanf ;
• les fonctions spécifiques de lecture (gets) ou d’affichage (puts) d’une chaîne (une seule à la fois).
• Les fonctions printf et scanf permettent de lire ou d’afficher simultanément plusieurs
informations de type quelconque. En revanche, gets et puts ne traitent qu’une chaîne à
la fois.
• De plus, la délimitation de la chaîne lue ne s’effectue pas de la même façon avec scanf et
gets. Plus précisément :
• avec le code %s de scanf, on utilise les délimiteurs habituels (l’espace ou la fin de ligne). Cela
interdit donc la lecture d’une chaîne contenant des espaces. De plus, le caractère délimiteur n’est
pas consommé : il reste disponible pour une prochaine lecture ;
• avec gets, seule la fin de ligne sert de délimiteur. De plus, contrairement à ce qui se produit avec
scanf, ce caractère est effectivement consommé : il ne risque pas d’être pris en compte lors d’une
nouvelle lecture.
85.
Lire et écriredes
chaînes
Prof. Y.BOUKOUCHI / AIAC 86
Les chaines de caractères
#include <stdio.h>
main(){
char nom[20], prenom[20], adresse[50];
printf("quelle est votre adresse : ");
gets (adresse);
printf ("donnez votre nom et votre
prénom : ");
scanf ("%s %s", nom, prenom);
printf ("bonjour cher %s %s qui habitez
à ", prenom, nom);
puts (adresse);
system("PAUSE");
}
quelle est votre adresse : 123, Rue Ghaza, Salam,
Casablanca donnez votre nom et votre prénom : BOUKOUCHI
Youness
bonjour cher Youness BOUKOUCHI qui habitez à 123, Rue Ghaza, Salam,
Casablanca Appuyez sur une touche pour continuer...
86.
La bibliothèque <string.h>
•La bibliothèque string.h contient des fonctions de traitement des chaînes de
caractères.
• strcpy
• La fonction strcpy copie une chaîne dans une autre.
• char* strcpy(char* destin, char*source);
• strcat
• La fonction strcat concatène deux chaînes de caractères.
• char* strcat(char* s1, char* s2);
• strlen
• La fonction strlen retourne la longueur d’une chaîne de caractères.
• size_t strlen(char* s);
• strcmp
• Le fonction strcmp permet de comparer deux chaînes pour l’ordre alphabétique.
• int strcmp(char* s1, char *s2);
• Le résultat est < 0 si s1 < s2, égal à 0 si s1=s2, et il est > 0 si s1 > s2.
• Etc.
Prof. Y.BOUKOUCHI / AIAC 87
Les chaines de caractères
• Une structureest un type qui permet de stocker plusieurs données, de même
type ou de types différents, dans une même variable de type structure.
• C'est une collection des données qui peuvent être de types différents (entières,
flottantes, tableaux, pointeurs, etc...).
• Ces données sont appelés les membres (ou les champs) de la structure.
Définition d’une
structure
Prof. Y.BOUKOUCHI / AIAC 89
Les structures
Voiture
Numéro: chaine de caractères
Date circulation: Date
Couleur: chaine de caractères
Marque: chaine de caractères
Personne
Nom : chaine de caractères
Prénom: chaine de caractères
Age: entier
Notes: tableaux des réels
Compte
Numéro: entier
Solde: réels
Date création:
structure Date
Date
Jour: entier
Mois: entier
Année: entier
89.
Déclaration d’une structure
•Une structure est définie avec le mot clef struct, à la fois dans la définition du
type et dans la déclaration des variables.
• La déclaration d’une variable de type struct se fait comme pour une autre
variable.
Prof. Y.BOUKOUCHI / AIAC 90
Les structures
/* Définition d’une structure */
struct point {
/* les champs se déclarent
comme des variables*/
/* mais on ne peut pas
initialiser les valeurs */
/* trois champs x, y, z */
float x,y;
float z;
};
/* Déclaration d’une variable de type point*/
struct point P;
/* Définition d’une structure */
struct nom_de_la_structure {
type_membre1 nom_membre1 ;
type_membre2 nom_membre2 ;
…
type_membreN nom_membreN ;
};
/* Déclaration d’une variable de type struct */
struct nom_de_la_structure variable;
90.
Déclaration d’une structure
•Grâce à un typedef, on peut donner un nom au type structure pour éviter
la répétition fastidieuse du mot clef struct dans la déclaration des variables.
Prof. Y.BOUKOUCHI / AIAC 91
Les structures
/* Définition d’un type Point3D */
typedef struct point
{ /* déclaration d’un */
float x,y,z; /* nouveau type par typedef */
}Point3D;
/* Déclaration d’une variable P de type
Point3D */
Point3D P;
/* Version 1*/
/* Définition d’un type nomType */
typedef struct nomStructure
{
// liste des membres;
}nomType;
/* Version 2*/
/* Définition d’un type nomType */
typedef struct
{
// liste des membres;
}nomType;
91.
Accès aux membres
•Accès aux membres par l’opérateur « . »
• nomVariable.champ
• compte1.solde = 3834.56;
• y=comptes[33].solde;
• Dans le cas des structures imbriquées:
• nomVariable.nomChamp1.nomChamp.nomChamp3.etc.
• compte1.dernierVersement.jour = 15;
• personnes[12].dateNaissance.mois = 11;
• printf("nDate d’emprunt %d/%d/%dn", m.emprunt.jour, m.emprunt.mois, m.emprunt.an);
Prof. Y.BOUKOUCHI / AIAC 92
Les structures
92.
Structure imbriquée
• Unestructure peut être membre d'une
autre structure
struct date {
int jour;
int mois;
int annee;
};
struct compte {
int no_compte ;
char nom[80];
float solde;
struct date
dernier_versem
ent;
};
• Remarque : ordre de
déclaration des
structures
93
Les structures Prof. Y.BOUKOUCHI / AIAC
int mois; int annee;
typedef struct {
int jour;
} Date ;
typedef struct { /* définition de la structure*/
int noCompte ; float solde;
Date dateCreation;
}Compte;
main(){
Compte c;
c.noCompte=2004001;
c.solde=550.78;
c.dateCreation.jour=11;
c.dateCreation.mois=10;
c.dateCreation.annee=2018;
printf("Numéro :%dn",c.noCompte);
printf("Solde :%.2fn",c.solde);
printf("Date :%d-%d-%d
n",c.dateCreation.jour,
c.dateCreation.mois,c.dateCreation.ann
ee);
Numéro :2004001
Solde :550.78
Date :23-11-2017
Appuyez sur une touche pour
93.
• En C,on peut utiliser une structure de deux manières :
• en travaillant individuellement sur chacun de ses champs ; Chaque champ d’une
structure peut être manipulé comme n’importe quelle variable du type correspondant.
• en travaillant de manière globale sur l’ensemble de la structure (Affectation : c1 = c2):
• Lors de l’affectation, il y a une copie « champs à champs » des informations
de la structure source vers la structure destination
• Pas de comparaison c1==c2 ( il faut comparer chaque membre)
• Initialisations de structures
• il est possible d’initialiser explicitement une structure lors de sa déclaration.
• struct compte c1 = {12345,"Youness",2690.45,{11,10,2018}}
Utilisation d’une
structure
Prof. Y.BOUKOUCHI / AIAC 94
Les structures
94.
• La syntaxede déclaration d’un tableaux:
• struct nomStructure nomTableau [DIM _Max]
• typeStructure nomTableau [DIM_Max]
Tableaux de
structures
Les structures
printf("Numéro
printf("Nom
Prof. Y.BOUKOUCHI / AIAC
95
#define MAX_COMPTES 10
typedef struct { /* définition de la structure*/
int numero ;
char nom[50];
char
specialite[60];
}Prof;
Prof listProfs[MAX_COMPTES];
main(){
int i,nbrProfs=2; /* le nombre effectif des comptes*/
Prof prof1={201,"Youness BOUKOUCHI","Informatique"};
Prof prof2={220,"Asmae BOUJIBAR","Planétologie"};
listProfs[0]=prof1;
listProfs[1]=prof2;
for(i=0;i<nbrProfs;i++){
:
%
d
}
}
Numer
o
Nom
:201
:Youness
BOUKOUCHI
Sospecialite :Informatiq
ue Numero :220
Nom :Asmae
BOUJIBAR
Sospecialite :Planetologie
Appuyez sur une touche
95.
• L'adresse dedébut d'une structure s'obtient à l'aide de l'opérateur &
• Compte c1={3030,"Youness",800.75} ; // c1 est de type Compte
• Compte * pc; //pc est un pointeur sur une variable de type Compte
• pc = &c1; // pc reçois l’adresse de c1
• Quand la structure est un pointeur, on utilise l’operateur « -> » pour accéder aux
membres . L’écriture p->champs est synonyme de (*p).champs, où p est un pointeur sur
une structure
• printf("Numéro :%dn", pc->noCompte);
• printf("Nom
• printf("Solde
:%sn", pc->nom);
:%.2fn",
(*pc).solde);
• pc->noCompte=4040;
• strcpy(pc->nom,"Youness
BOUKOUCHI");
• pc->solde=15000.00;
Adresse d’une
structures
Prof. Y.BOUKOUCHI / AIAC 96
Les structures
typedef struct
{ int
noCompte ;
char
nom[80];
float solde;
} Compte;
96.
Transmission d’une structure
•Les membres d'une structure peuvent être passés comme paramètres à des fonctions avec
ou sans modification
Prof. Y.BOUKOUCHI / AIAC 97
Les structures
// sans modification=> passage par valeur
void verserCompte(float solde, float montant)
{ solde = solde + montant;
}
in
t
m
ai
n(
){
Compte c={30030,"Youness",0.00};
verserCompte(c.solde,1000);
printf("Solde :%.2fn",c.solde);
// Solde:0.00
// avec modification=> passage par adresse
void verserCompte(float *solde, float montant) {
* solde = * solde + montant;
}
int main(){
Compte c={30030,"Youness",0.00};
verserCompte(& c.solde,1000);
printf("Solde :%.2fn",c.solde);
// Solde:1000.00
}
97.
Transmission d’une structure
•Une structure peuvent être passés comme paramètres à des fonctions avec ou sans
modification
Prof. Y.BOUKOUCHI / AIAC 98
Les structures
// sans modification=> passage par valeur
void verserCompte(Compte cpt, float montant)
{ cpt.solde = cpt.solde + montant;
}
int main(){
Compte c={30030,"Youness",0.00};
verserCompte(c,1000);
printf("Solde :%.2fn",c.solde);
// Solde:0.00
}
// avec modification=> passage par adresse
void verserCompte(Compte*cpt, float montant)
{ cpt-> solde = cpt->solde + montant;
}
int main(){
Compte c={30030,"Youness",0.00};
verserCompte(& c,1000);
printf("Solde :%.2fn",c.solde);
// Solde:1000.00
}
98.
Transmission d’une structure
•La valeur de retour d'une fonction peut être une structure ou une adresse d’une
structure
Prof. Y.BOUKOUCHI / AIAC 99
Les structures
// type de retour => une structure
Compte verserCompte(Compte cpt, float montant)
{
cpt.solde = cpt.solde + montant;
return cpt;
}
int main(){
Compte c={30030,"Youness",0.00};
c=verserCompte(c,1000);
printf("Solde :%.2fn",c.solde);
// Solde:1000.00
}
// type de retour => une adresse
Compte * verserCompte(Compte cpt, float montant)
{
cpt.solde = cpt.solde + montant;
return &cpt;
}
int main(){
Compte c={30030,"Youness",0.00};
Compte *pc;
pc=verserCompte(c,1000);
printf("Solde :%.2fn",pc->solde);
// Solde:1000.00
}
Un fichier
• Dansun ordinateur, il y a deux sortes de mémoire : la mémoire centrale
et la mémoire disque.
• Les données stockées en mémoire centrale ne durent que le temps de
l’exécution d’un programme.
• Pour mémoriser des données de manière permanente, il faut les stocker
sur un disque (disque dur, clef USB, carte mémoire, etc.).
• Un fichier est une série de données stockées sur un disque ou dans un
périphérique de stockage.
• Un fichier texte est un fichier qui contient du texte ASCII. On peut visualiser le contenu
d’un fichier texte avec un éditeur de texte.
• Un fichier binaire contient du code binaire. On ne peut pas visualiser son contenu avec
un éditeur de texte.
Prof. Y.BOUKOUCHI / AIAC 101
Les fichiers
101.
• On appellelecture dans un fichier le transfert de
données du fichier vers la mémoire centrale.
• On appelle écriture dans un fichier le transfert de
données de la mémoire centrale vers le fichier.
• Pour pouvoir utiliser les fichiers, on doit inclure la
bibliothèque d’entrées-sorties : #include<stdio.h>
• Pour lire ou écrire dans un fichier, nous avons besoin
d’un pointeur de fichier qui permet de désigner le
fichier dans lequel nous souhaitons lire ou écrire.
• Un pointeur de fichier est de type FILE *.
• On déclare un tel pointeur comme toute autre variable :
FILE *fp; /* déclaration d’un pointeur de fichier fp */
Déclaration d’un
fichier
Prof. Y.BOUKOUCHI / AIAC 102
Les fichiers
Fichier
E
c L fprintf()
r e fread()
i c
t t
u u
r r
e e
Mémoire
Centrale (RAM)
fscanf()
fwrite()
102.
• fp =fopen("monfichier.txt" ou "monfichier.dat","r"); /* (exemple de chemin relatif : répertoire local) */
• fp = fopen("/home/remy/algo/monfichier.txt","w"); /* (exemple de chemin absolu sous Unix ou Linux) */
• fp = fopen("C:remyalgomonfichier.txt","a"); /* (exemple de chemin absolu sous Windows) */
• Pour fermer le fichier on utilise la fonction fclose qui prend en paramètre le
pointeur de fichier: fclose(fp);
Prof. Y.BOUKOUCHI / AIAC 103
Ouverture et fermeture d’un fichier
• il faut lier le pointeur de fichier à un fichier sur le disque. On appelle cette
opération l’ouverture du fichier.
• On utilise la fonction fopen qui a deux paramètres:
• Le premier paramètre est le nom du fichier, ou plus exactement le chemin vers le
fichier dans l’arborescence des répertoires.
• Le deuxième paramètre est le mode d’accès , exemple : r, w, a, etc.
• La fonction fopen retourne le pointeur NULL en cas d’erreur d’ouverture de
fichier.
• Exemple
Les fichiers
103.
Prof. Y.BOUKOUCHI /AIAC 104
Les différents modes
d’accès
Les fichiers
"r" ouverture d'un fichier en lecture
"w" ouverture d'un fichier en écriture
"a" ouverture d'un fichier en écriture à la fin
"r+" ouverture d'un fichier en lecture/écriture
"w+" ouverture d'un fichier en lecture/écriture
"a+" ouverture d'un fichier en lecture/écriture à la fin
"rb" ouverture d'un fichier binaire en lecture
"wb" ouverture d'un fichier binaire en écriture
"ab" ouverture d'un fichier binaire en écriture à la fin
"r+b" ouverture d'un fichier binaire en lecture/écriture
"w+b" ouverture d'un fichier binaire en lecture/écriture
"a+b" ouverture d'un fichier binaire en lecture/écriture à la fin
"rt" ouverture d'un fichier texte en lecture
"wt" ouverture d'un fichier texte en écriture
"at" ouverture d'un fichier texte en écriture à la fin
"r+t" ouverture d'un fichier texte en lecture/écriture
"w+t" ouverture d'un fichier texte en lecture/écriture
"a+t" ouverture d'un fichier texte en lecture/écriture à la fin
Ces modes d'accès ont pour
particularités :
• Si le mode contient la lettre r, le
fichier doit exister.
• Si le mode contient la lettre w, le
fichier peut ne pas exister. Dans
ce cas, il sera créé. Si le
fichier existe déjà, son
ancien contenu sera
perdu.
• Si le mode contient la lettre a, le
fichier peut ne pas exister. Dans
ce cas, il sera créé. Si le
fichier existe déjà, les
nouvelles données seront
ajoutées à la fin du fichier
précédent.
104.
Prof. Y.BOUKOUCHI /AIAC 105
Fichier Texte
Lire des données formatées:
• le fichier doit préalablement avoir été ouvert en mode "r", "r+", "w+", ou "a+".
• Pour lire des données numériques ou autres dans un fichier texte, on utilise la
fonction fscanf qui prend en paramètres:
1. le pointeur de fichier,
2. la chaîne de format avec des %d, %f,...
3. les adresses des variables avec des &
Les fichiers
fp format &varaiables
• La fonction fscanf retourne le nombre de variables effectivement lues, qui peut
être inférieur au nombre de variables dont la lecture est demandée en cas
d’erreur ou de fin de fichier.
• le format de fichier est la manière dont les données sont organisées dans un
fichier.
105.
Prof. Y.BOUKOUCHI /AIAC 106
Fichier Texte
Lire des données formatées:
• Exemple : Chargement d’un fichier
d’entiers en mémoire centrale
(dans un tableaux d’entier). On
suppose que dans un fichier texte
sont écrits
des nombres entiers séparés par des
espaces :
• 5 12 -66 87 -14 12 -etc.
Les fichiers
tableau[0] = 5
tableau[1] = 12
tableau[2] = -66
tableau[3] = 87
tableau[4] = -14
tableau[5] = 12
Appuyez sur une touche pour
#include <stdio.h>
#include <stdlib.h> /* pour utiliser la fonction exit */
#define NB_ELEM_MAX 100
int ChargeFichier(int tableau[NB_ELEM_MAX])
{ FILE *fp; int i=0;
fp = fopen("monfichier.txt", "rt"); /* ouverture du fichier : */
if (fp ==NULL) /* gestion d’erreur */
{ puts("Erreur d’ouverture de fichier :");
puts("Fichier inexistant ou permissions insuffisantes");
exit(1); /* termine le programme avec code d’erreur */
}
while (i < NB_ELEM_MAX && fscanf(fp, "%d", tableau[i])==1)
i++; /* incrémentation : pareil que i=i+1 */
fclose(fp); /* fermeture du fichier */
return i; /* on retourne le nombre d’éléments lus */
}
void Affiche(int tableau[], int n)
{ int i;
for (i=0 ; i<n ; i++)
printf("tableau[%d] = %dn", i, tableau[i]);
}
int main()
{ int tab[NB_ELEM_MAX]; int n; n = ChargeFichier(tab);
Affiche(tab, n); return 0; }
106.
Prof. Y.BOUKOUCHI /AIAC 107
Fichier Texte
Ecrire des données formatées:
• le fichier doit préalablement avoir été ouvert en mode "w", "a", "r+", "w+" ou
"a+".
• Pour écrire des données numériques ou autres dans un fichier texte, on utilise
la fonction fprintf qui prend en paramètres:
1. le pointeur de fichier,
2. la chaîne de format avec le texte à écrire et les %d, %f, etc.
3. Les variables à écrire séparées par des virgules.
Les fichiers
fp chaine variables
107.
Lire des donnéesformatées:
• Exemple : Voici un programme qui lit un
fichier texte contenant des nombres
entiers, et écrit un fichier texte
contenant les entiers triples (chaque
entier est multiplié par 3).
Fichier Texte
Les fichiers Prof. Y.BOUKOUCHI / AIAC
108
#include <stdio.h>
int TripleFichier()
{
FILE *fpr, *fpw; /* deux pointeurs pour deux fichiers */
int n; /* pour lire */
fpr = fopen("fichierLecture.txt", "rt");
fpw = fopen("fichierEcriture.txt", "wt");
if (fpr==NULL || fpw==NULL) /* gestion d’erreur */
return 1; /* code d’erreur retourné au main */
while (fscanf(fpr, "%d", &n)==1) /* lecture d’un entier */
fprintf(fpw, " [%d] ", 3*n); /* écriture du triple */
fclose(fpr); /* fermeture des deux fichiers */
fclose(fpw);
return 0; /* pas d’erreur */
}
int main()
{ int codeErr;
codeErr = TripleFichier(); /* on récupère le code
d’erreur */
if(codeErr != 0)
puts("Erreur d’ouverture de fichier !");
108.
Fichier binaire
Ecriture dansun fichier binaire
• La fonction fwrite possède quatre arguments :
1. l’adresse d’un bloc d’informations(variable);
2. la taille d’un bloc en octets;
3. le nombre de blocs de cette taille que l’on souhaite
transférer dans le fichier;
4. le fichier (fp).
• La fonction fwrite retourne le nombre de blocs
effectivement écrits.
• La fonction sizeof donne la taille de chaque
type (ou
bloc).
• Par exemple: sizeof(char) vaut 1, sizeof(float) vaut
4.
Les fichiers
&variable taille fichier
Prof. Y.BOUKOUCHI / AIAC
109
#include <stdio.h>
main(){
int n ;
FILE * fp ;
fp =
fopen
("monfic
hier.data"
, "w");
do {
printf("donnez un entier : ") ;
scanf("%d", &n) ;
if (n) // si n !=0
fwrite (&n, sizeof(int), 1, fp)
;
}while (n) ;
fclose (fp);
} donnez un entier : 5643
donnez un entier :
7654 donnez un entier
: 9879 donnez un
entier : 0
109.
Fichier binaire
Lecture dansun fichier binaire
• La fonction fread possède quatre arguments:
1. l’adresse d’un bloc d’informations(variable);
2. la taille d’un bloc, en octets;
3. le nombre de blocs;
4. le fichier (fp).
• La fonction fread retourne le nombre de blocs
effectivement lus.
• La fonction feof (fp) prend la valeur vrai (c’est-
à-
dire 1) lorsque la fin du fichier a été
rencontrée.
• feof est utilisée comme une condition d’arrêt de
la boucle de lecture
Les fichiers
&variable taille fichier
Prof. Y.BOUKOUCHI / AIAC
110
#include <stdio.h>
main(){
int n ;
FILE * fp ;
fp = fopen
("monfichier.data
", "r") ;
while( fread (&n,
sizeof(int), 1,
fp)&&! feof(fp))
printf ("%d
n", n) ;
fclose (fp);
}
5643
7654
9879
110.
Prof. Y.BOUKOUCHI /AIAC 111
Positionnement dans un fichier
• Il y a deux techniques de gestion de fichiers :
• l’accès séquentiel consiste à parcourir les informations séquentiellement;
• l’accès direct consiste à se placer directement sur l’information souhaitée.
• La fonction fseek permet de se positionner à un endroit précis dans un fichier;
• Lorsqu’on écrit sur un emplacement, la donnée qui existait éventuellement à cet
emplacement est effacée et remplacée par la donnée écrite.
• Le prototype de la fonction fseek permettant de se positionner est:
Les fichiers
int File*fp long offset int origine
• La fonction modifie la position du pointeur fichier fp d’un nombre d’octets égal à
offset à
partir de l’origine.
• L’origine peut être :
• SEEK_SET : on se positionne par rapport au début du fichier ;
• SEEK_END : on se positionne par rapport à la fin du fichier ;
111.
Prof. Y.BOUKOUCHI /AIAC
112
• La fonction modifieNombre prend un entier i en
paramètre permet à l’utilisateur de modifier
le (i+1)ème entier du fichier.
Positionnement dans un
fichier
Les fichiers
#include <stdio.h>
void modifieNombre(int i, FILE *fp)
{int n, nouveau;
fread(&n, sizeof(int), 1, fp); /* lecture */
printf("L’ancien entier vaut %dn", n);
puts("Veuillez entrer la nouvelle valeur");
scanf("%d", &nouveau);
fwrite(&nouveau, sizeof(int), 1, fp); /* écriture */
}
void remplirFichier(FILE * fp)
{ int n,p=0 ;
printf("Taper des entiers different de 0.n") ;
do { printf("Entier %d : ",p) ;
scanf("%d", &n) ;
p++;
if (n) // si n !=0
fwrite (&n,
sizeof(int), 1,
fp) ;
}
void afficherFichier(FILE * fp)
fseek(fp, i*sizeof(int), SEEK_SET); /* positionnement */ {
int n,p=0;
fseek(fp, 0, SEEK_SET); /* positionnement */
while( fread (&n, sizeof(int), 1, fp)&&! feof(fp))
{ printf ("Position %d = %dn",p, n) ;
p++; }
fseek(fp, -sizeof(int), SEEK_CUR); /* recul d’une case */ }
int main(void)
{ int p; FILE *
fp=NULL ;
fp = fopen ("fichierNombre.data", "w+b");
remplirFichier(fp);
puts("Veuillez entrer la position");
scanf("%d", &p);
modifieNombre(p,fp);
afficherFichier(fp);
return 0;
}
Taper des entiers different de
0.
Entier 0 :
10
Entier 1 :
2018
Entier 2 :
0
Veuillez entrer la
position
0
LÆancien entier vaut 10
Veuillez entrer la nouvelle
valeur
201
9
Position 0 =
2019
112.
• La fonctionlong ftell(FILE *fp) retourne la position courante dans le fichier (en
nombre d'octets depuis l'origine).
Prof. Y.BOUKOUCHI / AIAC 113
Positionnement dans un fichier
• La fonction int rewind(FILE *fp) permet de se positionner au début du fichier. Elle
est équivalente à fseek(fp, 0, SEEK_SET);
Les fichiers