0% ont trouvé ce document utile (0 vote)
6 vues76 pages

Introduction à la programmation en C

Ce document présente un cours sur l'algorithmique et la programmation en C, abordant les concepts fondamentaux comme les structures de données, les pointeurs, et les procédures. Il décrit également l'historique et les avantages du langage C, ainsi que les outils nécessaires pour programmer, tels que les éditeurs de texte, compilateurs et environnements de développement intégrés. Enfin, il couvre des notions avancées comme les tableaux, les structures, et les énumérations.

Transféré par

alphayayaouattara0
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
6 vues76 pages

Introduction à la programmation en C

Ce document présente un cours sur l'algorithmique et la programmation en C, abordant les concepts fondamentaux comme les structures de données, les pointeurs, et les procédures. Il décrit également l'historique et les avantages du langage C, ainsi que les outils nécessaires pour programmer, tels que les éditeurs de texte, compilateurs et environnements de développement intégrés. Enfin, il couvre des notions avancées comme les tableaux, les structures, et les énumérations.

Transféré par

alphayayaouattara0
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Algorithme et programmation C

Dr Yannogo Hermann
Plan du cours

1. Généralités sur l’algorithmique et la programmation


2. Rappel sur les notions de basesStructures de données
3. Procédures et fonctions
4. Notions de pointeurs et allocation dynamique

Sommaire

▪ Objectifs de ce cours
 Comprendre les notions de bases en algorithmique et programmation
 Savoir écrire et écrire un algorithme et le traduire en langage C
 Maîtriser l’utilisation du langage C pour réaliser la mise en œuvre d’algorithmes et le

développement d’applications de petite taille


Présentation du langage C

▪ Historique
Date Description
1978  Création du langage C dans les laboratoires Bell par les chercheurs B. Kernighan et D.
Ritchie
1980  Invention du langage C++ par Bjarne Stroustrup (informaticien danois)

➢ Extension du langage C par la programmation Objet


1983  Création du langage Objective - C par Brad Crox

➢ Extension du langage C, pour la programmation objet

➢ Très utilisé par Apple pour la conception des interfaces graphiques de MacOS

1990  Normalisation du Langage C par la norme ANSI/ISO

➢ Normalisé par la norme ANSI/ISO (C99 ou Ansi C)


1998  Normalisation du Langage C++ par l’ANSI/ISO
Présentation du langage C

▪ Pourquoi choisir le langage C ?


 Sa popularité
➢ Un des langages de programmation les plus utilisés
➢ Il possède une communauté très importante et de nombreux tutoriels et documentations
➢ Il existe beaucoup de programmes et de bibliothèques développés en/et pour le C

20
Présentation du language C

▪ Pourquoi choisir le langage C ?


 Sa rapidité
➢ Connu pour être le langage très rapide
➢ Langage de choix pour tout programme où la vitesse d’exécution est cruciale
➢ Langage à cheval entre les langages haut niveau et bas niveau
 Sa légèreté
➢ Très utile pour les programmes embarqués où la mémoire disponible est faible
 Sa portabilité
➢ Un programme développé en C marche théoriquement sur n’importe quelle plate-
entation du langage C
forme
➢ Le C a été conçu pour la programmation système (pilotes, systèmes d'exploitation,
matériel embarqué, etc)

▪ Quels sont les outils nécessaires au programmeur ?


 3 éléments minimums sont nécessaires :
 Un éditeur de texte :
➢ Utile pour écrire le code source du programme
➢ Exemple : bloc-notes, notepad++, …
 Un compilateur:
➢ Transforme (ou compile) le code source en langage binaire
 Un debogueur:
➢ Très utile pour traquer les erreurs dans votre programme
 Il existe des environnements intégrant les trois éléments à la fois. On les appelle des IDE
(Environnement de Développement Intégré)

▪ Les environnements de développement intégré (EDI ou IDE)


 Visual C++
➢ IDE propriétaire de Microsoft
➢ Fonctionne uniquement sous Windows
➢ Version payante
➢ Il existe des versions gratuites : Visual C++ express (très complet)
 Eclispe CDT (C++ Development Tools)
 IDE gratuit et complet offrant des fonctionnalités facilitant la programmation
 Multiplateforme (Windows, Linux et Mac)

Présentation du langage C

▪ Les environnements de développement intégré (EDI ou IDE)


 Dev – C++
➢ IDE gratuit
 Code::Blocks
➢ IDE gratuit et disponible pour la plupart des systèmes d’exploitation
➢ Très simple d’utilisation et possède une complétion très riche

