1 of 93

Programmation en langage C

Tous les codes sources sont dans un fichier séparé, à suivre selon la référence indiquée pour chaque partie

2 of 93

Plan du cours

  • Les principes de base de la programmation en langage C
  • Les techniques avancées de la programmation en langage C
  • Les structures de données en langage C

3 of 93

Les principes de base de la programmation en langage C

  • La notion de programmation
  • Le langage C
  • Outils de programmation
  • Notre premier programme
  • Les variables
  • Les conditions
  • Les boucles
  • Les fonctions

​

4 of 93

La notion de programmation

Programmer signifie réaliser des « programmes informatiques ».

Un programme informatique est un ensemble d’opérations et d’instructions destinées à être exécutées par un ordinateur afin de réaliser des actions données.

Exemples de programmes informatiques:

  • Les jeux vidéos
  • Les logiciels de « chat »
  • Le traitement de texte
  • La calculatrice
  • …

4

5 of 93

La notion de programmation

L’ordinateur ne comprend qu’un seul langage appelé « langage binaire »; c’est un langage formé de 0 et de 1.

Problème: Il est inconcevable d’écrire un programme en langage binaire !

Solution: Les informaticiens ont inventé de nouveaux programmes de traduction intermédiaires entre l’utilisateur et l’ordinateur qui traduisent en binaire.

5

« fournis moi la table de multiplication du chiffre 9 »

Traduction binaire

0011001110011110

6 of 93

La notion de programmation

  • Un « langage de très haut niveau » est facile à utiliser et permet d’écrire, très rapidement, des programmes. Ainsi, il nécessite d’être accompagné de fichiers pour qu’il puisse s’exécuter. Exemple : Python
  • Un « langage de haut niveau » est un langage simplifié proche de notre vrai langue. Exemples de langage de plus au moins haut niveaux : le C++ et le JAVA
  • Un « langage bas niveau » est un langage peu plus difficile à utiliser. Exemple : le C.

​

6

7 of 93

La notion de programmation

  • Le texte qui représente les instructions de votre programme écrit dans un langage de haut niveau est appelé « code source »

7

Copie papier d'un code source en Fortran des années 1970, imprimé sur du papier continu (en), dédié aux fichiers textes.

8 of 93

La notion de programmation

  • Le programme qui traduit en binaire notre code source est appelé « compilateur ». L’opération de la traduction est appelé « compilation ».
  • Le programme binaire crée par le compilateur est appelé « l’exécutable ».

8

« fournis moi la table de multiplication du chiffre 9 »

Compilateur

L’exécutable

0011001110011110

9 of 93

Le langage C

Le langage C est l’un des langages les plus connus, les plus utilisés et les plus populaires. Il est inventé au cours de l’année 1972 par Dennis Ritchie et Ken Thompson. Il est utilisé pour programmer une grande partie des logiciels que vous connaissez.

9

Le logo de « The C Programming Language », utilisé dans la couverture du livre, « The C Programming Language », par Brian W. Kernighan et Dennis M. Ritchie, publié en 1978.

Ken Thompson (à gauche) et Dennis Ritchie (à droite)

10 of 93

Le langage C

Un peu d’histoire:

  • A tout début, on a inventé un langage de programmation appelé l’Algo.
  • Après, on a crée un langage appelé le CPL et qui a été évolué en BCPL. Par la suite il a pris le nom de langage B.
  • Dennis Ritchie a fait évoluer le langage B dans une nouvelle version suffisamment différente appelée langage C.
  • Un peu plus tard, on a amélioré le langage C pour avoir le langage C++.

Remarque: Le C et le C++ ne sont pas des langages concurrents. Ce sont juste deux manières assez différentes de programmer.

10

11 of 93

Outils de programmation

Les outils nécessaires pour un programmeur sont:

  • Un éditeur de texte pour écrire le code source du programme. L’éditeur de texte le plus connu est Bloc notes, cependant, il est préférable d’avoir un éditeur de texte qui colore le code pour pouvoir se y repérer facilement.
  • Un compilateur pour compiler le code source en binaire.
  • Un débogueur qui va nous aider à traquer les erreurs dans notre programme.

11

12 of 93

Outils de programmation

Il y a deux possibilités:

  • Soit récupérer chacun de ces trois programmes séparément. C’est la méthode la plus difficile !
  • Soit utiliser un seul programme qui combine éditeur de texte, compilateur et débogueur. Ces programmes sont appelé IDE ou encore Environnement de développement intégré. Les IDE que l’on peut trouver sont:
  • Sous Windows: Dev-C++, Visual C++ Express
  • Pour Mac: Xcode
  • Sous Windows, Linux et Mac: Code::Blocks

12

13 of 93

Notre premier programme

  • Demander le minimum de code à Code::Blocks [1]
  • Analysons ce code:
  • Les lignes 1 et 2 s’appellent directives de préprocesseur. Le préprocesseur est un programme qui se lance au début de la compilation. Ces deux lignes demande d’inclure deux bibliothèques (fichiers) stdio.h et stdlib.h. Ces bibliothèques contiennent un code tout prêt qui permet d’afficher du texte à l’écran.
  • « main » est le nom de la fonction principale de votre programme.
  • Les lignes 6 et 7 s’appellent les instructions. Chaque instruction est une commande à l’ordinateur.

​

​

13

14 of 93

Notre premier programme

Remarque: toute instruction doit se terminer par un point virgule, si non votre programme ne compilera pas !

  • La ligne 6 demande d’afficher le message « Hello World » à l’écran.
  • La ligne 7 indique qu’on arrive à la fin de la fonction « main » et demande de renvoyer la valeur 0.

Remarque: Pourquoi la valeur 0 ? Le 0 indique que tout s’est bien passé et toute autre valeur indique qu’il y a une erreur.

