Académique Documents
Professionnel Documents
Culture Documents
Contenu de cours
1
10/05/2021
Parmi ces directives, une seule est obligatoire pour le bon Exemples de programme en langage C
fonctionnement d’un programme : #include<stdio.h>. #include<stdio.h>
main(){
int i; /*déclaration des variables */
instruction_1;
instruction_2;
...
}
# include <stdio.h>
main (){
//Mon 1er programme en C
printf ("Bonjour tout le monde, c’est mon premier programme en langage C") ;
}
2
10/05/2021
3
10/05/2021
4
10/05/2021
ABCDEFGHIJKLMNOPQRSTUV";
x="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV ";
5
10/05/2021
6
10/05/2021
7
10/05/2021
8
10/05/2021
9
10/05/2021
10
10/05/2021
11
10/05/2021
12
10/05/2021
Exemples
Trouver le résultat retourné par le programme suivant : Trouver le résultat retourné par le programme suivant :
void main(void) void main(void)
{ char A=129; { char A=-129;
printf(" %d", A); printf(" %d", A);
} }
2 ; On a 129=128+1;
Sa représentation binaire est:10000001; donc,
127 ;
129 ; -127 ;
c’est un nombre négatif;
-127 ; CA2(0000001)2=(1111111)2 129 ;
Autre chose ; Après calcul, on trouve :(1111111)2=(127)10 Autre chose ;
Donc, la valeur exacte est: (10000001)2 =(-127)10
Remarque Importante: On a 256= 28 =(100000000)2; char sur 8bits, donc, on a
fuite d’information (perte des bits).
09/05/2021 Prof. ASIMI Younes 49 09/05/2021 Prof. ASIMI Younes 50
Exemples Exemples
Trouver le résultat retourné par le programme suivant : Trouver le résultat retourné par le programme suivant :
void main(void) void main(void)
{ char A=256; { char A=-260;
printf(" %d", A); printf(" %c", A);
} }
On a 260=256+4;
256 ; 4 ;
Sa représentation binaire est:100000100;
0 ; 252 ; Char sur un octet, donc, on va prendre la valeur
-128 ; 131 ; binaire: 00000100, fuite d’information;
127 ; 260 ; -260=CA2(260)10=(11111100)2
Après calcul, on trouve que le code ascci égale à:
(252)10
13
10/05/2021
Exemples Exemples
Trouver le résultat retourné par le programme suivant : Trouver le code ASCII du caractère retourné par le programme
void main(void) suivant :
{ char A=-260; void main(void)
printf(" %d", A); { char A=-20;
} printf(" %c", A);
-260 ; } Sa représentation binaire de 20 est:00010100;
-4 ; 20 ; Char sur un octet, donc, on va prendre la valeur
binaire: 00010100, sans fuite d’information;
4 ; 4 ;
-20=CA2(20)10=(11101100)2
260 ; 235 ; Après calcul, on trouve que le code ascci égale à:
236 ; (236)10
14
10/05/2021
15
10/05/2021
Ecrire un programme en langage C qui permet d’afficher les Ecrire un programme qui calcule la somme, le produit et la
dix premiers nombres impairs. moyenne de N nombres entiers positifs saisis au clavier.
16
10/05/2021
Ecrire un programme en langage C qui lit deux entiers Ecrire un programme en langage C qui permet de calculer et
entrés au clavier n et p (avec n<p) et permet d’afficher les d’afficher les sommes suivantes :
nombres de n à p, sauf les multiples de 3 et les multiples de 5.
S=1+3+5+7……+N. (Avec N est un nombre entier impair)
S=2+4+6………+N. (Avec N est un nombre entier pair)
S=1+22+32+…+N2.
S=1+1/2+1/3+……+1/N. (Avec N est un entier strictement
positif)
17
10/05/2021
Ecrire un programme qui calcule la moyenne de En C, un tableau est une structure de données composée d’un
quatre notes saisies au clavier; nombre fixe d’éléments de même type (élément homogène);
Les éléments d’un tableau sont indexés (Numérotés);
Evoluer cet exercice afin de réponde à la question de N
Un tableau est désigné par un identificateur unique ;
notes, avec N est le nombre des notes saisi au clavier;
Ce nombre devrait être déterminer lors de l’exécutions Chaque élément est repéré par un "indice" précisant sa position au sein
( N<=50) de l'ensemble;
Les éléments d’un tableau occupent dans la mémoire des zones
contiguës de même taille;
Le nombre des indices correspond à la dimension du tableau:
Pour un tableau simple on utilise un seul indice;
Tableaux Tableaux
18
10/05/2021
Tableaux Tableaux
Donc, pour affecter la valeur de 12 au huitième élément du
Remplir tous les éléments par la boucle for :
tableau, on écrit :
tab[2]=12 ;
int tab[3]; int i ;
for(i=0 ;i<=2 ;i++){
tab[2] est le troisième élément du tab .
tab[i]=i+1 ;
Il existe plusieurs façons de remplir un tableau : }
Affecter des valeurs aux éléments du tableau un par un: Remarques importantes :
tab[0]=10 ; tab[1]=40 ; tab[2]=0; int tab[3]={1,2,3,4} ;
Remplir tous les éléments du tableau au moment de la Retourne une erreur car le nombre des valeurs de remplissage
déclaration: est strictement supérieur à la taille du tableau (=3).
Un tableau tab de trois éléments : int tab[3]={1,2,3} ; ou int tab[3]={3,4} ;
int tab[3]={1,0,5}; Opération d’affectation correcte.
int tab[]={1,2,3,4,20, 5} ;
Déclaration et remplissage du tableau tab de taille 6.
La taille du tableau dépend du nombre d’éléments affectés au
tableau;
Remplir tous les éléments grâce à la boucle for et l’instruction Scanf :
int tab[3]; int i ;
for(i=0 ;i<=2 ;i++){
scanf ("%d", &tab[i]) ;
}
19
10/05/2021
Tableaux Tableaux
#include <stdio.h>
Ecrire un programme en C qui calcule la moyenne des notes et le #define NbNot 10
nombre des notes supérieures à la moyenne calculée. main() { int i, nb =0;
float note [NbNot ], som, moy ;
Ce programme devrait être structuré comme suite: printf ("donnez vos %d notes : ", NbNot ) ;
Déclare une constante nommée NbNot qui détermine la taille du for ( i = 0 ; i< NbNot ; i++)
tableau; scanf ("%f", ¬e[i]) ;
som = 0. ;
Déclare des variables ; for (i = 0 ; i< NbNot; i++)
Saisir les notes (10 par exemple); som = som + note[i] ;
moy = som / NbNot ;
Calculer la somme et la moyenne des notes; for (i = 0 ; i< NbNot; i++)
Calculer le nombre des notes supérieures à la moyenne; if (note[i] > moy)
Afficher la moyenne et le nombre des notes supérieures à la nb++ ;
printf ("moyenne = %f\n", moy) ;
moyenne;
printf ("il y a %d notes supérieures à cette moyenne", nb) ;
}
20
10/05/2021
Tableaux Caractères
Exécuter le programme suivant: 1ère adresse est:2293464 En langage C, char apparaît comme un cas particulier de int. Ce type
char permet de stocker des nombres signés compris entre -128 et 127, mais,
il est prévu pour stocker des lettres. Bien entendu, la mémoire ne peut
stocker que les nombres, d’où, il fallait faire une conversion entre les
nombres et les lettres.
Pour cet intérêt, on doit utiliser un traducteur des lettres en nombres.
Effectivement, c’est le rôle de la table de code ASCII étendu. Ainsi, pour
obtenir cette conversion, il suffit d'écrire cette lettre entre apostrophes.
char ch = 'A';=> stocke la valeur 65 dans la variable ch.
Pour afficher le caractère, on doit utiliser le symbole %c :
21
10/05/2021
Une chaîne de caractères n'est rien d'autre qu'un tableau de type Un tableau de caractères est en fait une chaîne de caractères. Son
char. Ce tableau devrait contenir un caractère spécial à la fin ‘\0’. remplissage peut se faire de plusieurs façons :
Chaine constante/ tableaux de caractères. : char p1[10]={’B’,’o’,’n’,’j’,’o’,’u’,’r’} ;
En C, une chaîne de n caractères occupe en mémoire un emplacement de char p2[10]="Bonjour" ; /* Remplissage par une chaîne
n+1 octets. Ainsi, pour stocker un mot de dix lettres, il fallait déclarer un littérale */
tableau de type char et de taille onze tab[11]. char p3[ ]="Bonjour" ; /* p3 aura alors 8 éléments */
Déclaration et initialisation:
Affichage à l'écran d’une chaîne de caractères:
char ch[20] = { 'b','o','n','j','o','u','r','\0' } ;
On peut utiliser la fonction printf et le format %s. Ici, il faut
22
10/05/2021
Remarque:
A l'issue de la saisie d'une chaîne de caractères, le
Adresse
Valeur fixe Valeur dynamique
23
10/05/2021
Pointeurs Pointeurs
Pointeurs Pointeurs
La déclaration d’un pointeur permet la réservation uniquement d’un
emplacement pour que ce pointeur pointe sur une variable de type
donné. Elle ne réserve pas en plus un emplacement pour stoker les
valeurs d’une variable.
Elle permet effectivement de réserver un emplacement
d’une adresse de type entier.
En générale, on distingue deux types d’adressage:
Adressage direct: Accès au contenu d'une variable par le nom
de la variable:
Exp : int A=12 ;
Adressage indirect: Accès au contenu d'une variable, en passant
par un pointeur qui contient l'adresse de la variable:
Déclaration : Int *P ;
Redimensionnement : p=&A ; // On dit : 'P pointe sur A'.
09/05/2021 Prof. ASIMI Younes 95 09/05/2021 Prof. ASIMI Younes 96
24
10/05/2021
Pointeurs Pointeurs
Opérateurs de base
Il existe deux opérateurs de base permettant de manipuler les
Un tableau statique est un tableau dont toutes les lignes ont même
nombre de colonnes (même taille). pointeurs:
opérateur d’adressage & : obtient l'adresse d'une variable.
Un tableau dynamique est un tableau dont les lignes n’ont pas
opérateur de contenu * : accède au contenu d'une adresse.
nécessairement même nombre de colonnes.
Pour une variable int nombre:
Un pointeur est une variable qui a pour valeur l’adresse d’une
autre variable. nombre permet d'accéder à la valeur de la variable ;
&nombre permet d'accéder à l'adresse de la variable.
Un pointeur est une variable qui fournit l'adresse d'une
information quelconque. Sur un pointeur int *pointeur:
pointeur permet d'accéder à la valeur du pointeur, c'est-à-dire à l'adresse
La taille d’un pointeur ne peut être connue que au moment
de la variable pointée ;
d’exécution; *pointeur permet d'accéder à la valeur de la variable pointée.
Les opérations ++ et -- s’appliquent aux pointeurs. &pointeur donne l’adresse du pointeur lui même;
09/05/2021 Prof. ASIMI Younes 97 09/05/2021 Prof. ASIMI Younes 98
Pointeurs Pointeurs
Opérateur d’indirection *
Avant de manipuler un pointeur, et notamment de lui appliquer l’opérateur Exemples des pointeurs
d’indirection *, il faut l’initialiser. Sinon, par défaut et en général, la valeur du char *pc; pc est un pointeur pointant sur un objet de type char.
pointeur est égale à une constante qui vaut 0.
int *pi; pi est un pointeur pointant sur un objet de type int.
L’opérateur *, mis en préfixe d’un nom de pointeur signifie : valeur de
la variable pointée ou, plus simplement, valeur pointée. float *pr; pr est un pointeur pointant sur un objet de type float.
L'opérateur * désigne en fait le contenu de l'adresse.
Remarques:
Exmple 1:
char *pc,i=34; Pour un pointeur pointant sur un objet de type char, la valeur de ce
pc = &i ;
pointeur donne l’adresse de l’octet où cet objet est stocké.
printf("la valeur de la variable pointée est : %d\n",*pc);
printf("le contenu du pointeur pc est : %d\n",pc); Par contre, pour un pointeur pointant sur un objet de type int, la
printf("l’adresse du pointeur pc est : %d\n",&pc);
valeur de ce pointeur donne l’adresse du premier octet des 4 octets
printf("l’adresse de la variable i est : %d\n",&i);
où l’objet est stocké.
25
10/05/2021
Pointeurs Pointeurs
Exemple
int a=1 ;
int *pt ; déclaration d’un pointeur sur un entier;
pt=&a ; pt pointe sur a ;
*pt=12 ; la variable pointée par pt reçoit 12;
printf("a=%d \n",a) ; affiche "a=12" .
Remarque importante :
Les deux variables *pt et a ont même valeur ainsi que la valeur de pt est
égale à l’adresse de &a.
Type *p ,*q ; p=q est équivalente à *p=*q et les variables p et q pointent
sur la même adresse.
Dans ces cas, on a initialisé un pointeur par l’affection d’une adresse
d’une autre variable.
09/05/2021 Prof. ASIMI Younes 101 09/05/2021 Prof. ASIMI Younes 102
Pointeurs Pointeurs
Opération sur les pointeurs
Supposant que j’ai déclaré un pointeur nommé P:
La valeur de P est celle de &P[0].
*P est équivalent à P[0].
P++ est équivalent à &P[1] . Elle donne l’adresse de l’élément suivant;
*P++ est équivalent à P[1]. Elle donne la valeur de l’élément suivant;
(*P)++ est équivalent à *P +1=P[0]+1.
P+i est équivalent à &P[i]. Elle donne l’adresse de l’élément d’indice i;
*(P+i) est équivalent à P[i] . Elle donne la valeur de l’élément d’indice i;
*P+i est équivalent à P[0]+i. Elle incrémente l’élément d’indice 0 par la
valeur i;
09/05/2021 Prof. ASIMI Younes 103 09/05/2021 Prof. ASIMI Younes 104
26
10/05/2021
Pointeurs Pointeurs
Opération sur les pointeurs Opération sur les pointeurs
On suppose que l’adresse du Tableau égale à 2293508 , trouvez les résultats
d’exécution du programme suivant:
Remarques:
ad1++ : représente l'adresse de ad1
augmentée de un sizeof(int),
effectivement, il pointe sur l’élément
suivant;
*(ad1++) : donne la valeur d’objet Remarques:
suivant; A++ ou bien *A++ expression invalide;
Dans ce cas, le pointeur devient un tableau
et vice-versa;
09/05/2021 Prof. ASIMI Younes 105 09/05/2021 Prof. ASIMI Younes 106
Pointeurs Pointeurs
09/05/2021 Prof. ASIMI Younes 107 09/05/2021 Prof. ASIMI Younes 108
27
10/05/2021
Pointeurs Pointeurs
Ecrire un programme qui :
déclare un tableau de type Int initialisé avec quatre valeurs:
Déclare un pointeur de type Int;
Initialise ce pointeur par l’adresse du 1 er élément de ce tableau.
Change le 2ème et le 3ème élément de ce tableau en utilisant le
pointeur;
Affiche les éléments du tableau en utilisant le pointeur.
09/05/2021 Prof. ASIMI Younes 109 09/05/2021 Prof. ASIMI Younes 110
09/05/2021 Prof. ASIMI Younes 111 09/05/2021 Prof. ASIMI Younes 112
28
10/05/2021
09/05/2021 Prof. ASIMI Younes 113 09/05/2021 Prof. ASIMI Younes 114
29
10/05/2021
09/05/2021 Prof. ASIMI Younes 117 09/05/2021 Prof. ASIMI Younes 118
30
10/05/2021
09/05/2021 Prof. ASIMI Younes 121 09/05/2021 Prof. ASIMI Younes 122
Processus Processus
Programme Mémoire Classes de mémorisation
31
10/05/2021
09/05/2021 Prof. ASIMI Younes 125 09/05/2021 Prof. ASIMI Younes 126
09/05/2021 Prof. ASIMI Younes 127 09/05/2021 Prof. ASIMI Younes 128
32
10/05/2021
09/05/2021 Prof. ASIMI Younes 129 09/05/2021 Prof. ASIMI Younes 130
33
10/05/2021
Ecrire un programme qui remplit les éléments d’un tableau de 4 pointeurs par
10*i+j, avec i et j indice de la ligne et de colonne respectivement;
09/05/2021 Prof. ASIMI Younes 135 09/05/2021 Prof. ASIMI Younes 136
34
10/05/2021
09/05/2021 Prof. ASIMI Younes 137 09/05/2021 Prof. ASIMI Younes 138
09/05/2021 Prof. ASIMI Younes 139 09/05/2021 Prof. ASIMI Younes 140
35
10/05/2021
09/05/2021 Prof. ASIMI Younes 141 09/05/2021 Prof. ASIMI Younes 142
09/05/2021 Prof. ASIMI Younes 143 09/05/2021 Prof. ASIMI Younes 144
36
10/05/2021
37
10/05/2021
09/05/2021 Prof. ASIMI Younes 149 09/05/2021 Prof. ASIMI Younes 150
09/05/2021 Prof. ASIMI Younes 151 09/05/2021 Prof. ASIMI Younes 152
38
10/05/2021
09/05/2021 Prof. ASIMI Younes 153 09/05/2021 Prof. ASIMI Younes 154
char chaine[100];
Version d’allocation dynamique :
09/05/2021 Prof. ASIMI Younes 155 09/05/2021 Prof. ASIMI Younes 156
39
10/05/2021
Tableau de pointeurs sur des chaines Tableau de pointeurs sur des chaines
Déclaration d’un tableau des pointeurs: Tableau de Tableaux Dynamiques ≡ Tableaux de chaînes de caractères:
char * jour[10] ; → 10 est le nombre d’adresses.
Déclaration et initialisation d’un tableau des pointeurs : L’adresse qui jour[0]
“Lundi”
char * jour[10] = { " Lundi", " ",… "", "" } ; 1ère ligne
pointe sur la jour[1] “Mardi”
Exercice : 1ère ligne
Écrire un programme qui affiche un jour de la semaine en se basant sur un jour[2]
“Mercredi”
numéro saisi au clavier entre 1 et 7.
#include <stdio.h>
int main()
{char * jour[7] = { "lundi", "mardi", "mercredi",
"jeudi","vendredi", "samedi", "dimanche" } ; 7 mots(jours) de longueur maximale
int i ; inconnue
printf ("donnez un entier entre 1 et 7 : ") ;
scanf ("%d", &i) ;
printf ("le jour numéro %d de la semaine est %s", i, jour[i-1] ) ;
jour[6] “Dimanche”
return 0;}
09/05/2021 Prof. ASIMI Younes 157 09/05/2021 Prof. ASIMI Younes 158
09/05/2021 Prof. ASIMI Younes 159 09/05/2021 Prof. ASIMI Younes 160
40
10/05/2021
41
10/05/2021
09/05/2021 Prof. ASIMI Younes 165 09/05/2021 Prof. ASIMI Younes 166
Fonctions Fonctions
Un programme en langage C est constitué d’un ensemble de fonctions toutes Déclaration d’une fonction avec arguments: Ou bien la définition de la
accessibles à partir d’une fonction principale appelée main(). signature d’une fonction:
Syntaxe :
Ces fonctions permettent d’exécuter, dans plusieurs parties du programme, Type nomFonction(type1, Type2,…,TypeN);
un ensemble d’instructions par un simple appel dans le corps du Ou bien :
programme principal. Void nomFonction(type1, Type2,…,TypeN);
La conception d’une fonction se fait en général par trois phases : Exemple :
Déclaration d’une fonction ou bien signature d’une fonction. int somme(int, int, int) ;
float racine(int ) ;
Définition de cette fonction. int prod(int *, char *) ;
Appel à cette fonction. void somme(int, int, int) ;
void racine(int ) ;
void prod(int *, char *) ;
09/05/2021 Prof. ASIMI Younes 167 09/05/2021 Prof. ASIMI Younes 168
42
10/05/2021
Fonctions Fonctions
Déclaration d’une fonction sans arguments:
Définition d’une fonction sans retourne:
Syntaxe :
Type nom_function(type1 arg1,...,typeN argN) {
Type nomFonction(); Ou bien Void nomFonction(); Déclaration des variables locales si nécessaire
Exemple : Instructions;
int som() ; float raci() ; void som() ; void raci() ; return 0 }
Définition d’une fonction avec retourne:
Remarque :
Type nom_function(type1 arg1,...,typeN argN) {
Le type void précise que la fonction ne renvoie (retourne) aucune valeur et Déclaration des variables locales si nécessaire
équivalent à return() ; ou return 0;. Autrement dit, il faut donc appeler la Les instructions;
fonction d’affichage « printf() » si on a besoin d’affichage. return (la sortie de cette fonction);
C’est mieux de définir et de déclarer une fonction à l’extérieur de la fonction }
principale main(). Remarque : le type de l'expression figurant dans return peut être différent du
L’appel d’une fonction se fait toujours à l’intérieur de la fonction principale type du résultat tel qu'il a été déclaré dans l'en-tête, ici, le compilateur se chargera
main(). automatiquement de l’opération de conversion.
09/05/2021 Prof. ASIMI Younes 169 09/05/2021 Prof. ASIMI Younes 170
Fonctions Fonctions
nom_function(arg1,...,argN);
Exemple :
Somme(a,b) ;
09/05/2021 Prof. ASIMI Younes 171 09/05/2021 Prof. ASIMI Younes 172
43
10/05/2021
Fonctions Fonctions
En C, on a deux méthodes pour déclarer, définir et appeler une Déclaration et définition de la fonction avant la fonction
fonction: principale main();
Exemple:
Déclaration et définition de la fonction avant la fonction
#include <stdio.h>
principale main();
int add(int x, int y){//Déclaration et définition d’une fonction
Déclaration au sein (ou avant) de la fonction principale, par int resultat = x + y;
contre, la définition de la fonction à ce moment doit être après la return resultat;
fonction principale main(); }
int main(){
L’appel d’une fonction est toujours à l’intérieur de la fonction
int a = 4;
principale main(); int b = 5;
int c = add(a,b); //appel d’une fonction
return 0;
}
09/05/2021 Prof. ASIMI Younes 173 09/05/2021 Prof. ASIMI Younes 174
Fonctions Fonctions
Déclaration au sein (ou avant) de la fonction principale, par contre, la Passage de paramètre par Valeur
définition de la fonction à ce moment doit être après la fonction principale main();
Exemple: Dans cette situation, la fonction ne peut pas modifier le contenu de la
variable recopiée. Effectivement, elle travaille sur une copie de la variable.
#include <stdio.h>
D’où, la modification de la copie n’entraîne pas une modification de la variable
int add(int , int ); //signature d’une fonction (porté globale)
originale.
int main(){
int add(int , int ); //signature d’une fonction (porté locale) Exemple:
int a = 4, int b = 5; #include <stdio.h> int main(){
int c = add(a,b); //appel d’une fonction int add(int x, int y){ int a = 4;
return 0;} int resultat = x + y;
int b = 5;
int add(int x, int y){//Définition d’une fonction int c = add(a,b);
return resultat; return 0;
int resultat = x + y;
} }
return resultat;}
09/05/2021 Prof. ASIMI Younes 175 09/05/2021 Prof. ASIMI Younes 176
44
10/05/2021
Fonctions Fonctions
09/05/2021 Prof. ASIMI Younes 177 09/05/2021 Prof. ASIMI Younes 178
Fonctions Fonctions
#include <stdio.h>
int add(int x, int y){
int a = 3;
int b = 7;
int c = a + b;
int resultat = x + y; int main(){
return resultat; int a = 4;
} int b = 5;
int c = add(a,b);
return 0;
}
09/05/2021 Prof. ASIMI Younes 179 09/05/2021 Prof. ASIMI Younes 180
45
10/05/2021
Fonctions Fonctions
Attention?? C n’autorise pas le non respect du type des arguments
lors d’un appel à une fonction: le compilateur n’opère pas alors une
conversion de type.
09/05/2021 Prof. ASIMI Younes 181 09/05/2021 Prof. ASIMI Younes 182
Fonctions Fonctions
Passage de paramètre par adresse
Pour modifier une variable par un appel de fonction, il faut passer en
paramètre une adresse (pointeur) qui pointe sur cette variable. Ainsi, on
travaille sur l’emplacement mémoire de la variable au lieu de son contenu.
Exemple: La fonction suivante prend en paramètre un pointeur :
#include <stdio.h>
void Modifie(int *p) {
*p = *p+1; →p pointe sur x, la copie de p aussi le x du main est modifie ;
}
int main(void) {int *p, x=1; → la variable x n’est pas un pointeur ;
p = &x; → pointeur qui pointe sur x ;
Modifie(p);
printf("%d", x); → affiche 2 ;
return 0;}
Le pointeur p et sa copie pointent tous les deux sur la variable x de la
fonction principale main.
09/05/2021 Prof. ASIMI Younes 183 09/05/2021 Prof. ASIMI Younes 184
46
10/05/2021
Fonctions Fonctions
Problème d'inversion
Le passage par valeur n’a aucun influence sur arguments effectifs
ainsi:
La fonction Inverser() reçoit deux valeurs correspondant à ses deux
arguments muets a et b.
Elle effectue un échange de ces deux valeurs. Mais, lorsque l'on est
revenu dans le programme principal, aucune trace de cet échange ne
subsiste sur les arguments effectifs a et b.
Exemple:
#include <stdio.h>
void Inverser(int a, int b){ int main(){
int tmp = a; int a = 1, b = 9;
a = b; Inverser(a,b);
b = tmp;} return 0;}
09/05/2021 Prof. ASIMI Younes 185 09/05/2021 Prof. ASIMI Younes 186
Fonctions Fonctions
Problème d'inversion Problème d'inversion
La solution est :???
Le passage par adresse qui s’influence sur arguments effectifs ainsi:
#include <stdio.h>
void inverser(int * a, int * b){
int tmp = * a;
* a = * b;
* b = tmp;
}
int main(){
int a = 1, int b = 9;
inverser(&a,&b);
return 0;
}
09/05/2021 Prof. ASIMI Younes 187 09/05/2021 Prof. ASIMI Younes 188
47
10/05/2021
09/05/2021 Prof. ASIMI Younes 189 09/05/2021 Prof. ASIMI Younes 190
09/05/2021 Prof. ASIMI Younes 191 09/05/2021 Prof. ASIMI Younes 192
48
10/05/2021
09/05/2021 Prof. ASIMI Younes 193 09/05/2021 Prof. ASIMI Younes 194
#include <stdio.h>
void ajouteTrois(int * a){
* a = * a + 3;
printf("dans ajouteTrois a: %d\n", * a);
}
int main(){
int a = 5;
ajouteTrois(&a);
printf("dans main a: %d\n",a);
return 0;
}
09/05/2021 Prof. ASIMI Younes 195 09/05/2021 Prof. ASIMI Younes 196
49
10/05/2021
09/05/2021 Prof. ASIMI Younes 197 09/05/2021 Prof. ASIMI Younes 198
Structures Structures
structure. Nom,
09/05/2021 Prof. ASIMI Younes 199 09/05/2021 Prof. ASIMI Younes 200
50
10/05/2021
Structures Structures
Définition d’une structure Définition d’une structure
Le langage C permet au programmeur de construire ses propres Exemple: un point d'un plan 2-D est caractérisé par ses
types de données. coordonnées x et y. Supposant que les coordonnées sont des
Pour cela, le programmeur doit préciser: entiers, la structure décrivant un point est déclarée en C par:
le nom donné au type; struct point{
la composition du type, c'est-à-dire le nom et la nature des int x;
données qu'il contient. int y;
La syntaxe de définition d'un type est: };
struct nom_structure{ Attention: le mot-clé struct fait partie intégrante du nom du
type1 var1; type.
type2 var2;
Le mot-clé struct introduit la déclaration de la structure, qui
...
}; est une liste de déclarations placées entre { et }
09/05/2021 Prof. ASIMI Younes 201 09/05/2021 Prof. ASIMI Younes 202
Structures Structures
Définition d’une structure Définition d’une structure
Le mot-clé « struct » peut être suivi d'un nom qu'on souhaite attribuer Voyez tout d'abord cette déclaration :
à la structure. Dans ce cas, nous désignons ce modèle défini : point. struct Produit
{ int numero ;
Ce nom sera utilisé par la suite pour se référer à la structure
int qte ;
(déclaration des variables de ce type). float prix ;
Les variables nommées dans la structure sont appelées les membres };
ou champs de la structure. Une fois un tel modèle défini, nous pouvons déclarer des "variables
structurées " du type correspondant:
La déclaration d'une structure définit un nouveau type.
struct Produit Pdt1 ;
« struct point » constitue le nouveau type ou bien le modèle sur Cette déclaration réserve un emplacement nommé Pdt1 "de type Produit "
lequel on va baser pour créer les variables structurées (objets) . destiné à contenir deux entiers et un flottant.
De manière semblable :
struct Produit Pdt1 , Pdt2;
Elle réserverait deux emplacements Pdt1 et Pdt2 du type Produit.
09/05/2021 Prof. ASIMI Younes 203 09/05/2021 Prof. ASIMI Younes 204
51
10/05/2021
Structures Structures
Définition d’une structure Définition d’une structure
Il est recommandé de regrouper la définition du modèle de structure et la scanf ("%f", &Pdt2.prix) ; → lit, suivant le code format %d, une valeur qui sera
déclaration du type des variables dans une seule instruction comme dans cet affectée au champ prix de la structure Pdt2.
exemple : Pdt1.numero++; → incrémente de 1 la valeur du champ numero de la structure
struct Produit{ int numero ; Pdt1.
int qte ; Il est possible d'affecter à une structure le contenu d'une structure définie à partir du
float prix ; même modèle:
} Pdt1 , Pdt2; Pdt1=Pdt2;
La désignation d'un champ se note en faisant suivre le nom de la Notez bien qu'une affectation globale n'est possible que si les structures ont été
variable structure de l'opérateur "point" (.) suivi du nom de champ tel définies avec le même nom de modèle:
qu'il a été défini dans le modèle: Pdt1.numero = Pdt2.numero ;
Pdt1.numero = 15 ; → affecte la valeur 15 au champ numero de la Pdt1.qte = Pdt2.qte ;
structure Pdt1. Pdt1.prix = Pdt2.prix ;
On peut initialiser notre structure Pdt1, au moment de sa déclaration :
printf ("%f", Pdt1.prix) ; → affiche, suivant le code format %d, la
struct Produit Pdt1 = { 100, 285, 2000 } ;
valeur du champ prix de la structure pdt1.
09/05/2021 Prof. ASIMI Younes 205 09/05/2021 Prof. ASIMI Younes 206
Structures Structures
Tableau des Structures Tableau des Structures
Tableaux de structures:
Lorsqu’on déclare un tableau des structures, effectivement, on crée un tableau
Voyez ces déclarations :
de N éléments structurés :
struct Produit Pdt[20]; struct point { char nom ;
Ici, nous avons créé 20 éléments structurés. Plus précisément, nous avons créer int x ;
20 adresses qui pointent sur 20 éléments structurés. int y ;
};
struct point courbe [50] ;
La structure point pourrait, par exemple, servir à représenter un point d'un
plan, point qui serait défini par son nom (caractère) et ses deux
coordonnées.
La notation : courbe[i].x
désigne la valeur du champ x de l'élément de rang i du tableau courbe.
Tableau des structures
09/05/2021 Prof. ASIMI Younes 207 09/05/2021 Prof. ASIMI Younes 208
52
10/05/2021
Structures Structures
Structures imbriquées Allocation dynamique des Structures
Par ailleurs : L’allocation dynamique de variables structurées est utile pour optimiser leur
courbe[4] taille en fonction de besoins qui ne sont souvent connus qu’à l’exécution:
typedef struct
→ représente la structure de type point correspondant au cinquième { char nom[20];
(adresse) élément du tableau courbe. char Prenom[20];
float note;
} Etudiant ;
Voici un exemple d'initialisation:
void main(void)
struct point courbe[50]= { {'A', 10, 25}, {'M', 12, 28},{'P', 18,2} } { Etudiant * ListeEtudiant ; /* pointeur pour le TABLEAU de structures */
int i, nb_etud = 0 ;
printf("Tapez le nombre d'étudiants :");
scanf("%d", &nb_etud );
09/05/2021 Prof. ASIMI Younes 209 09/05/2021 Prof. ASIMI Younes 210
Structures Structures
Allocation dynamique des Structures Déclarations
Allocation d'un tableau de structures : Différentes façons permettant de déclarer des variables d'une structure.
ListeEtudiant = (Etudiant *) malloc( nb_etud * sizeof(Etudiant ) );
struct point{
if (ListeEtudiant==NULL) int x; p1, p2, p3, p4, p5 sont des variables
{ int y;
globales initialisées automatiquement à
printf("\n Allocation dynamique impossible !"); } p1, p2, p3 ;
0.
exit(1) ; // on quitte le programme struct point p4, p5;
main(){ p1, p2, p3 ont été déclarées avec la
} struct point p6;
53
10/05/2021
Structures Structures
Déclarations Nouveaux types: typedef
struct {
int x; Le nom du nouveau type non Le langage C permet de créer de nouveaux types de données par
int y; spécifié. typedef.
} q1, q2; Chaque fois qu'on souhaite
main(){
La déclaration:
déclarer une nouvelle variable on
struct { typedef int nouveau_type;
int x; a besoin de réécrire le code de la
int y; structure. Donc nouveau_type constitue un synonyme de int.
} q3, q4, q5; q1 et q2 sont des variables
printf("%d %d\n",q1.x, q1.y);
Déclaration des variables du nouveau type (nouveau_type):
globales initialisées
printf("%d %d\n",q3.x, q3.y); nouveau_type len, maxlen; → variables simples de type int;
} automatiquement a 0.
q3, q4 et q5 sont des variables nouveau_type * tab[10]; → tableau de 10 pointeurs qui pointe
09/05/2021 Prof. ASIMI Younes 213 09/05/2021 Prof. ASIMI Younes 214
Structures Structures
Nouveaux types: typedef Nouveaux types: typedef
La déclaration : typedef int entier ; La structure point:
→signifie que entier est "synonyme" de int, de sorte que les déclarations typedef struct point POINT;
suivantes sont équivalentes :
. . .
int n, p ; entier n, p ;
POINT p1,p2; → déclaration de deux points;
De même :
typedef int * ptr ; POINT p3[10]; → tableau de 10 points;
→ signifie que ptr est synonyme de int *. Les déclarations suivantes sont POINT *p4; → pointeur sur un point;
équivalentes : p4 = malloc(10*sizeof(POINT)); → allocation de
int * p1, * p2 ; ptr p1, p2 ; l'espace mémoire pour 10 points;
La déclaration : typedef int vecteur [3] ;
→ les déclarations suivantes sont équivalentes :
int v[3], w[3] ; vecteur v, w ;
09/05/2021 Prof. ASIMI Younes 215 09/05/2021 Prof. ASIMI Younes 216
54
10/05/2021
Structures Structures
Nouveaux types: typedef Nouveaux types: typedef
Différentes façons de définir les nouveaux types: Différentes façons de définir les nouveaux types:
09/05/2021 Prof. ASIMI Younes 217 09/05/2021 Prof. ASIMI Younes 218
Structures Structures
Nouveaux types: typedef Initialisation et accès aux membres
Différentes façons de définir les nouveaux types: Les membres peuvent être initialisées au moment de la
déclaration de la variable de type structure.
typedef struct{ struct point pt1 = {20,30};
int x; Aucun nom n'a été attribue à struct point pt2={2,3}, pt3={-7,50};
int y; Les valeurs d'initialisation sont fournies entre { et }.
la structure.
} point;
main(){ L'affectation des initialisations suit l'ordre d'apparition des
point p, q = {3,-6};
Le type struct point n'existe champs dans la structure. La Nième valeur est affectée au
point * r; pas. champ introduit a la Nième position dans la définition de la
point s[20]; structure.
}
Exemple: dans struct point pt1 = {20,30};
x reçoit 20 et y reçoit 30.
09/05/2021 Prof. ASIMI Younes 219 09/05/2021 Prof. ASIMI Younes 220
55
10/05/2021
Structures Structures
Initialisation et accès aux membres Initialisation et accès aux membres
#include<stdio.h>
Accès aux champs s'effectue comme suit: struct point{
NomDeStructure.membre; int x;
int y;
Le point (.) permet de connecter le champ (variable membre) à la
};
structure dont il fait partie. int main(int argc, char* argv[]){
L'opérateur de sélection de membre qui se note peut être struct point a = {2,3}, b = {2};
une flèche -> si la variable structuré est un pointeur. struct point c = {}, d ;
printf("a = (%d,%d)\n", a.x, a.y);
NomDeStructure->membre; oub bien (*NomDeStructure).membre; printf("b = (%d,%d)\n", b.x, b.y);
Modfier les valeurs des champs des structures: printf("c = (%d,%d)\n", c.x, c.y);
pt1.x = -2; pt1.y = 0; printf("d = (%d,%d)\n", d.x, d.y);
return 0;
pt2.x = pt1.y; pt2.y = 2*pt1.x; }
09/05/2021 Prof. ASIMI Younes 221 09/05/2021 Prof. ASIMI Younes 222
Structures Structures
Structures imbriquées Structures imbriquées
Une structure peut être d'un type absolument quelconque : pointeur, La notation :
tableau, structure,... De même, un tableau peut être constitué d'éléments employe.heures[4]
qui sont eux-mêmes des structures. → désigne le cinquième élément du tableau heures de la structure
Structure comportant des tableaux: employe.
Soit la déclaration suivante : employe.nom[0]
struct personne { → représente le premier caractère du champ nom de la structure
char nom[30] ; employe.
char prenom [20] ; &courant.heures[4]
float heures [31] ; → représente l'adresse du cinquième élément du tableau heures de la
} employe, courant ; structure courant.
Elle réserve les emplacements pour deux structures nommées employe Voici un exemple d'initialisation d'une structure de type personne lors de
et courant. sa déclaration :
struct personne emp = { "Dupont", "Jules", { 8, 7, 8, 6, 8, 0, 0, 8} }
09/05/2021 Prof. ASIMI Younes 223 09/05/2021 Prof. ASIMI Younes 224
56
10/05/2021
Structures Structures
Structures imbriquées Organisation des champs
Exemple:
#define MAX 20
struct id {
Pas d’ambiguïté dans la
char firstname[MAX]; struct foo{
char lastname[MAX]; ligne struct id id; de la int a; Sortie:
};
struct Personne{
structure Personne: char b;
0xbfc98bb4
id est une variable membre
float c;
struct id id; 0xbfc98bb8
};
int age; le type de id est struct id; int main(int argc,char* argv[]){ 0xbfc98bbc
};
int main(){ struct foo f; 0xbfc98bb4
struct Personne p; printf("%p\n",&(f.a));
strcpy(p.id.firstname,“ASIMI"); printf("%p\n",&(f.b)); L'adresse d'une structure =
strcpy(p.id.lastname,“Younes"); printf("%p\n",&(f.c)); l'adresse de premier octet de
p.age=943;
return 0;
printf("%p\n",&f); son premier champ.
return 0;
}
}
09/05/2021 Prof. ASIMI Younes 225 09/05/2021 Prof. ASIMI Younes 226
Structures Structures
Exemple Complet Exemple Complet
Ecrire un programme en C qui déclare un modèle d’une structure void main(void)
nommée Etudiant contenant les champs suivants: { int n,m,i,j;
Nom: tableau de 20 éléments de type char; float *moy ;
Note : Pointeur sur N notes de type Float; printf("\n Choisir le nombre des etudiants : ");
Age: de type int ; scanf("%d",&n) ;
La signature de ce modèle est: Allocation dynamique des variables structurées:
struct Etudiant Etd=(struct Etudiant *) calloc(n, sizeof(struct Etudiant));
{ printf("\n Déterminer le nombre des notes de chaque etudiants : ");
char nom[20] ; scanf("%d",&m) ;
float *note ; Allocation dynamique des notes:
int age ; for (i = 0; i < n; i++){
}; Etd[i].note=(float *)calloc(m,sizeof(float));
Déclaration d’une variable structuré de type pointeur: }
struct Etudiant *Etd;
09/05/2021 Prof. ASIMI Younes 227 09/05/2021 Prof. ASIMI Younes 228
57
10/05/2021
Structures Structures
Exemple Complet Exemple Complet
Initialisation des champs: }
for (i = 0; i < n; i++){ moy[i]=SomNote/m;
printf("\n Nom et age de %d l'etudiant : ", i+1) ; }
scanf("%s%d", Etd[i].nom, &Etd[i].age ) ; Affichage du Nom, age et moyenne,:
printf("\n Donnez les %d notes de l'etudiant : ",m) ; for (i = 0; i < n; i++){
for (j = 0; j < m; j++){ printf("\n Nom de l'etudiant est %s : ",Etd[i].nom ) ;
scanf("%f", &Etd[i].note[j]) ; printf("\n Age de l'etudiant est %d: ", Etd[i].age) ;
}} printf("\n La moyenne de l'etudiant est %f: ",moy[i]) ;
Allocation dynamique de la moyenne }
moy=(float *)calloc(n,sizeof(float )) ; for (i = 0; i < n; i++){
Calcul de la moyenne free(Etd[i].note);
for (i =0; i < n; i++){ }
float SomNote=0; free(Etd);
for (j =0; j < m; j++){ free(moy);
SomNote+=Etd[i].note[j]; }
09/05/2021 Prof. ASIMI Younes 229 09/05/2021 Prof. ASIMI Younes 230
58
10/05/2021
10/05/2021 Prof. ASIMI Younes 233 10/05/2021 Prof. ASIMI Younes 234
59
10/05/2021
Contenu de cours
LISTE CHAINÉE
Une liste chaînée est une structure de données à l’intérieure de laquelle les objets
sont ordonnés de façon linéaire. À la différence d’un tableau, où l’ordre linéaire
est déterminé par les indices du tableau, l’ordre dans une liste chaînée est
déterminé par un pointeur dans chacun des objets.
Elle est constituée :
d'un champ de données ;
d'un pointeur vers la structure elle-même.
données
pointeur
La liste chaînée est accessible uniquement par sa tête de liste c’est-à-dire son
premier élément.
60