▪ Les compilateurs du C++


 Visual C++ build (Microsoft)
 Borland C++ builder
 Gratuit
 Utilisable sous Windows et linux
 GCC (GNU Compilation Collection)
➢ Excellent compilateur, gratuit et le plus utilisé
➢ Multiplateforme
➢ Compilateur multi-langage (C, C++, Java, …)
 Nous allons utiliser plutôt le GCC
 Code::blocks intègre tous les compilateurs
Les variables

▪ Type de variable
 Lorsqu’on déclare une variable, il faut préciser ce que l’on voudra mettre dedans c’est le
type

 Types numériques : entier (int en C), réel (double ou float en C)

 Type alphanumérique : caractère, chaine de caractères (char en C)

 Type booléen (valeurs logiques VRAI, FAUX)


Les variables

▪ Les variables en Langage C


 La déclaration d’une variable s’écrit

Type nomVariable;

Type nombreVariable = valeur;

 Attention

 Le langage C n’initialise pas les variables avec des valeurs par défaut

 Une variable non initialisée possède une valeur indéterminée

 Source de nombreux « bugs »


 Règle : toujours initialiser les variables

118
▪ Les variables en Langage C
 Le langage C est sensible à la casse (majuscule/minuscule)

 Exemple : somme # Somme

 Les espaces sont interdits dans les noms de variables

 A la place, on peut utiliser le caractère underscore « _ »

 Exemple : variable indiquant le nombre de vie d’un joueur : nombre_de_vie ou


nombreDeVie

 Vous n’avez pas le droit d’utiliser des accents (é, à,ê, etc.).

 Exemple : on ne peut pas ecrire « précaution » mais « precaution »

119
Les variables

▪ Les variables en Langage C


 Pour afficher le contenu d’une variable, on utilise la fonction « printf » et une commande
spécifique

 Exemple : code permettant d’afficher le nombre de vie d’un joueur :

printf("Il vous reste %d vies" , nombreDeVies);

 Ce « symbole spécial » est un '% suivi d'une lettre (dans mon exemple, la lettre 'd').
Cette lettre permet d'indiquer ce que l'on doit afficher. 'd' signifie que l'on souhaite
afficher un entier « int »

120
▪ Les variables en Langage C
 Il existe plusieurs autres possibilités, mais pour des raisons de simplicité on va se contenter
de retenir celles-ci
Format Type attendu
« %d » int
« %ld » long
« %f » Float, double

 Pour récupérer les informations saisies par l’utilisateur sur le clavier, on utilise la fonction
« scanf ». Pour ce faire, une fois l’information saisie, on va le récupérer et le stocker dans
une variable

double poids = 0;
scanf("%lf", &poids);

121
▪ Les variables en Langage C
 Exemple : Traduction en C de l’algorithme convertissant un nombre de secondes sous
forme d’heure, minutes et seconde

122
Les opérations de bases

▪ Les opérateurs mathématiques


 Il s’agit des opérations usuelles

 L’addition : +

 La soustraction : -

 La multiplication : *

 La division : /

 Le modulo : mod ( « % » en C)

▪ Les opérateurs relationnels (ou booléens)


 < (inférieur) , > (supérieur) , <= (inférieur ou égal) , >= (supérieur ou égal) , =(égal, en C,
on utilise ==) , <>(différent de – en C, on utilise !=)

123
Les opérations de bases

▪ Les opérateurs logiques


Types En C
Négation !
Et logique &&
Ou logique ||
▪ Autres opérations
 Incrémentation (++) et décrementation (--)

➢ Elle consiste respectivement à incrémenter (et décrementer) la valeur d’une variable de 1

 Affectation avec opération


➢ Addition: +=, ex : a += b  a = a + b
➢ Soustraction: -=, ex : a -= b  a = a – b
➢ Multiplication: *=, ex : a *= b  a = a * b
➢ Division: /=, ex : a /= b  a = a / b

124
Structures de contrôle et boucles

▪ Structure de contrôles
 Les structures conditionnelles ou alternatives permettent de réaliser des opérations en
fonction d'une condition. On distingue :

 Les conditions simples

 Conditions à choix multiple

 Conditions simples : si … sinon … finsi

125
Structures de contrôle et boucles

▪ Structure de contrôles
 Conditions à choix multiple : selon que .. Autrement … finselonque

43

 En langage C :

126
Structures de contrôle et boucles