​

14

15 of 93

Notre premier programme

Les caractères spéciaux:

C’est un ensemble de deux caractères, le premier est toujours un antislash (\), le second est une lettre ou un nombre. Les caractères spéciaux les plus utilisé sont:

\n : indique un retour à ligne et \t : indique une tabulation [2]

Les commentaires:

Commenter signifie taper du texte au milieu du programme pour ajouter des annotations.

  • Si le commentaire si tient sur une seule ligne, vous tapez un double antislash (\\) suivi de votre commentaire.
  • Si le commentaire est long, vous le débuter par un /* et le terminer par un */.

​

15

16 of 93

Les variables

Une variable est une donnée dont la valeur est susceptible de varier pendant le déroulement du programme. En langage C, une variable est constituée de deux éléments:

  • Une valeur: c’est le nombre qu’elle stocke.
  • Un nom: c’est ce qui permet de la connaitre.

Remarques sur le nom d’une variable:

  • Il ne peut contenir que des minuscules, des majuscules et des chiffres.
  • Il doit commencer par une lettre.
  • Les espaces sont interdits, à leurs places on peut utiliser des « underscores » (_).
  • Vous n’avez pas le droit d’utiliser des accents.

16

17 of 93

Les variables

Il existe plusieurs types de nombres à savoir:

  • Les nombres entiers positifs : 45, 398, 7650
  • Les nombres entiers négatifs : -87, -916
  • Les nombres décimaux : 75.909, 1.7741, 9810.7
  • Les nombres négatifs décimaux : -76.9, -100.11

Pour créer une variable vous devez indiquer son type. Les principaux types de variables qui existent en langage C sont:

  • signed char, int et long : pour stocker les nombres entiers
  • float et double : pour stocker les nombres décimaux (appelé aussi flottants)
  • unsigned char, unsigned int et unsigned long : pour stocker que les nombres entiers positifs.

​

17

18 of 93

Les variables

La différence entre les types de variables dans C:

​

18

Nom du type

Minimum

Maximum

signed char

-127

127

int

-32 767

32 767

long

-2 147 483 647

2 147 483 647

float

-1x1037

1x1037

double

-1x1037

1x1037

Nom du type

Plage de valeurs

unsigned char

0 à 255

unsigned int

0 à 65 535

unsigned double

0 à 4 294 967 295

19 of 93

Les variables

Déclaration d’une variable:

Pour déclarer une variable, vous indiquez son type suivi d’un espace suivi du nom que vous voulez donner à votre variable.

Affecter une valeur à une variable:

Pour affecter une valeur à une variable, vous indiquez son nom suivi d’un signe égal suivi de la valeur que vous voulez y mettre.

Pratiquement, on combine la déclaration et l’affectation dans une même instruction. [3]

19

20 of 93

Les variables

Une constante est une variable dont la valeur reste constante pendant toute la durée du programme.

Pour déclarer une constante, il faut utiliser le mot const juste avant le type de la variable.

Remarque : Pour la constante, il faut obligatoirement lui donner une valeur au moment de sa déclaration. [4]

20

21 of 93

Les variables

Affichage du contenu d’une variable:

Pour afficher la valeur d’une variable on utilise (comme pour l’affichage du texte) la fonction « printf » dans laquelle on insère le format de la variable à l’endroit où l’on veut afficher la valeur sans oublier d’ajouter le nom de la variable en question après les guillemets et une virgule.

Le format de la variable dépend de son type:

​

21

Type de la variable

Format

int

%d

long

%ld

float

%f

double

%f

22 of 93

Les variables

Affichage du contenu de plusieurs variables:

Pour afficher le contenu de plusieurs variables il suffit pour cela d’indiquer les formats des variables là où vous voulez puis d’indiquer les noms des variables correspondantes dans le même ordre séparé par des virgules. [5]

Récupération d’une saisie:

Pour demander à l’utilisateur de saisir un nombre, on va utiliser la fonction prédéfinie « scanf ». Vous devez y mettre un format pour indiquer à l’utilisateur ce qu’il doit entrer, puis vous devez ensuite indiquer le nom de la variable qui va recevoir le nombre.

Attention: il faut mettre le symbole & devant le nom de la variable qui va recevoir la valeur. Pour le type double il faut utiliser le format %lf. [6]

​

22

23 of 93

Les variables

Les calculs de base :

​

23

Opération

Signe

Effet

Addition

+

Addition de deux valeurs

Soustraction

-

Soustraction entre deux valeurs

Multiplication

*

Multiplication de deux valeurs

Division

/

Division de deux valeurs

Modulo

%

Reste de la division

Les opérateurs d’incrémentation:

​

Opérateur

Signe

Effet

Incrémentation

++

Ajouter 1 à un variable

Décrémentation

--

Retirer 1 à une variable

24 of 93

Les variables

Les opérateurs d’assignation:

​

​

​

​

​

​

​

[7]

​

24

Opérateur

Effet

=

Affecte une valeur (à droite) à une valeur (à gauche)

+=

Additionne deux valeurs et stocke le résultat dans la variable (à gauche)

-=

Soustrait deux valeurs et stocke le résultat dans la variable (à gauche)

*=

Multiplie deux valeurs et stocke le résultat dans la variable (à gauche)

/=

Divise deux valeurs et stocke le résultat dans la variable (à gauche)

%=

Soustrait deux valeurs et stocke le reste de la division dans la variable (à gauche)

25 of 93

Les variables

La bibliothèque mathématique:

En langage C, il existe une bibliothèque qui contient des fonctions mathématiques toutes prêtes, il s’agit de la bibliothèque « math.h », voici quelques fonctions de cette bibliothèque:

​

25

Fonction

Rôle

Fonction

Rôle

fabs

Retourne la valeur absolue d’un nombre