▪ Les boucles
 Elles permettent de répéter une opération autant de fois que nécessaire;

 On distingue 3 types de boucles :

 La boucle « pour »

 Elle est employée quand on connait a priori le nombre d’itération à effectuer


 Notation LDA En langage C

127
Structures de contrôle et boucles

▪ Les boucles
 Elles permettent de répéter une opération autant de fois que nécessaire;

 On distingue 3 types de boucles :

 La boucle « tant … que »

 Utilisée quand on connait pas le nombre d’opération à effectuer


 Notation LDA En langage C

128
▪ Jusqu’ici, nous avons travaillé les variables

➢ Rappel : une variable ne permet de stocker qu’une seule et unique valeur


▪ Que se passe t-il si on devait stocker plusieurs valeurs du même type? Et de types différents ?
▪ Dans ce chapitre, nous verrons particulièrement deux types de variables permettant de
stocker plusieurs valeurs :

 Les tableaux

 Les types structurés

➢ La définition de ces types est dépendante du langage

➢ En particulier, en C, nous verrons principalement:

➢ Les structures

129
▪ Définition
 Un tableau (encore appelé table ou variable indicée) est un ensemble de données, qui sont
toutes de même type, désigné par un identificateur unique (le nom du tableau), et qui se
distinguent les une des autres par leur numéro d’indice

 L’accès à un élément du tableau se fait grâce son indice

 Attention : l’écriture de Température[-2] ou Température[12] n’ont pas de sens car elles

130
Tableaux

▪ Déclaration de tableau
 Trois éléments définissent un tableau:

➢ Son nom : identificateur respectant les règles classiques des identificateurs d’un
programme

➢ Le nombre de ses éléments

➢ Le type de données qu’il contient


 Un tableau à plusieurs dimensions est un tableau pour lequel l’accès à un élément se fait en
utilisant plusieurs indices

131
Tableaux en C

▪ Déclaration

Type nomTableau [taille1]…[taillek] ;

 Attention : La taille du tableau (ou nombre de cases) est forcément fournie à la déclaration

 Exemple :
int tab[1000] ; // Déclaration d’un tableau d’entiers de 1000 éléments
float notes[40][10];

 Déclaration d’un tableau initialisé

Type nomTableau[] = {valeur1, valeur2,…,valeurN} ;

 La taille est déduite du nombre de valeurs fournies

132
 Exemple :
// Déclaration d’un tableau de 4 éléments initialisés
int tab[] = {10, 11, -1, 5} ; // tableau variable 54

▪ Parcours d’un tableau


 Le parcours d’un tableau se fait grâce aux indices variant entre 0 et la taille (du tableau) - 1

 Exemple : cas de la température

133
Les structures

▪ Généralités
 Le type tableau est une structure composée de plusieurs éléments de même type
 Supposons que l’on souhaiter travailler sur un fichier de personnes et on voudrait
regrouper une variable de type « chaine de caractères » pour le nom, une variable de type
« entier » pour le numéro d’employé, …
 Impossible d’utiliser un tableau car ne contenant qu’un seul type de données
 Pour regrouper les informations de différents types, un autre structure composée appelée
type structuré(ou enregistrement ou struture) est recommandé

134
▪ Déclaration d’une structure en C
 La déclaration se fait comme suit :

struct nomStructure

type1 nomChamp1;
type2 nomChamp2;

typen nomChampn;
};

 Chaque élément déclaré à l’intérieur de la structure est appelé un champ


 Attention : on a fait que déclarer un type de structure, pas une variable. Pour
déclarer une variable du type « nomStructure », on procède comme suit :

struct nomStructure A, B ;

135
Les structures

▪ Déclaration d’une structure en C


 Exemple : Nous souhaitons écrire une structure « Adresse » permet de gérer des adresses
postales. Les champs d’une adresse sont :
 Un numéro de porte (int)
 Le nom de la rue (char)
 Le numéro du secteur (char)

struct Adresse

int numero ;
char rue[50] ;
int secteur ;
};

 Pour déclarer des variables de type « Adresse », on procède ainsi :


 struct adresse chezFati, chezSogotele

136
Les structures

▪ Déclaration d’une structure en C


 Remarque : Il est possible de combiner la déclaration de la structure et celle des variables
associées comme suit

struct Adresse

int numero ;
char rue[50] ;
int secteur ;
} chezFati, chezSogotele ;

137
▪ Accès au champs d’une structure en C
 Pour accéder aux données contenues dans les champs d’une structure, on fait suivre le
nom de la structure par un point "." et le nom du champ voulu :

[Link]=19 ;
printf(“%s”,[Link]);

 On peut initialiser une structure lors de sa déclaration :

struct Adresse chezFati= { 15 , "rue M. Yaméogo", 8 } ;

▪ Affectation
 Si deux variables sont de même structure alors on peut effectuer une affectation:
➢ chezJean = chezFati ; /* Jean a emménagé chez Fati ! */
 Attention : on ne peut pas comparer 2 variables de même structure (avec == ou !=).

138
Les structures

▪ Structure de structure en C
 On peut utiliser une structure comme champ d’une autre structure.
 Dans la lignée des exemples précédents, on peut définir une structure adresse qui pourrait
être utilisée dans la structure repertoire ou toute autre structure.

struct adresse {
int numero ;
char rue[50] ;
int secteur;
};
struct repertoire {
char nom[20] ;
char prenom[20] ;
struct adresse maison ;
};

139
▪ Tableau de structure en C
 La déclaration et l’utilisation d’un tableau de structure en C se fait de la même façon qu’un
tableau de variables simples. Le nombre d’éléments est précisé entre crochets.

struct adresse pers[100] ;


 Cette déclaration nécessite que la structure adresse ait déjà été déclarée avant.
 « pers » est alors un tableau dont chaque élément est de structure de type adresse.
 « pers[i].rue » fait référence au champ « rue » du ième élément du tableau « pers ».

140
Les énumérations

▪ Déclaration
 Un type énuméré est un type simple correspondant à une liste de valeurs symboliques (i.e.
des noms). Une variable de ce type ne peut prendre sa valeur que parmi ces symboles.
 Pour déclarer un type énuméré, on utilise le mot-clé « enum », suivi de la liste de symboles
séparés par des virgules :
 Chaque valeur est en réalité associée à une valeur entière dont le premier champ prend la
valeur 0 et les autres champs s’incrementent de 1
 Pour déclarer une variable de ce type

64
enum nom_du_type

valeur_1,
valeur_2,

};

enum nom_du_type nomVariable = valeur_i ;


141
 Exemple : on souhaiterait gérer les mois de l’année
enum Jour

};

 Pour déclarer une variable enum Mois x = JANVIER


 Remarque : Il est possible de spécifier une valeur (entière) à l’un des champs
enum Mois

};

142
▪ Utilités
 Nous avons vu que pour déclarer une structure (car de l’« Adresse »), on utilise la syntaxe :
struct adresse

int numero ;
char rue[50] ;
int secteur;
};

 La déclaration des variables se fait : struct Adresse ChezFati


 Si l’on déclare cette structure en utilisant le mot clé « typedef » comme suit :
typedef struct adresse

int numero ;
char rue[50] ;
int secteur;
};

 Alors la déclaration d’une variable de type « Adresse » se fera sans l’utilisation de « struct »
 Le mot clé « typedef » permet d’éviter la répétition « struct » lors de la déclaration d’une
variable. Cela est valable pour tous les types structurés

143
Les Procédures et les fonctions

▪ Définition et utilité
 Les procédures et fonctions permettent de décomposer un programme complexe en
plusieurs parties plus simple et relativement indépendantes (aussi appelées sous-
programmes)

 Les avantages:

☺ Elles peuvent implémentées et testées séparément

☺ Si le même traitement est nécessaire en plusieurs point du programme, on se contente


d’appeler la fonction (ou procédure) correspondante plusieurs fois au lieu de
dupliquer le code source ;

☺ Une même fonction (ou procédure) peut être utilisée dans plusieurs programmes
différents, grâce au concept de bibliothèque

 Les aspects les plus importantes des fonctions et procédures sont leur création et leur

144
Les Procédures et les fonctions

▪ Fonctionnement d’un programme


 Un programme (ou algorithme) peut être composé d’un ou plusieurs sous-programmes
(exécutant des taches bien définies)
 Un sous-programme est obligatoirement caractérisé par un nom (un identifiant) unique

145
▪ Environnement d’un sous-programme
 Un sous-programme est caractérisé par 3 types de variables :

 Les variables globales : elles sont définies dans le programme appelant et ont donc
une portée globale

 Les variables locales : Elles sont définies à l’intérieur du sous-programme et ne sont


pas accessible en dehors du sous-programme. Leur portée est locale

 Les variables formels : Il s’agit des variables d’entrées servant d’échanges entre les
programmes appelant et appelé

146
Les procédures

▪ Définition
 Une procédure est un sous-programme représentant une ou plusieurs actions, et ne
retournant aucune valeur, sauf en paramètre.

 Déclaration

72
147
3.3 Les fonctions