sqrt

Calcul la racine carré d’un nombre

ceil

Retourne le premier nombre entier après le nombre décimal donné

exp

Calcul l’exponentielle d’un nombre

floor

Fait l’inverse de la fonction ceil

log

Calcul le logarithme népérien d’un nombre

pow

Permet de calculer la puissance d’un nombre

…

​

26 of 93

Les conditions

Les conditions permettent de tester des variables s’elles sont égales ou inférieures ou supérieures ou … à une valeur donnée.

Les symboles utilisés dans les conditions sont:

​

26

Symbole

Signification

==

Est égal à

>

Est supérieur à

<

Est inférieur à

>=

Est supérieur ou égal à

<=

Est inférieur ou égal à

!=

Est différent de

27 of 93

Les conditions

Le test if (le test simple):

Le test if (pour exprimer « si ») permet d’exécuter un bloc d’instructions si une condition est vérifiée.

if (/* Votre condition */)

{

Instructions à exécuter si la condition est vraie

}

[8]

​

27

28 of 93

Les conditions

Le test else (le test double):

Si le test simple n’a pas marché (il est faux), on va dire à l’ordinateur d’exécuter un autre bloc d’instructions. Pour ce faire il faut utiliser un else  pour dire « sinon ». [9]

if (/* Votre condition */)

{

// Bloc d’instructions 1

}

else

{

// Bloc d’instructions 2

}

​

​

​

28

29 of 93

Les conditions

Le test else if :

Il est possible aussi de faire un « sinon si » en utilisant un else if pour faire un autre test si le premier test n’a pas marché en introduisant un else if entre le if et le else. Dans ce cas l’ordinateur fait les tests dans l’ordre suivant:

  1. D’abord il teste le premier if, si la condition est vraie, il exécute le bloc d’instruction 1.
  2. Sinon, il va au else if et fait un nouveau test, si ce test est vrai, il exécute le bloc d’instructions 2.
  3. Enfin, si aucun des tests précédents n’a pas marché, il exécute le bloc d’instructions 3.

​

​

​

29

30 of 93

Les conditions

Le test else if :

if (/* Condition 1 */)

{

// Bloc d’instructions 1

}

else if (/* Condition 2 */)

{

// Bloc d’instructions 2

}

else

{

// Bloc d’instructions 3

}

[10]

​

​

​

​

30

31 of 93

Les conditions

La condition switch:

Le switch est une alternative du if quand il s’agit d’analyser la valeur d’une variable. Si vous avez besoin de tester plusieurs cas, le switch permet de rendre le code source plus clair. Si vous vous trouvé avoir utilisé plusieurs else if c’est en général le signe qu’un switch serait plus adapté pour rendre le code source plus lisible !

​

​

​

​

​

​

31

32 of 93

Les conditions

switch (variable)

{

case valeur_1:

instructions 1;

break;

…

case valeur_n:

instructions n;

break;

default:

instructions n+1;

break;

}

​

​

​

​

​

32

Remarques:

  1. Vous devez obligatoirement mettre une instruction break; à la fin de chaque cas. Si vous ne le faite pas l’ordinateur lit les instructions en dessous censées être réservées aux autres cas !
  2. Le default: correspond au else que l’on connait. Si la variable ne connait aucune des valeurs précédentes, alors l’ordinateur va lire le default. [11]

33 of 93

Les conditions

Plusieurs conditions à la fois:

On peut faire plusieurs tests à la fois dans notre if. Pour cela, il va falloir utiliser de nouveaux symboles:

​

​

​

​

Exemples:

  • if (poids > 60 && poids < 70)
  • if (age > 30 || poids < 75)
  • if (!(age < 18))

33

Symbole

Signification

&&

Pour dire « et »

||

Pour dire « ou »

!

Pour dire « non »

34 of 93

Les conditions

Les booléens:

Un booléen est une variable qui peut avoir deux états: vrai (1) ou faut (0). On utilise des int pour stocker des booléens car ce ne sont en fait rien d’autre que des nombres.

Remarque: Toute autre valeur différente de 0 est considérée comme vraie.

​

En voici quelques petits tests pour comprendre les booléens [12]

34

35 of 93

Les boucles

Une boucle est une technique qui permet de répéter les même instructions plusieurs fois.

Dans ce mode de structure:

  1. L’ordinateur lit les instructions de la première à la dernière.
  2. Une fois arrivé à la dernière instruction il repart à la première.
  3. Il recommence à lire toutes les instructions du haut en bas.
  4. Et ainsi de suite …

Pour ne pas répéter les instructions d’une manière infinie, une condition d’arrêt est cependant nécessaire !

​

35

36 of 93

Les boucles

La boucle while:

Le mot while signifie « tant que ». Dans cette boucle, on dit à l’ordinateur: tant que la condition est vrai, répète les instructions entre les accolades.

while (/* Condition */)

{

// Instructions à répéter

}

[13]

36

37 of 93

Les boucles

La boucle do while:

La boucle do while est très similaire à la boucle while, sauf que dans cette boucle au lieu de placer la condition au début de la boucle, elle est placée à la fin.

do

{

// Instructions à répéter

} while (/* Condition */);

[14]

​

37

38 of 93

Les boucles

À noter !

  • Dans la boucle while le test de continuation s'effectue avant d'entamer le corps de boucle qui, de ce fait, peut ne jamais s'exécuter.
  • Dans la boucle do while ce test est effectué après le corps de boucle, lequel sera alors exécuté au moins une fois. Il est donc parfois utile d’utiliser ce genre de boucle pour s’assurer que l’on rentre au moins une fois dans la boucle.

38

39 of 93

Les boucles

La boucle for:

La boucle for signifie « pour ». Dans cette boucle, on dit à l’ordinateur de répéter un ensemble d’instructions pour une plage de valeur d’un compteur qui se modifie au cours de l’exécution.

for (initialisation ; condition ; incrémentation)

{

Bloc d’instructions

}

​

39

40 of 93

Les boucles

La boucle for:

Analysons les trois instructions condensées de la boucle for:

  • L’initialisation : elle effectue l’initialisation des données de la boucle.
  • La Condition : c’est la condition qui dit si la boucle doit être répétée ou non. Tant que la condition est vraie, la boucle for continue.
  • L’incrémentation : elle est utilisée pour mettre à jour les données de la boucle.

[15]

​

40

41 of 93

Les fonctions

  • Tous les gros programmes en langage C sont dans la réalité des assemblages de petits bouts de codes. Ces petits bouts de codes sont ce que l’on appelle les fonctions.
  • Une fonction exécute des actions et renvoie un résultat. C’est un morceau du code qui sert à faire des instructions précises.
  • Une fonction possède en générale une entrée (les informations avec lesquels la fonction travaille) et une sortie (le résultat).

​

41

Une fonction

Entrée

Sortie

42 of 93

Les fonctions

Prenons l’exemple d’une fonction appelée « triple » qui calcule le triple d’un nombre qu’on lui donne:

​

​

​

​

La structure d’une fonction:

Toute fonction est structurée comme ainsi:

type nomFonction(parametres)

{

// instructions à exécuter

}

​

42

Triple

(multiplie le nombre en entrée par 3)

12

36

43 of 93

Les fonctions

  • Le type : c’est le type de la fonction, il correspond à la sortie.
  • Si la fonction renvoie une valeur, on met un des types que l’on connait (int, long, double, …).
  • Si la fonction ne renvoie pas de valeur, on met un type spécial « void » (qui signifie « vide »).
  • nomFonction : c’est le nom de la fonction. Il doit respecter les mêmes règles de nomination que les variables.
  • parametres : il correspondent à l’entrée, ce sont les valeurs avec lesquels la fonction va travailler.

[16]

43

44 of 93

Les fonctions

Prenons l’exemple de la fonction triple:

​

int triple(int nombre)

{

int resultat = 0;

resultat = 3 * nombre;

return resultat;

}

44

  • La fonction est de type int donc elle doit renvoyer une valeur de type int.
  • Les paramètres de la fonction triple correspondent à la variable nombre de type int.
  • La variable resultat est créée dans la fonction triple, cela signifie qu’elle n’est utilisable que dans cette fonction.

​

45 of 93

Les fonctions

Remarque 1:

Il est recommandé de placer votre fonction avant la fonction main parce que l’ordre a une réelle importance. En effet, si vous placez votre fonction avant le main dans votre code source, votre ordinateur l’aura lue et la connaîtra. Lorsque vous ferez un appel à la fonction dans la fonction main, l’ordinateur connaîtra la fonction et saura où aller la chercher.

En revanche, si vous mettez votre fonction après le main, cela ne marchera pas car l’ordinateur ne connait pas encore la fonction !

45

46 of 93

Les fonctions

Il est possible de créer des fonctions acceptant plusieurs paramètres. Exemple:

int addition(int x, int y)

{

return x+y;

}

46

Comme il est possible de créer (rarement) des fonctions ne prenant aucun paramètre. Exemple:

void bonsoir()

{

printf("Bonsoir");

}

Comme cette fonction ne retourne rien, elle est de type void.

Remarque 2:

47 of 93

Les fonctions

Remarque 3:

  • Une variable définie à l'intérieur d’une fonction est une variable locale, elle n’est connue qu'à l'intérieur de cette fonction, elle est créée à l'appel de la fonction et détruite à la fin de son exécution.
  • Une variable définie à l’extérieur d’une fonction est une variable globale, elle est définie durant toute l’application et peut être utilisée et modifiée par les différentes fonctions du programme.

Attention ! Les variables déclarées au début de la fonction principale main ne sont pas des variables globales, mais elles sont locales à main.

47

Utilisant la fonction triple dans un exemple [16]

48 of 93

Les fonctions

Le prototype pour annoncer une fonction:

Nous allons annoncer nos fonctions à l’ordinateur en utilisant ce qu’on appelle des « prototypes ».

Prenons l’exemple de la fonction triple et copions la première ligne de cette fonction juste après les directives du préprocesseur tout en ajoutant un point virgule à la fin.

En faisant ainsi, nous pouvons placer notre fonction triple après la fonction main si nous voulons.

Cette opération s’appelle l’ajout du prototype. Un prototype est une indication pour l’ordinateur qui lui indique qu’il existe une fonction appelée triple. Cela permet à l’ordinateur de s’organiser.

48

49 of 93

Les techniques avancées de la programmation en langage C

  • Les pointeurs
  • Les tableaux
  • Les chaînes de caractères
  • Les structures
  • Les énumérations
  • Lire et écrire dans les fichiers
  • L’allocation dynamique
  • Une saisie de texte sans limites

50 of 93

Les pointeurs

Supposons que nous voulons écrire une fonction qui renvoie deux valeurs, ce serais impossible car on ne peut pas avoir deux return dans une seule fonction.

Prenons un exemple: supposons que nous souhaitons écrire une fonction à laquelle on envoie un nombre de minutes et celle-ci renverrait le nombre d’heures et de minutes correspondantes:

  • Si on envoie 15, la fonction renvoie 0 heure et 15 minutes
  • Si on envoie 70, la fonction renvoie 1 heure et 10 minutes
  • Si on envoie 90, la fonction renvoie 1 heure et 30 minutes

Tentons de tester cette fonction [17]

​

​

50

51 of 93

Les pointeurs

Que s’est-il passé ?