▪ Définition
 Une fonction est un sous-programme à l’image d’une procédure mais qui retourne des
valeurs

 Déclaration

74
148
Appel de fonction (ou procédure)

▪ Méthodologie
 Pour utiliser une fonction (ou procédure), on fait un appel en lui passant des expressions
correspondant aux paramètres dont elle a besoin

 La syntaxe est la suivante :

nomFonction( param1, param2, …, paramk) ;

 Exemple : Appel des procédure et fonction défini précédemment

Age( 1901)

X  Maximum(45, 1)

 Remarque : lors de l’appel d’une fonction (ou procédure), un paramètre formel (ou
argument) d’une fonction (ou procédure) peut être une variable ou une valeur mais doit

149
Appel de fonction (ou procédure)

▪ Remarque
 Une fonction (ou procédure) avant d’être appelée doit être préalablement définie (et
implémentée)

 Etant donnée qu’une fonction retourne une valeur, il est possible d’affecter cette valeur à
une variable ou peut être utilisée dans une autre fonction ou expression

77

Passage des paramètres

▪ Il existe principalement 3 modes de passages des paramètres

 Le passage par valeur


 Le passage par adresse
 Le passage par référence
 On s’interessera uniquement aux 2 modes (les seuls modes utilisés en C)
150
Passage des paramètres

▪ Passage par valeur


 Lorsque les paramètres formels sont transmis à une procédure (ou fonction) en mode
passage par valeur alors toute modification de ces paramètres dans la procédure ne sont
sans effet dans le programme appelant.

 Le programme appelant garde les mêmes valeurs des paramètres avant et après appel de la
procédure. Pour déclarer ces paramètres, on parle de « Données »

 Exemple

151
Passage des paramètres

▪ Passage par adresse


 Pour ce mode de passage, toute modification de ces paramètres dans la procédure (ou
fonction) aura un effet dans le programme appelant.

 En LDA, les paramètres en mode passage par adresse sont appelés « Données
Modifiées ». En langage C, ces paramètres sont des pointeurs

152
Fonction
ions et procédures en C
▪ Syntaxe de déclaration

Type nomFonction( Type idParam1, Type idParam2, …, Type idParamN )


{

 Le type de retour d’une procédure est un « void »


 Pour une fonction, le type de retour peut être un entier (int), un réel (float), …
 Dans le corps d’une fonction, on doit avoir obligatoirement l’instruction « return »
permettant de renvoyer le résultat attendu de la fonction

153
Fonctions et procédures en C

▪ Exemple
 Reprenons les exemples précédent

void Age (int annee_naissance)

int age; int main ()


age = 2020 – annee_naissance
printf(‘vous avez %d ans’, age) int maxi;
if( a >
maxi = a;
int Maximum (int a, int b)
else{
int maxi; maxi = b;
if( a > b){
maxi = a; return maxi;
else{
maxi = b;

return maxi;
154
82
Fonctions récursives

▪ Définition
 On appelle fonction récursive toute fonction qui s’appelle elle-même

 Elle permet de coder des fonctions (mathématiques) définie à partir de relation de


récurrence

 Exemple : calcul du factoriel d’un nombre entier


o 1ère définition

• n! = 1 * 2 * 3 * 4 * … * n

• Traduction par une boucle :

o 2ème définition:

155
Fonctions récursives

▪ Définition
 Exemple : calcul du factoriel d’un nombre entier

156
Fonctions récursives

▪ Définition
 Dérouler cet algorithme pour factoriel(5)

3.7 Exercices

157
Notions de pointeurs et allocation dynamique

158
Généralités
▪ Un des chapitres les plus importants du langage C/C++
 Le cœur du langage C/C++
▪ Les pointeurs sont totalement indispensables car on s'en sert tout le temps
▪ Nous verrons des cas de problèmes qu’on ne pourra pas résoudre sans utiliser de pointeurs
▪ La notion de pointeurs est intrinsèquement liée à la notion de mémoire

159
Notion d’adressage mémoire

▪ Mémoire vive d’un ordinateur (Rappel)


➢ Schéma
▪ La mémoire vive contient 2 éléments (en colonne)
▪ les adresses : une adresse est un nombre qui permet à
l'ordinateur de se repérer dans la mémoire vive
➢ Commence à l'adresse 0 (au tout début de la mémoire)
➢ Plus vous avez de mémoire vive, plus il y a d'adresses,
▪ Les valeurs : à chaque adresse, on peut stocker une valeur (un
nombre) : votre ordinateur stocke dans la mémoire vive des
nombres pour pouvoir s'en souvenir par la suite.
▪ On ne peut stocker qu'un nombre par adresse !

160
Notion d’adressage mémoire

▪ Exemple
 Exemple

int main() /* Plus petit programme C/C++. */


{
int ageUtilisateur = 16;
return 0;
}

1 2 3 4 5 …

14562 14563 14564 14564 14565 … ageUtilisateur


16
53567 53568 53569 53570 53571 …

… … … … … …
… … … … … …
… … … … … …

 Notre programme utilise une seule de ces cases, la 14562, pour y stocker sa variable.
 Jusqu’à présent, la manipulation de la « 16 » était possible grâce à la variable « ageUtilisateur »

161
Notion d’adressage mémoire
▪ Chaque variable possède une seule adresse et que chaque adresse correspond à une seule
variable.
 L'adresse est donc un deuxième moyen d'accéder à une variable.
▪ On peut atteindre la case rose (la valeur 16) du schéma par deux chemins différents :
 Le nom de la variable
 Dans l’exemple, il s’agit de ageUtilisateur
 L’adresse de la variable i.e son numéro de case
➢ l’adresse 14562
 D’où la notion de pointeur

162
Notion de pointeurs

▪ Définition
 Un pointeur est une variable qui contient l'adresse d'une autre variable.
➢ L'adresse contenue dans un pointeur est celle d'une variable qu'on appelle variable
pointée.
➢ On dit que le pointeur pointe sur la variable dont il contient l'adresse.
➢ Un pointeur est associé à un type de variable sur lequel il pointe. Par exemple, un
pointeur sur entier ne peut pointer que sur des variables entières.

163
Notion de pointeurs

▪ Déclaration
 Il faut déclarer le type de la variable pointée.
 Par convention, les variables pointeurs commencent par la lettre p.
 Syntaxe (langage C) :

Type * nom_pointeur

 Exemple :

int * p_toto

 Note : * est appelé opérateur de déréférencement

164
Notion de pointeurs

▪ Exemple

{
// Pointeur sur un entier
int * ptr_int ;
// Deux pointeurs sur des réels
float * ptr_int1, * ptr_int2 ;
// Pointeur vers une instance de vecteur
}
 Attention : un pointeur est une variable de type élémentaire. Sa valeur n’est donc pas
initialisée par défaut (source de très nombreux bugs).
 Il faut toujours initialiser un pointeur

165
Notion de pointeurs

▪ Initialisation
▪ Pointeur ne pointant sur rien : NULL
{
// Un pointeur ne pointant sur
rien
Type * ptr_variable = NULL ;
}

▪ Initialisation à partir de l’adresse d’une variable


➢ Utilisation de l’opérateur & : renvoi l’adresse d’une variable

{
// Déclaration d’une variable
Type var ;
// Initialisation d’un pointeur par l’adresse d’une variable
Type * ptr_identifiant = & var ;
}

166
Notion de pointeurs

▪ Exemple

{ int i = 15
// Déclaration d’une variable de type entier (int)
int i = 15 ;
// Déclaration et initialisation de deux pointeurs
int * int *
// sur cette variable de type entier (int) ptr1_i ptr2_i
int * ptr1_i(&i) ;
int * ptr2_i = &i ;
}

167
Notion de pointeurs

▪ Déréférencement ou indirection
 Déréférencer un pointeur consiste à extraire la valeur de la variable sur laquelle il pointe.
 Utilisation de l’opérateur * : récupération de la valeur pointée
 Soit ptr un pointeur
 La valeur pointée est accessible (lecture/écriture) via l’expression *ptr
▪ Exemple

{
// Variable de type entier
int a = 10 ;
// Pointeur sur cette variable
int * ptr_a(&a) ;
// Déclaration d’une seconde variable
int b = *ptr_a ; // b vaut 10 (initialisé à partir de la valeur de a, pointée par ptr_a)
// Changement de la valeur de a, pointée par ptr_a
(*ptr_a) = 5 ; // a vaut 5
// Incrementation de la valeur de a, pointée par ptr_a
(*ptr_a)++ ; // a vaut 6
}
98

168
Notion de pointeurs

▪ Syntaxe algorithmique

Syntaxe C/C++
syntaxe algorithmique
int n = 33;
Variables
int *p; //déclaration du pointeur p
n: entier
p = &n; // p pointe sur n
p: pointeur sur entier
Début
cout << *p //affiche 33 à l'écran, la valeur
p ← @n // adresse de n p pointe sur n
de n
afficher *p // affichée
*p ← 34 // n vaut maintenant 34
*p = 34 // n vaut maintenant 34

169
Pointeurs et structures de données

▪ Pointeur et tableau
 Déclaration d’un tableau à une dimension
Type tab[NB] ;

➢ Le nom d'un tableau représente l'adresse de son premier élément.


➢ En d'autre termes: &tab[0] et tab sont une seule et même adresse.
 Déclaration d’un pointeur vers le premier élément

Type * p_tab =&tab[0] ;

➢ ou

Type * p_tab = tab ;

 Il existe une arithmétique sur les pointeurs

100

170
Pointeurs et structures de données

▪ Pointeur et tableau
▪ Arithmétique sur les pointeurs
 Relation 1 : *(p_tab + i)  tab[i]

0 1 2 i … NB -1
p_tab …

p_tab+1

p_tab+i tab

 Relation 2 : tab  &tab[0]


 Relation 3 : tab[i]  *(tab+i)  *(p_tab+i)  p_tab[i]

171
Pointeurs et structures de données

▪ Pointeur et tableau
 Cas d’un tableau à deux dimensions
➢ Un tableau à 2 dimensions est un tableau dont les éléments sont eux-mêmes des
tableaux
➢ Ainsi, le tableau défini par int tab[4][5] ; contient 4 tableaux de 5 entiers chacun.
➢ tab donne l’adresse du 1er sous-tableau,
➢ tab+1 celle du 2ème sous-tableau et ainsi de suite :

172
Pointeurs et structures de données

▪ Pointeur et chaines de caractères


 De la même façon qu'un pointeur sur « int » peut contenir l'adresse d'un nombre isolé ou
d'un élément d'un tableau, un pointeur sur un « char » peut pointer sur un caractère isolé
ou sur les éléments d'un tableau de caractères.
 Un chaîne de caractères est représentée en langage C par un tableau de caractères.
 Exemple d’initialisation
char *c;
c = "Salut !";

173
Pointeurs et structures de données

▪ Pointeur et chaines de caractères


 Attention : Il existe une différence importante entre les deux déclarations:

char T[] = "Salut !"; un tableau

char *C = "Salut !"; /* un pointeur */

➢ T est un tableau qui a exactement la grandeur pour contenir la chaîne de caractères et la


terminaison '\0'. Les caractères de la chaîne peuvent être changés, mais le nom T va toujours
pointer sur la même adresse en mémoire.
➢ C est un pointeur qui est initialisé de façon à ce qu'il pointe sur une chaîne de caractères
constante stockée quelque part en mémoire. Le pointeur peut être modifié et pointer sur autre
chose. La chaîne constante peut être lue, copiée ou affichée, mais pas modifiée.

174
Pointeurs et structures de données

▪ Pointeur et structure
▪ Supposons que l’on ait défini la structure « struct personne » à l’aide de la déclaration :

struct personne {
char nom[60] ;
char prenom[60]
int age ;
int secteur;
};

 On déclarera une variable de type pointeur vers la structure « personne » de la manière

 On pourra alors affecter à « p » des adresses de « struct personn


 e»

struct personne pers = {"sanou", "sogotèlè", 15, 27}; 105

175
Pointeurs et structures de données

▪ Accès aux éléments d’une structure pointée


 Pour accéder aux éléments d’un pointeur de structure, on peut utiliser 2 méthodes:
 Méthode du déréférencement

(* p).champ1;

 Utilisation de l’opérateur « → »

p →champ1

 Exemple
struct personne {

};

struct personne pers = {"sanou", "sogotèlè", 15, 27};

106
printf("nom : %s\nprésom : %s", (*p).nom, p->prenom)

176
Allocation dynamique

▪ Définition
 L'allocation dynamique de mémoire permet à un programme en cours d‘exécution de
réserver un espace mémoire dont la taille n'est pas nécessairement connue lors de la
compilation.
 Cette allocation de la mémoire gérée manuellement
 La libération de la mémoire gérée manuellement
 Attention : Responsabilité du programmeur
 Règle : tout objet créé dynamiquement doit être désalloué
 L'allocation dynamique est réalisée par les fonctions « malloc() » et « calloc () ».
 Quant à la libération de la mémoire, on utilise la fonction « free() »

177
Allocation dynamique

▪ Fonction « Malloc(…) »
 Cette fonction permet de réserver un bloc de taille t (en octets) et renvoie un pointeur vers
l'adresse du bloc alloué s'il y a suffisamment de mémoire disponible;
 Son prototype est :

void* malloc( size_t t)

 En cas d’erreur, cette fonction renvoie « NULL »


 Pour l’utiliser il faut inclure la bibliothèque <stdlib.h> en début de programme.
 Exemple :

i n t *a ;
a= ( i n t ∗) m a l l o c ( s i z e o f ( i n t ) ) ;
*a=25;

 La fonction « malloc » alloue (si possible) un bloc mémoire pour 1 « int » et retourne
l'adresse (non typée, void ∗) du bloc. On effectue alors une conversion de type : void ∗
vers int ∗. 108

178
Allocation dynamique

▪ L’opérateur « sizeof(type) »
 D’une machine à une autre, la taille réservée pour un « int » ou un « float », peut varier.
 L’opérateur « sizeof » permet de réserver la mémoire en tenant compte des spécificités de
la machine
 Exemple :

printf("char : %d octets\n", sizeof(char));


printf("int : %d octets\n", sizeof(int));

179
Allocation dynamique

▪ Fonction « free() »
 La fonction « free() » permet de libérer de la mémoire préalablement allouée par les
fonctions « malloc() ».
 En paramètre, on passe l'adresse du bloc mémoire à libérer.
 Son prototype :

void free(void* p)
 Exemple :
#include<stdio.h>
#include<stdlib.h>
int main() {
int* memoireAllouee ;
memoireAllouee =(int*) malloc(sizeof(int)); // Allocation de la mémoire

if (memoireAllouee == NULL) {
exit(0); Erreur : on arrête tout !
}
Utilisation de la mémoire
printf("Quel age avez-vous ? ");
scanf("%d", memoireAllouee);
printf("Vous avez %d ans\n", *memoireAllouee);
free(memoireAllouee); // Libération de mémoire
110
}
180
Allocation dynamique

▪ Tableau dynamique
 Un des principaux intérêts de l'allocation dynamique est de permettre à un programme de
réserver la place nécessaire au stockage d'un tableau en mémoire dont il ne connaissait pas
la taille avant
 En effet, jusqu'ici, la taille de nos tableaux était fixée dans le code source. Lors de la
déclaration d’un tableau en langage C, il fallait préciser les dimensions, soit de:
➢ façon explicite :
➢ int tab[5] ;
➢ float tam[3][2];
➢ façon implicite (par initialisation) :
➢ int tab[ ] = {4, 6, 2, 8, 1};
➢ float tam[ ][ ] = { {0 , 1 } , {2 , 3 } , {4 , 5 } };
 Dans les 2 cas, on a déclaré des tableaux de tailles fixes et donc impossible de changer la
taille
 Mais si l’on veut que le tableau change de taille d’une exécution à une autre, cela nous
oblige à modifier le programme et à le recompiler à chaque fois, ou bien à déclarer un
tableau de taille nettement plus grand mais ce serait du gâchis.D’où l’intérêt de
l’allocation dynamique
181
Allocation dynamique

▪ Tableau dynamique
 Syntaxe :

type * tab =(type*)malloc(taille_tab×sizeof(type))


 Exemple 1

182
▪ Tableau dynamique
 Exemple 2
#include<stdio.h>
#include<stdlib.h>
int main() {
int nombreDAmis = 0, i = 0 ;
int* ageAmis = NULL; // Ce pointeur va servir de tableau après l'appel du malloc
// On demande le nombre d'amis à l'utilisateur
printf("Combien d'amis avez-vous ? ");
scanf("%d", &nombreDAmis);

if (nombreDAmis > 0) { // Il faut qu'il ait au moins un ami


ageAmis = (int *)malloc(nombreDAmis * sizeof(int)); // On alloue de la mémoire pour le tableau
if (ageAmis == NULL) { // On vérifie si l'allocation a marché ou non
exit(0); // et on quitte le programme si l’allocation a échoué
}
// On demande l'âge des amis un à un
for (i = 0 ; i < nombreDAmis ; i++){
printf("Quel age a l'ami numero %d ? ", i + 1);
scanf("%d", &ageAmis[i]); // on pouvait aussi ecrire scanf("%d", (ageAmis+i));
}
// On affiche les âges stockés un à un
printf("\n\nVos amis ont les ages suivants :\n");
for (i = 0 ; i < nombreDAmis ; i++) {
printf("%d ans\n", ageAmis[i]);
}
// A la fin, on libère la mémoire allouée avec malloc, on n'en a plus besoin
free(ageAmis);
}return 0
113

183
5.3 Plusieurs fichiers par projet

Vous aimerez peut-être aussi