Quand vous envoyez une variable à une fonction, une copie de la variable est réalisée. Ainsi les variables h et min dans la fonction HeuresMinutes ne sont pas les mêmes que celles de la fonctions main, ce sont juste des copies !

Dans la réalité la fonction HeuresMinutes fait sont travail; à son intérieur, les variables h et min ont les bonnes valeurs à savoir 1 (heure) et 10 (minutes).

Mais puisque toutes les variables créées dans une fonction sont détruites à la fin de cette fonction, les copies de h et min sont donc supprimées. Lorsqu’on retourne à la fonction main, les variables h et min valent toujours 0 et 70 !!

51

52 of 93

Les pointeurs

La mémoire vive (RAM) de votre ordinateur peut être présentée par la figure à droite.

La première ligne présente la cellule du tout début de la mémoire, chaque cellule à un numéro, c’est son adresse.

A chaque adresse on peut stocker un et un seul nombre (la valeur).

​

​

52

Adresse

Valeur

0

1

3

3 448 765 900

…

2

145

3.8028322

0.827551

3901930

…

940.5118

53 of 93

Les pointeurs

Supposons que nous avons créé une variable poids de type int ayant la valeur 65.

Votre programme demande au système d’exploitation (Windows par exemple) la permission d’utiliser un peu de mémoire. Le système d’exploitation répond en indiquant à quelle adresse en mémoire vous pouvez stocker votre nombre, on dit qu’il alloue de la mémoire.

La valeur 65 a été alors inscrite quelque par dans la mémoire, supposons à l’adresse n°4655.

Ainsi, le mot poids dans votre programme est remplacé (par le compilateur) par l’adresse 4655 à l’exécution.

53

54 of 93

Les pointeurs

Ainsi à chaque fois que vous tapez le mot poids dans votre programme, il est remplacé par 4655 et votre ordinateur cherche en mémoire cette adresse et y trouve la valeur 65.

Affichons l’adresse de notre variable poids créée [18]

Retenons:

  • En tapant le nom de variable poids, l’ordinateur va nous fournir la valeur de la variable en mémoire à savoir 65.
  • En tapant &poids, l’ordinateur va vous fournir l’adresse de la variable poids.

En langage C, on peut créer des variables contenant des adresses. Ce sont ce que l’on appelle les pointeurs.

Un pointeur est une variable qui stocke l’adresse à laquelle se trouve une autre variable en mémoire.

​

​

54

55 of 93

Les pointeurs

Comment créer un pointeur ?

Pour créer une variable de type pointeur, on ajoute le symbole * avant le nom de la variable: int *monPointeur;

Remarques:

  • On peut aussi écrire int* monPointeur; mais il est préférable d’utiliser la première syntaxe car au cas où vous avez à déclarer plusieurs pointeurs vous serez obliger de mettre le * avant le nom de chaque pointeur:

int *monPointeur1, *monPointeur2, *monPointeur3;

  • Pour initialiser un pointeur, on n’utilise généralement pas le 0 mais le mot-clé NULL (en majuscule) ce qui signifie que votre pointeur ne contient aucune adresse:

int *monPointeur = NULL;

​

55

56 of 93

Les pointeurs

Lors de la création et l’initialisation d’un pointeur que se passe-t-il ?

Lors de la création d’un pointeur, le programme demande à l’ordinateur de réserver une case mémoire qui va contenir, comme valeur, l’adresse d’une autre variable en mémoire.

Testons un exemple …

  • La ligne « int poids = 65; » signifie créer une variable de type int nommée poids dont la valeur vaut 65.
  • La ligne « int *monPointeur = &poids; » signifie créer une variable de type pointeur nommée monPointeur dont la valeur vaut l’adresse de la variable poids.

56

57 of 93

Les pointeurs

Remarque:

Comme la valeur du pointeur monPointeur est l’adresse de la variable poids qui est de type int, alors monPointeur doit être de type int* !

Vocabulaire: on dit que la variable monPointeur pointe sur la variable poids.

Quelques instructions à retenir : [19]

C’est quoi alors l’intérêt des pointeurs ?

Le plus important intérêt des pointeurs réside dans le fait qu’on peut les envoyer à des fonctions pour qu’ils modifient directement une variable en mémoire et non pas une copie de cette variable.[20]

​

57

58 of 93

Les tableaux

Un tableau est une suite de variables de même type, situées dans un espace contigu en mémoire.

Un tableau a une dimension bien précise.

Toutes les cases d’un tableau doivent être du même type.

58

Adresse

Valeur

5000

5001

5003

5004

5002

145

32

16

65

301

59 of 93

Les tableaux

La déclaration d’un tableau:

La déclaration d’un tableau se fait comme suit:

type nomTableau[dimension];

L’initialisation d’un tableau:

Pour initialiser toutes les cases d’un tableau créé à 0 nous écrivons:

type nomTableau[dimension] = {0};

Exemple: créons un tableau de type int nommé ages et de dimension 5:

int ages [5] = {0};

​

​

59

60 of 93

Les tableaux

La définition d’un tableau:

Prenons l’exemple du tableau ages. Pour le définir (remplir ses cases), il y a deux manières de le faire:

La première : lors de la déclaration

int ages[5] = {11,19,5,28,63};

La deuxième : après la déclaration

ages[0] = 11;

ages[1] = 19;

ages[2] = 5;

ages[3] = 28;

ages[4] = 63;

60

61 of 93

Les tableaux

Attentions !! Un tableau commence toujours à l’indice numéro 0. Notre tableau de 5 int contient donc les indices 0, 1, 2, 3 et 4.

Remarque : Si nous écrivons int age[5] = {11,19}; la case n°0 prendra la valeur 11, la case n°1 prendra la valeur 19, et toutes les autres cases prendront la valeur 0 par défaut.

Erreur très fréquente ! Si nous écrivons int ages[5] = {1}, cela revient à remplacer la case n°0 par 1 et toutes les autres cases prendront la valeur 0 (par défaut), contrairement à ce que beaucoup semblent croire, on n’initialise pas toutes les cases à 1.

61

62 of 93

Les tableaux

Parcourir et afficher les éléments d’un tableau:

Pour parcourir un tableau, la façons la plus appropriée et la plus rapide est d’utiliser la boucle for.

Prenons l’exemple de notre tableau ages:

for (i = 0 ; i < 5 ; i++)

{

printf("%d\n", ages[i]);

}

​

62

63 of 93

Les tableaux

Quelle relation entre les tableaux et les pointeurs ? [21]

  • En écrivant dans l’instructions printf("%d\n",ages); seulement ages, nous obtenons un pointeur sur la première case du tableau.
  • En indiquant l’indice de la case du tableau, par exemple printf("%d",ages[0]);), nous obtenons la valeur de la case correspondante.
  • puisque ages est un pointeur, nous pouvons utiliser le symbole * pour connaitre la première valeur: printf("%d",*ages);
  • Si nous souhaitons par exemple obtenir la valeur de la seconde case il suffit d’écrire *(ages+1) : printf("%d\n",*(ages+1));

​

​

​

​

63

64 of 93

Les tableaux

Les tableaux à deux dimensions : les matrices

La déclaration d’un tableau à deux dimensions en langage C se fait de la manière suivante :

Type NomTableau [NbLignes][NbColonnes]

Lors de la déclaration d'un tableau à deux dimensions, on peut initialiser les composantes du tableau, en indiquant la liste des valeurs respectives entre accolades.

A l'intérieur de la liste, les composantes de chaque ligne du tableau sont encore une fois comprises entre accolades. Pour améliorer la lisibilité des programmes, on peut indiquer les composantes dans plusieurs lignes.

​

​

​

64

65 of 93

Les tableaux

Ainsi, on peut déclarer et initialiser un tableau comme l’exemple suivant :

int A [3][10] = {{0,10,20,30,40,50,60,70,80,90},

{10,11,12,13,14,15,16,17,18,19},

{1,12,23,34,45,56,67,78,89,90}};

Remarque : Si A est un tableau de dimensions L et C, les indices du tableau varient de 0 à L-1, respectivement de 0 à C-1.

Comment créer, remplir et afficher un tableau de deux dimensions à l’aide une boucle ? [22]

​

​

​

65

66 of 93

Les chaînes de caractères

Une « chaîne de caractère » est un nom programmatiquement correct pour désigner du texte.

Une chaine de caractère c’est donc du texte que l’on peut retenir sous forme de variable en mémoire.

Cependant, notre ordinateur ne peut retenir que des nombres, les lettres sont exclues. Comment fait-on alors pour manipuler du texte ?

66

67 of 93

Les chaînes de caractères

Si vous vous souvenez bien, le type char permet de stocker des nombres compris entre -127 et 127. Cependant, si ce type permet de stocker des nombres, il faut savoir qu’on C on l’utilise rarement pour ça ! En fait, le type char est prévu pour stocker une lettre.

Comme la mémoire ne peut stocker que des nombres, on a inventé une table, appelée table ASCII (American Standard Code for Information Interchange (Code américain normalisé pour l'échange d'information)), c’est une norme informatique de codage de caractères apparue dans les années 1960. La plupart des caractères de base dans cette table sont codés entre 0 et 127.

67

68 of 93

Les chaînes de caractères

Table des 128 caractères ASCII:

​

68

69 of 93

Les chaînes de caractères

Pour obtenir le nombre associé à une lettre, il suffit d’écrire cette lettre entres apostrophes, par exemple 'Z'. Lors de la compilation le 'Z' sera remplacé par la valeur correspondante dans la table ASCII à savoir 90. Testons cet exemple [23]

Pour afficher un caractère, on doit utiliser le symbole %c (c pour caractère) à l’intérieur du printf [24]

On peut aussi demander à l’utilisateur d’entrer une lettre en utilisant le symbole %c dans le scanf [25]

69

70 of 93

Les chaînes de caractères

Une chaîne de caractères n’est rien d’autre qu’un tableau de caractères, autrement dit, un tableau de type char.

Essayons de créer la chaine de caractère "salut" à l’aide d’un tableau de caractères nommé chaine. [26]

La figure suivante donne une idée sur la façon avec laquelle la chaine de caractères "salut "   est stockée en mémoire.

70

Adresse

Valeur

7000

7001

7003

7004

7002

's'

'a'

'l'

'u'

't'

71 of 93

Les chaînes de caractères

Toutefois, une chaîne de caractère ne contient pas que des lettres, elle doit impérativement contenir un caractère spécial à la fin de la chaîne appelé « caractère de fin de chaine » qui s’écrit « \0 ». Ce caractère indique à l’ordinateur quand arrête la chaine de caractères.

Ainsi, pour stocker en mémoire le mot "salut" il nous faut un tableau de 6 char et non pas de 5. [27]

71

Adresse

Valeur

7000

7001

7003

7004

7002

's'

'a'

'l'

'u'

't'

7005

'\0'

72 of 93

Les chaînes de caractères

Pour afficher une chaîne de caractères, il faut utiliser dans le printf le symbole %s (s pour string, chaine en anglais).

La méthode décrite dans [27] est une méthode manuelle et reste très peu efficace. Heureusement, il existe une méthode plus simple, celle décrite en [28].

Dans cette méthode, vous n’avez pas besoin d’indiquer la dimension de votre tableau chaîne; le compilateur compte lui-même le nombre des lettres et ajoute 1 pour le \0.

On peut enregistrer une chaîne de caractères entrée par un l’utilisateur via le scanf en utilisant le symbole %s. Cependant, il y a un problème, c’est qu’on ne sait pas combien de caractères l’utilisateur va entrer. Pour ce faire, il va falloir créer un tableau d’une dimension suffisamment grande. [29]

72

73 of 93

Les chaînes de caractères

Fonctions de manipulation des chaînes:

Il existe une pléthore de fonctions toutes prêtes de manipulation des chaînes dans la bibliothèque string. Pour pouvoir les utiliser, il faut inclure string.h. [30]

  1. Calculer la longueur d’une chaine de caractères: strlen

strlen est une fonction qui calcule la longueur d’une chaîne de caractères. Vous lui envoyez un seul paramètre, à savoir votre chaîne de caractères, et elle vous retourne la longueur de cette chaîne. [31]

73

74 of 93

Les chaînes de caractères

  1. Copier une chaîne dans une autre: strcpy

La fonction strcpy permet de copier une chaîne dans une autre. Supposons que nous avons deux chaînes de caractères « chaine » contenant le mot "salut" et « copie » initialement vide, et que nous souhaitons copier chaine dans copie. Schématiquement, la copie fonctionne comme suit:

​

​

​

​

74

chaine

copie

s

a

l

u

t

\0

s

a

l

u

t

\0

…

Assurez vous toujours que la chaîne copie est suffisamment grande pour accueillir le contenu de chaine sinon votre ordinateur plantera ! [32]

75 of 93

Les chaînes de caractères

  1. Concaténer deux chaînes de caractères: strcat

strcat permet de concaténer deux chaînes de caractères; c’est-à-dire ajouter une chaîne à la fin d’une autre. Supposons que nous avons les deux chaînes suivantes:

chaine1 = "bonjour "  

chaine2 = "maryam"

Après la concaténation, chaine2 reste inchangée; elle vaut toujours "maryam", et chaine1 est changée; elle devient "bonjour maryam" .

75

76 of 93

Les chaînes de caractères

Schématiquement, la concaténation fonctionne comme suit:

76

chaine1

chaine2

b

o

n

j

o

u

m

a

r

y

a

m

\0

r

\0

…

Assurez vous toujours que chaine1 est suffisamment grande pour que l’on puisse lui ajouter le contenu de chaine2 ! [33]

77 of 93

Les chaînes de caractères

  1. Comparaison entre deux chaînes de caractères: strcmp

strcmp permet de comparer deux chaînes de caractères entre elles. Cette fonction renvoie:

  • 0 si les chaînes sont identiques
  • Une autre valeur (positive ou négative), si les chaînes sont différentes. [34]
  • Rechercher un caractère dans une chaîne de caractères : strchr

strchr permet de chercher un caractère dans une chaîne. Cette fonction renvoie un pointeur vers le premier caractère qu’elle a trouvé, c’est-à-dire qu’elle renvoie l’adresse de ce caractère dans la mémoire. Si elle n’a rien trouvé elle renvoie NULL. [35]

​

77

78 of 93

Les chaînes de caractères

Dans cette exemple ([35]), chaine pointe sur le premier caractère, à savoir 's', tandis que caractereReCherche pointe sur le premier caractère recherché trouvé à savoir 'm'.

Schématiquement cette recherche se fait comme suit:

78

s

a

l

u

t

m

e

s

e

t

u

d

i

a

n

t

s

chaine

caractereReCherche

  1. Rechercher une chaîne de caractères dans une autre: strstr

strstr permet de chercher la première occurrence d’une chaîne dans une autre. [36]

​

79 of 93

Les chaînes de caractères

  1. Ecrire dans une chaîne de caractères: sprintf

sprintf permet d’écrire dans une chaine de caractères. Cette fonction s’utilise de la même manière que printf, sauf que vous devez lui donnez en premier lieu un pointeur vers la chaîne de caractère qui va recevoir le texte.

Toujours assurez vous que votre chaine est suffisamment grande pour recevoir tout le texte que sprintf va lui donner.

Remarque: la fonction sprinft appartient à la bibliothèque stdio.h, contrairement aux fonctions précédentes qui appartiennet à la bibliothèque string.h. [37]

79

80 of 93

Les structures

Une structure est un assemblage de variables qui peuvent avoir différents types.

La définition d’une structure commence par le mot « struct » suivi du nom de votre structure. Ensuite vous ouvrez les accolades et les fermez plus loin. Attention: vous devez mettre un point virgule après l’accolade fermante !! À l’intérieur des accolades, vous placez toutes vos variables :

strcut NomDeLaStructure {

int variable_1;

int variable_2;

long variable_3;

double variable_4;

};

80

81 of 93

Les structures

Créons un type de variable personnalisé appelé « Sportif » contenant les informations: age, poids et taille.

81

strcut NomDeLaStructure {

int variable_1;

int variable_2;

long variable_3;

double variable_4;

};

En faisant ainsi, nous avons créé notre « nouveau » propre type de variables personnalisé appelé «  NomDeLaStructure ». Ce type stocke différents types d’informations. « variable_1 », « variable_2 », « variable_3 » et « variable_4 » s’appellent des sous variables.

82 of 93

Les structures

Exemple d’une structure:

strcut Sportif {

int age;

double poids;

double taille;

};

​

​

82

Une structure peut aussi contenir des tableaux. Exemple:

Struct Etudiant {

char nom[100];

char prenom[100];

int age;

int genre // booléen: 1=F, 0=M

};

​

​

Créons une variable nommée x de type Sportif. [38]

83 of 93

Les structures

Les programmeurs ont trouvé pénible d’écrire le mot struct à chaque déclaration d’une variable personnalisée. Pour remédier à ce problème, ils ont inventé une instruction spéciale: le « typedef ».

83

strcut Sportif {

int age;

double poids;

double taille;

};

typedef strcut Sportif Sportif;

Cette ligne dit « écrire le mot Sportif est désormais équivalent à écrire struct Sportif ». Ainsi, vous n’aurez plus besoin d’écrire le mot struct à chaque déclaration d’une variable de type Sportif. [39]

84 of 93

Les structures

Pour accéder à chaque composante de la structure, nous devons écrire:

variable.NomDeLaComposante

Prenons l’exemple de notre structure Sportif. Maintenant que notre variable x a été créée, nous allons modifier les informations relatives comme suit:

x.age = 28;

x.poids = 65.3;

x.taille = 1.65;

Analysons le bout de code suivant [40].

84

85 of 93

Les structures

L’intérêt des structures réside dans le fait que l’on peut créer plusieurs variables chacune a ses propres informations.

Exemple: Etudiant etudiant1, etudiant2;

On peut même faire encore mieux; créer un tableau de Etudiant. Exemple: Etudiant etudiants[3];

L’avantage d’utiliser un tableau est qu’on peut faire une boucle pour demander les informations du premier étudiant, le deuxième et le troisième sans avoir à répéter le même code trois fois. [41]

85

86 of 93

Les structures

Comme pour les variables, les pointeurs et les tableaux, il est vivement conseillé d’initialiser les structures dès leurs création. L’initialisation des structures ressemble un peu à l’initialisation des tableaux.

Prenons l’exemple de la structure Sportif, l’initialisation se fait comme suit:

Sportif x = {0,0,0};

Cela définira dans l’ordre: x.age=0, x.poids=0 et x.taille=0

Et pour la structure Etudiant, son initialisation se fait comme suit:

Etudiant x = {"" , "" ,0,0};

On utilise les guillemets pour initialiser une chaine de caractère.

86

87 of 93

Les structures

Un pointeur de structure:

De la même manière qu’un pointeur de int, de double, de … on peut créer un pointeur de structure.

Prenons l’exemple de la structure Sportif :

Sportif *x = NULL;

​

Analysons le code suivant qui illustre l’utilisation des pointeurs de structure [42].

87

88 of 93

Les énumérations

À l’instar des structures, les énumérations est une manière, un peu différente, pour créer ses propres variables.

Dans une énumération on ne trouve pas des sous variables, mais des « valeurs possibles » pour une variable. Ainsi, une énumération prend une case en mémoire, et cette case peut prendre une des valeurs définies (et une seule à la fois).

Les énumérations se créent de la même manière que les structures:

typedef enum NomEnum NomEnum;

enum NomEnum {

VALEUR1, VALEUR2, VALEUR3

}; [43] [44] [45]

88

89 of 93

Lire et écrire dans les fichiers

Problématique : Le grand problème des variables, c’est qu’elles n’existent que dans la mémoire vive de l’ordinateur. C’est-à-dire qu’une fois votre programme est arrêté, toutes vos variables sont perdues. Ainsi vous perdrez leurs valeurs.

Heureusement, en langage C on peut lire et écrire dans des fichiers. Ces derniers sont écrits sur le disque dur de votre ordinateur. Ainsi, même si vous arrêté votre programme, ces fichiers ne sont pas perdus.

Comment peut on donc lire et écrire dans des fichiers ?

89

90 of 93

Lire et écrire dans les fichiers

Ouvrir un fichier:

Pour ouvrir un fichier, on utilise la fonction « fopen » de la bibliothèque stdio. Le prototype de cette fonction est:

FILE* fopen(const char* nomDuFichier, const char* modeOuverture);

Cette fonction attends deux paramètres:

  • Le nom du fichier à ouvrir.
  • Le mode d’ouverture du fichier (écriture, lecture, les deux à la fois).

Et elle renvoie un pointeur sur FILE, c’est un pointeur sur une structure de type FILE de la bibliothèque stdio.

​

90

91 of 93

Lire et écrire dans les fichiers

  • Comme la fonction fopen renvoie un pointeur sur FILE, il est extrêmement important de récupérer ce pointeur pour pouvoir lire et écrire dans le fichier [46].
  • Les modes d’ouverture possibles d’un fichier sont:
  • "r" : lecture seule. Vous pouvez lire le contenu du fichier, mais pas y écrire. Dans ce cas, le fichier doit avoir été créé au préalable.
  • "w"  : écriture seule. Vous pouvez écrire dans le fichier, mais pas lire son continu. Si le fichier n’existe pas, il sera créé.
  • "a" : mode d’ajout. Vous ajouterez du texte à la fin du fichier. Si le fichier n’existe pas il sera créé.

​

91

92 of 93

Lire et écrire dans les fichiers

  • "r+" : lecture et écriture. Vous pouvez lire et écrire dans le fichier. Le fichier doit avoir été crée au préalable.
  • "w+"  : lecture et écriture, avec suppression du contenu au préalable. Le fichier est d’abord vidé de son contenu. Vous pouvez y écrire et le lire ensuite. Si le fichier n’existe pas, il sera créé.
  • "a+" : ajout en lecture / écriture à la fin. Vous écrivez et lisez du texte à partir de la fin du fichier. Si le fichier n’existe pas, il sera créé.

Créons un fichier nommé test de type .txt et essayons de l’ouvrir en mode lecture / écriture. [47]

​

92

93 of 93

Lire et écrire dans les fichiers

Fermer un fichier:

Pour fermer un fichier, on utilise la fonction « fclose » de la bibliothèque stdio. Le prototype de cette fonction est le suivant:

int fclose(FILE* pointeurSurFichier);

Cette fonction prend en paramètre votre pointeur sur le fichier, et renvoie un int qui indique si la fermeture a réussi ou pas:

  • Si le int vaut 0, cela indique que la fermeture a réussi.
  • Sinon, il y a une erreur.

[48]

93