Vous êtes sur la page 1sur 186

Algorithmique et

Programmation
INSA Hauts-de-France
Licence Informatique [Mathématiques] 2ème année – Semestre 3

Christophe Wilbaut
Objectifs du module - Syllabus
• Appréhender un langage compilé de programmation impérative
• Connaître les fondamentaux d’un langage typé
• Instructions du langage, opérateurs, types
• Fonctions avec ou sans effets de bord
• Appréhender la gestion de la mémoire en programmation
• Mémoire statique vs mémoire dynamique
• Définir et utiliser des structures de données dynamiques
• Tableaux, listes chaînées, piles / files

2
Organisation du module
• Volume horaire
• 6h CM → 4 séances de 1.5h
• 15h TD → 10 séances de 1.5h
• 15h TP → 10 séances de 1.5h

3
Organisation du module
• Volume horaire
• 6h CM → 4 séances de 1.5h
• 15h TD → 10 séances de 1.5h
• 15h TP → 10 séances de 1.5h
• Modalités d’évaluation
• DS + TP

4
Organisation du module
• Volume horaire
• 6h CM → 4 séances de 1.5h
• 15h TD → 10 séances de 1.5h
• 15h TP → 10 séances de 1.5h
• Modalités d’évaluation
• DS + TP
• Progression
• Séance de cours → Travail personnel → TD / TP
• Travail personnel : exercices spécifiques, vidéos à regarder, …
• Fiches d’exercices traitées en TD et TP

5
Espace de cours Moodle
• Nom : Algorithmique et Programmation Impérative
• Nom abrégé : ALGO3

• Clef d’inscription
• LANGAGE_C_2021

6
Espace de cours Moodle
• Nom : Algorithmique et Programmation Impérative
• Nom abrégé : ALGO3

• Clef d’inscription
• LANGAGE_C_2021

• Contenu
• Slides du cours,
• Liens pour les vidéos
• Fiches d’exercices (TD, TP)
• Anciens sujets de DS
7
Plan du module
• Partie I
Eléments du langage
• Partie II
De la mémoire statique à la mémoire dynamique
• Partie III
Des structures de données dynamiques
• [Partie IV]
[Algorithmique non numérique]

8
PARTIE I :
Eléments du langage
Vidéo 1 : introduction Vidéo 6 : conditions et alternatives
Vidéo 2 : utiliser un logiciel et un compilateur Vidéo 7 : boucles
Vidéo 3 : types et opérateurs simples Vidéo 8 : fonctions
Vidéo 4 : mémoire, lecture / écriture Vidéo 9 : structures
Vidéo 5 : notion de pointeur Vidéo 10 : tableaux

9
Le langage C
• Langage de Programmation crée dans les années 70
• Réécriture d’UNIX
• Version stabilisée en 1978

10
Le langage C
• Langage de Programmation crée dans les années 70
• Réécriture d’UNIX
• Version stabilisée en 1978
• Normalisation
• C89 ou ANSI C
• puis C90 ou C ISO
• C94 / C95
• C99
• C11

11
Le langage C
• Langage de programmation impératif
• Langage dit de "bas niveau"
• En opposition aux langages dits de "haut niveau"
• Un de ses principaux avantages : sa rapidité d’exécution
• Un de ses principaux inconvénients : vérification de ce qui a été choisi

12
Le langage C
• Langage de programmation impératif
• Langage dit de "bas niveau"
• En opposition aux langages dits de "haut niveau"
• Un de ses principaux avantages : sa rapidité d’exécution
• Un de ses principaux inconvénients : vérification de ce qui a été choisi
• Le ‘C’ est un langage compilé
• vs langage interprété
• Exemples de langages … compilés … interprétés
Ada, C++, Pascal PHP, Python, Ruby, Matlab
• Exemple de langage « hybride » : Java
13
Pourquoi considérer le C ?
• Pour manipuler un langage compilé
• Parce qu’il est fondé sur un standard ouvert
• Parce qu’il existe depuis longtemps …
• … et surtout qu’il est encore très utilisé [1]

14
[1] : https://spectrum.ieee.org/at-work/tech-careers/top-programming-language-2020
Pourquoi considérer le C ?
• Pour manipuler un langage compilé
• Parce qu’il est fondé sur un standard ouvert
• Parce qu’il existe depuis longtemps …
• … et surtout qu’il est encore très utilisé [1]
• Parce qu’il reste un langage simple …
• … et que l’on peut faire des choses (très) évoluées avec
• Parce qu’il est très efficace
• Parce qu’il est une base de nombreux autres langages et applications

15
[1] : https://spectrum.ieee.org/at-work/tech-careers/top-programming-language-2020
Pourquoi considérer le C ?
• Quelques exemples d’applications … historiques
• Le noyau d’UNIX (1969 → 1972)
• Oracle (1977 → 1983)
• GNU (1984)
• Windows (1985)
• Le noyau de Linux (1991)

16
Pourquoi considérer le C ?
• Quelques exemples d’applications … historiques
• Le noyau d’UNIX (1969 → 1972)
• Oracle (1977 → 1983)
• GNU (1984)
• Windows (1985)
• Le noyau de Linux (1991)
• De façon plus générale le C est toujours utilisé dans les systèmes
d’exploitation
• Noyau de Windows – Linux (et +) - Mac
• Noyau d’Android – d’iOS – de Windows Phone
→ Ordinateurs et smartphones utilisent le C via leur OS
17
Pourquoi considérer le C ?
• Quelques autres exemples d’applications
• Les systèmes de gestion de bases de données
• Oracle, MySQL, MS SQL Server, Postgre SQL
→ éducation, santé, finance, loisirs, web, etc.

18
Pourquoi considérer le C ?
• Quelques autres exemples d’applications
• Les systèmes de gestion de bases de données
• Oracle, MySQL, MS SQL Server, Postgre SQL
→ éducation, santé, finance, loisirs, web, etc.

• Systèmes embarqués
• Alarme, micro onde, garage, voiture, paiement par carte, etc.

• Animations 3D

19
Pourquoi considérer le C ?
• Comment expliquer cette utilisation ?
• Il existe aujourd’hui de nombreux langages permettant
• D’être plus productif
• De faire plus de choses

20
Pourquoi considérer le C ?
• Comment expliquer cette utilisation ?
• Il existe aujourd’hui de nombreux langages permettant
• D’être plus productif
• De faire plus de choses
• Langages de haut niveau avec de nombreuses librairies qui simplifient la vie
pour travailler avec
• Des pages Web, des requêtes clients, des connexions à des BD, manipuler du contenu
média, etc.
• Mais le C est (pratiquement) un langage portable
• Disponible sur toutes les architectures de processeurs existantes

21
Pourquoi considérer le C ?
• Portabilité + bas niveau
• Compilateurs, interpréteurs et librairies d’autres langages souvent écrits en C
• Python, Ruby et PHP
• Communication avec la machine via le C
• Eiffel, Forth

22
Pourquoi considérer le C ?
• Portabilité + bas niveau
• Compilateurs, interpréteurs et librairies d’autres langages souvent écrits en C
• Python, Ruby et PHP
• Communication avec la machine via le C
• Eiffel, Forth
• Dernier point important : le C est (peut être ?) entrain de devenir le
"langage commun" entre développeurs
• Alex Allain, Directeur Ingénierie chez Dropbox et créateur de
Cprogramming.com [2]
“C is a great language for expressing common ideas in programming in a way that most people are comfortable
with. Moreover, a lot of the principles used in C -- for instance, argc and argv for command line parameters,
as well as loop constructs and variable types -- will show up in a lot of other languages you learn so you'll be
able to talk to people even if they don't know C in a way that's common to both of you.”
23
[2] : https://www.cprogramming.com/whyc.html
Langage C – un premier exemple de programme
/* */ : Commentaires
void f1(); /* prototype */
main : fonction principale
/* Fonction : main */
/* Description : appelle la function f1 */
int main()
{
f1();
return 0;
} f1 : une fonction (qui ne
retourne rien ici)
void f1() ( ) : obligatoire
{ → l’appel de f1 dans le main
/* la fonction f1 ne fait rien */ se fait de façon classique :
} nom de la fonction, suivi
des ( )
{ … }  début … fin ;  termine chaque instruction
24
Langage C – un premier exemple de programme
• Commentaire
• Tout ce qui est écrit entre /* et */ est interprété comme du commentaire
• Un commentaire peut être sur plusieurs lignes
• Un commentaire ne peut pas être dans un autre commentaire
• Le commentaire est utile mais ne doit pas paraphraser le code
• Fonction main
• Chaque programme C a une (et une seule) fonction main
• C’est cette fonction qui est exécutée au lancement du programme
• Il s’agit bien d’une fonction qui retourne un entier (int)

25
Le langage C
• Le C est un langage typé
• Tout objet doit être déclaré via un identifiant (unique) et un type avant
d’être utilisé

26
Le langage C
• Le C est un langage typé
• Tout objet doit être déclaré via un identifiant (unique) et un type avant
d’être utilisé
• Un objet est déclaré avec une certaine portée
• Variable globale
• Variable locale
• etc.

27
Le langage C
• Le C est un langage typé
• Tout objet doit être déclaré via un identifiant (unique) et un type avant
d’être utilisé
• Un objet est déclaré avec une certaine portée
• Variable globale
• Variable locale
• etc.
• La notion de type est fondamentale
• Sémantique
• Définit la taille de chaque variable
• Définit la liste des opérations possibles
28
Le langage C – déclaration
• Déclaration d’une variable : identifiant
• Commence par une lettre ou le caractère _ ("underscore")
• Peut contenir des majuscules
• Peut contenir des minuscules (distinction majuscule / minuscule)
• Peut contenir des chiffres
• Ne peut pas contenir d’espace
• Ne peut pas contenir d’accent

29
Le langage C – déclaration
• Déclaration d’une variable : identifiant
• Commence par une lettre ou le caractère _ ("underscore")
• Peut contenir des majuscules
• Peut contenir des minuscules (distinction majuscule / minuscule)
• Peut contenir des chiffres
• Ne peut pas contenir d’espace
• Ne peut pas contenir d’accent
_une_variable → ok
1variable → non
• Ces règles sont également valides pour les identifiants de fonctions

30
Le langage C – déclaration
• Quelques caractères spéciaux
•{ } ! # , ; ~ . + - * / % < = > ( ) [ ] ‘ "

31
Le langage C – déclaration
• Quelques caractères spéciaux
•{ } ! # , ; ~ . + - * / % < = > ( ) [ ] ‘ "
• Quelques mots réservés
auto else long typedef
break enum register union
case extern return unsigned
char float short void
const for signed volatile
continue goto sizeof while
default if static …
do inline struct
double int switch
32
Le langage C – déclaration
• Déclaration d’une variable : type
• Le C dispose d’un ensemble de types simples prédéfinis
• Types Entier

33
Le langage C – déclaration
• Déclaration d’une variable : type
• Le C dispose d’un ensemble de types simples prédéfinis
• Types Entier
• char : codage d’un entier sur 8 bits (prise en charge du code ASCII)
• short : codage d’un entier court sur 16 bits
• int : codage d’un entier sur 32 bits
• long (int) : codage d’un entier long sur 32 ou 64 bits
• long long (int) : codage d’un entier long long sur 64 bits
• Entiers signés (par défaut) ou non signés
• unsigned

34
Le langage C – déclaration
• Intervalle des entiers codés
Type #Bits Bornes
char 8 -128 - 127
unsigned char 8 0 - 255
short 16 -32,768 - 32,767
unsigned short 16 0 - 65,535
int 32 -2,147,483,648 - 2,147,483,647
unsigned int 32 0 - 4,294,967,295
long 64 -9,223,372,036,854,775,808 - 9,223,372,036,854,775,807
unsigned long 64 0 - 18,446,744,073,709,551,615

35
Le langage C – type char
• Type entier qui peut être utiliser pour stocker un (seul) caractère
•  d’une chaîne de caractères
• ‘ ‘ pour entourer une valeur correspondant à un caractère (" " réservés aux
chaînes)

36
Le langage C – type char
• Type entier qui peut être utiliser pour stocker un (seul) caractère
•  d’une chaîne de caractères
• ‘ ‘ pour entourer une valeur correspondant à un caractère (" " réservés aux
chaînes)
• Code ASCII (American Standard Code for Information Interchange)
• 128 caractères codés de 0 à 127
• Exemple : ‘A’  65, ‘B’  66, … , ‘a’  97, ‘b’  98
• Le type char permet de stocker une de ces valeurs

37
Le langage C – type char
• Recommandation
• Type à utiliser uniquement au sein d’un tableau de caractères
• Si besoin de stocker un seul caractère → utiliser un int
• Lors de l’affichage (voir plus loin)
• %d  code ASCII
• %c  caractère
• Opérateurs : idem type int

38
Le langage C – valeurs réelles
• Types réel
• float : réel simple précision sur 32 bits
• double : réel double précision sur 64 bits
• long double : réel quadruple précision sur 128 bits (OS 64 bits)
• Représentation
• Partie entière + partie fractionnaire
• Au moins 6 chiffres après la virgule (float) et 10 chiffres (double)
• Recommandation
• Utiliser le type double
• Plus précis
• Nécessaire dans les fonctions mathématiques prédéfinies

39
Le langage C – déclaration
• Format : type identifiant [, identifiant2, etc.] ;

40
Le langage C – déclaration
• Format : type identifiant [, identifiant2, etc.] ;
• Exemples
• char un_caractere ;
• int i, j, k ;
• double d, un_reel ;
• unsigned int mon_entier ;
• unsigned long super_entier ;

41
Le langage C – déclaration
• Format : type identifiant [, identifiant2, etc.] ;
• Exemples
• char un_caractere ;
• int i, j, k ;
• double d, un_reel ;
• unsigned int mon_entier ;
• unsigned long super_entier ;
• Déclaration et initialisation
int i, j, k ; int i, j, k = 1 ;
k = 1;

42
Le langage C – déclaration
• Remarque
• Type booléen (bool) introduit dans la norme C99
• Librairie stdbool.h
• Déclaration et initialisation
bool un_booleen ;
un_booleen = true ; /* ou false */
• On peut définir son propre type booléen (voir plus loin)
• On peut simplement associer 0 à false et 1 à true

43
Le langage C – déclaration et portée
• Portée de déclaration
• Certaines variables sont visibles (donc accessibles, donc modifiables) depuis
tout le code → variables globales
• D’autres ne sont visibles que d’une partie du code → variables locales

44
Le langage C – déclaration et portée
• Portée de déclaration
• Certaines variables sont visibles (donc accessibles, donc modifiables) depuis
tout le code → variables globales
• D’autres ne sont visibles que d’une partie du code → variables locales
• La portée dépend de l’endroit où est déclarée la variable
• Globale : déclaration en dehors d’une fonction
• Locale : déclaration au début d’une fonction ou d’un "bloc" ({ … })
• Variable globale
• Visible par toute fonction définie après sa déclaration
• Souvent définie dans un fichier entête qui est inclus partout où nécessaire

45
Le langage C – déclaration et portée

int i;
La variable i est visible ici, pas j ni k

int main()
{ Ici portée du main : i et j sont visibles, mais pas k !
int j;

{
int k ; Ici portée du bloc { } : les variables i, j et k sont visibles
}

return 0;
}

Une variable locale n’est visible qu’à l’intérieur de son bloc défini et délimité par { }

46
Le langage C – déclaration et portée
• Remarque : typage statique vs typage dynamique
• En C le compilateur vérifie la concordance variable  type

47
Le langage C – déclaration et portée
• Remarque : typage statique vs typage dynamique
• En C le compilateur vérifie la concordance variable  type
• Typage statique
#include <stdio.h> In function 'main’:
warning: comparison between signed and unsigned
unsigned int i = 2;
int j = -1; i < j ????
int main() {
if ( i < j ) { printf("i < j"); }
else { printf("i > j"); }
return 0;
}

48
Le langage C – déclaration et portée
• Remarque : typage statique vs typage dynamique
• Dans d’autres langages la vérification se fait pendant l’exécution
• Typage dynamique
• Typage le plus utilisé dans les langages de script
• En Python le type de la variable est défini lors de la première affectation

49
Le langage C – déclaration et portée
• Remarque : typage statique vs typage dynamique
• Dans d’autres langages la vérification se fait pendant l’exécution
• Typage dynamique
• Typage le plus utilisé dans les langages de script
• En Python le type de la variable est défini lors de la première affectation
def f(v):
if v:
return (1 + 1)
else: >>> test(True)
return (1 + “test") 2
>>> test(False)
TypeError: unsupported operand type(s) for +:
'int' and 'str'
50
Le langage C – déclaration et portée
• Typage dynamique
• Facile à utiliser
• Nécessite de tester tous les embranchements du code
• Typage statique
• Vérifie l’ensemble du code avant exécution
• Plus performant

51
Le langage C – opérateurs
• Opérateur = 1 ou plusieurs caractère(s) utilisé(s) comme une fonction
prédéfinie
• Nombreux opérateurs existants
• Exemples les plus utiles pour commencer
• Affectation =
• Opérateur de signe +, -
• Opérations mathématiques de base +, -, *, /, % (sur entiers)
• Comparaison ==, !=, >, <, >=, <=
• Opérateurs logiques &&, ||, !

52
Le langage C – opérateurs
• Affectation =
• Prend la valeur de ce qui se trouve à droite du = et l’affecte à la variable qui
se trouve à gauche du =
int i, j ;
j = 2 ;
i = 1 + 1 ;
i = i + j ;

53
Le langage C – opérateurs
• Affectation =
• Prend la valeur de ce qui se trouve à droite du = et l’affecte à la variable qui
se trouve à gauche du =
int i, j ;
j = 2 ;
i = 1 + 1 ;
i = i + j ;
• Remarque : vous rencontrerez sûrement une erreur de compilation
mentionnant quelque chose comme "invalid lvalue in assignment"
• lvalue fait référence à la valeur se trouvant à gauche (left) du =
• Signifie que vous essayer d’affecter une valeur à quelque chose qui ne peut pas la recevoir
• Exemple : 2 = 1 + 1 ;

54
Le langage C – opérateurs
• Signes et mathématiques
• + unaire +2
• - unaire -2
• addition, soustraction, multiplication
• division entière / (Euclidienne)
• 5 / 2
• division réelle /
• 5.0 / 2.0
• reste de la division entière (modulo) %
• 5 % 2
• Remarque : priorité des opérateurs → ( )

55
Le langage C – opérateurs
• Comparaison
• 6 opérateurs pour comparer deux expressions
• Expression
• Chaîne formée d’opérateurs, variables, nombres ou combinaison de ces éléments
• Doit pouvoir être analyser par le compilateur
• Exemples d’expressions valides
• 33
• 1 + 1
• i (si i a été déclaré bien sûr)
• i + 2 * j - 5
• 4 / ma_fonction(i)

56
Le langage C – opérateurs
• Comparaison
• Résultat → valeur booléenne
• 0  false
• 1  true (en fait true   0)
• Utile pour les boucles et alternatives

57
Le langage C – opérateurs
• Comparaison
• Résultat → valeur booléenne
• 0  false
• 1  true (en fait true   0)
• Utile pour les boucles et alternatives
• Opérateurs
• == est égal à (ATTENTION)
• != est différent de
• >, <, >=, <=
• En ‘C’ une expression qui n’est pas évaluée 0 est "vraie"
vrai = (2 + 2 == 4);
faux = (2 + 2 == 5);

58
Le langage C – opérateurs
• Logique
• Pour combiner les expressions à évaluer
• &&  et logique
• ||  ou inclusif logique
• !  non logique

59
Le langage C – opérateurs
• Logique
• Pour combiner les expressions à évaluer
• &&  et logique
• ||  ou inclusif logique
• !  non logique

(i > j) || !(i > j)

60
Le langage C – d’autres opérateurs
• Affectation "spéciale" : opérateurs ++ et --
• Raccourci d’écriture
• ++  ajouter 1 à
• --  retirer 1 à

61
Le langage C – d’autres opérateurs
• Affectation "spéciale" : opérateurs ++ et --
• Raccourci d’écriture
• ++  ajouter 1 à
• --  retirer 1 à
• Applicables sur les variables entières ou réelles
i = i + 1 ; i = i – 1;
i++; i--;
++i; --i;

62
Le langage C – d’autres opérateurs
• Affectation "spéciale" : opérateurs ++ et --
• Raccourci d’écriture
• ++  ajouter 1 à
• --  retirer 1 à
• Applicables sur les variables entières ou réelles
i = i + 1 ; i = i – 1;
i++; i--;
++i; --i;
• Différence entre i++ et ++i
• L’incrémentation se fait après l’action (i++) ou avant (++i)
i = 2;
j = i++;
j = ++i;

63
Le langage C – d’autres opérateurs
• Affectations "spéciales" : opérateurs +=, -=, *=, /=
• Raccourci d’écriture sur un principe similaire
• +=  ajouter une valeur à
• -=  retirer une valeur à
• *=  multiplier par une valeur
• /=  diviser par une valeur

64
Le langage C – d’autres opérateurs
• Affectations "spéciales" : opérateurs +=, -=, *=, /=
• Raccourci d’écriture sur un principe similaire
• +=  ajouter une valeur à
• -=  retirer une valeur à
• *=  multiplier par une valeur
• /=  diviser par une valeur
• Applicables sur les variables entières ou réelles
i = i + j;  i+= j;
i = i - 2;  i-= 2;
i = i * j;  i*= j;
i = i / 5;  i/= 5;
• On peut aussi utiliser %= (uniquement pour les entiers)
i = i % 2;  i %= 2;

65
Le langage C – d’autres opérateurs
• Conversion de type
• Forme générale : (type) variable ;
• Permet de convertir un type en un autre

66
Le langage C – d’autres opérateurs
• Conversion de type
• Forme générale : (type) variable ;
• Permet de convertir un type en un autre
• Exemple
int i;
double d = 3.37;
i = (int) d;
• Pas toujours possibles
• Remarques
• En C conversion en int  troncature ou arrondi à l’inférieur
• Opération inverse possible :
d = (double) i;

67
Le langage C – d’autres opérateurs
• Conversion de type int i, s;
• Forme générale : (type) variable ; double m;

• Permet de convertir un type en un autre s = 0;


• Exemple for(i=1; i<=10; i++) {
s+= i;
int i;
}
double d = 3.37; m = s / 10;
i = (int) d;
• Pas toujours possibles
• Remarques
• En C conversion en int  troncature ou arrondi à l’inférieur
• Opération inverse possible :
d = (double) i;

68
Le langage C – d’autres opérateurs
• Conversion de type int i, s;
• Forme générale : (type) variable ; double m;

• Permet de convertir un type en un autre s = 0;


• Exemple for(i=1; i<=10; i++) {
s+= i;
int i;
}
double d = 3.37; m = s / 10;
i = (int) d;
m = (double)s / 10;
• Pas toujours possibles /* ou */
• Remarques m = s / 10.0 ;
• En C conversion en int  troncature ou arrondi à l’inférieur /* ou */
m = (double)s / 10. ;
• Opération inverse possible :
d = (double) i;

69
Langage C – un second exemple de programme
#include <stdio.h>
#define STOP 0
 Directives au préprocesseur
/* Fonction : main */ /* */ : Commentaires
/* Description : affiche un compte à rebours depuis une valeur saisie jusque STOP*/
int main()
{
/* déclarations */
int compteur; /* un entier pour stocker les valeurs comptées */
int depart; /* le point de depart du compte à rebours */
/* invite pour l’utilisateur */
printf("Entrer un entier positif : ");
scanf("%d", &depart); /* lecture et affectation à depart */
/* compte à rebours avec affichage */
for (compteur=depart; compteur >= STOP; compteur--) {
printf("%d ", compteur);
}
; obligatoire à la fin de chaque instruction
return 0;
}
70
Langage C – un second exemple de programme
• Directives au préprocesseur
• #include <stdio.h>
• Copie du fichier entête stdio.h dans le programme avant la compilation
• Ce fichier contient la description (prototype) de fonctions / variables / types utilisables
• Peut être défini par l’utilisateur
• #define STOP 0
• Remplacement de toute instance de la chaîne "STOP" dans le programme par la chaîne "0"
avant la compilation
• C’est une macro → utile pour les valeurs qui ne changent pas dans le programme
(constantes) mais qui peuvent être facilement modifiées pour une autre exécution
• Il existe bien d’autres directives

71
Le langage C – le type pointeur
• Variable  donnée stockée quelque part en mémoire
• Pointeur  variable qui contient l’@ de cet emplacement

72
Le langage C – le type pointeur
• Variable  donnée stockée quelque part en mémoire
• Pointeur  variable qui contient l’@ de cet emplacement
• Nombreuses applications des pointeurs en C
• Passage de paramètres par adresse
• Manipulation de chaînes de caractères
• Types de données dynamiques (tableaux, listes, piles, files, arbres, etc.)
• Utilisation des fonctions standards de lecture / écriture
• Pointeurs de fonctions
• Programmation générique

73
Le langage C – le type pointeur
• Notion d’adresse
• Soit la déclaration : short j ;
• Réservation en mémoire d’un emplacement suffisamment grand pour stocker
un entier court
• Cet emplacement est repéré (appelé) j
• Chaque variable occupe donc un certain nombre d’unités mémoire (cases), et
chaque unité peut contenir certaines valeurs
• Chaque case de la mémoire est donc accessible via un numéro  son adresse

74
Le langage C – le type pointeur
• Toutes les variables (entre autres) sont stockées en mémoire
• La mémoire peut être vue comme un (immense) tableau
• Chaque élément (case) de la mémoire a une adresse
• Une adresse est un entier (comme les indices d’un tableau)

75
Le langage C – le type pointeur
• En C une adresse mémoire est un pointeur
• L’utilisation d’un pointeur permet donc d’accéder à un élément donné
de la mémoire
• En fait un pointeur sur une variable permet de pointer sur l’@ du
premier octet de la variable

76
Le langage C – le type pointeur
• Remarque
• L’adresse d’une variable et sa taille en unités mémoire peuvent être connues
lors de l’exécution d’un programme écrit en C
short j;
printf("%lu %p\n", sizeof(j), &j);
• sizeof : retourne le nombre d’unités mémoire occupées par la variable (ou
le type) passée en paramètre
• &j : correspond à l’adresse en mémoire de la variable j

77
Le langage C – le type pointeur
• Un pointeur pointe sur une donnée → type
• Déclaration d’un pointeur
short *p; int *ip ;
double *dp;

78
Le langage C – le type pointeur
• Un pointeur pointe sur une donnée → type
• Déclaration d’un pointeur
short *p; int *ip ;
double *dp;
• Opérateurs unaires
• & (référence)
• Permet d’accéder à l’adresse de son argument
• L’argument doit être une variable
• * (déréférence ou indirection)
• Permet d’accéder à la valeur de son argument
• L’argument doit être un pointeur

79
Le langage C – le type pointeur
1: int i; /* déclaration d’un entier, i */
2: int *p; /* déclaration d’un pointeur sur un entier, p */

80
Le langage C – le type pointeur
1: int i; /* déclaration d’un entier, i */
2: int *p; /* déclaration d’un pointeur sur un entier, p */

3: i = 10;
4: p = &i; Ne pas confondre :
5: *p = 5; - La valeur du pointeur (une adresse)
6: i--;
- La valeur de l’objet pointé
- L’* ligne 2 et celle ligne 5
7: *p *= 2;

81
Le langage C – le type pointeur
1: int i; /* déclaration d’un entier, i */
2: int *p; /* déclaration d’un pointeur sur un entier, p */

3: i = 10;
4: p = &i; Ne pas confondre :
5: *p = 5; - La valeur du pointeur (une adresse)
6: i--;
- La valeur de l’objet pointé
- L’* ligne 2 et celle ligne 5
7: *p *= 2;
→ Tant qu’un pointeur (p par exemple) pointe sur une variable (i par exemple), les notations
*p et i sont équivalentes

82
Le langage C – le type pointeur
• La variable pointée par un pointeur peut donc être modifiée via le
pointeur
• Un pointeur peut aussi être modifié (c’est une variable !!)

83
Le langage C – le type pointeur
• La variable pointée par un pointeur peut donc être modifiée via le
pointeur
• Un pointeur peut aussi être modifié (c’est une variable !!)
int a = 33, b = 33;
int *p;
p = &a;
*p = *p + 2;
p = &b;
*p = *p - 2;

84
Le langage C – le type pointeur
• Pointeur  adresse → opérations numériques
• Addition (soustraction) d’un entier à un pointeur
int *p = a;
p+= 2;

85
Le langage C – le type pointeur
• Pointeur  adresse → opérations numériques
• Addition (soustraction) d’un entier à un pointeur
int *p = a;
p+= 2;
• Ici on n’utilise pas l’opérateur * → le pointeur est modifié
• int codé sur 4 octets → @ décalée de 8 octets (2 entiers)
• Attention : p pointe sur un autre emplacement en mémoire

86
Le langage C – le type pointeur
• Pointeur  adresse → opérations numériques
• Addition (soustraction) d’un entier à un pointeur
int *p = a;
p+= 2;
• Ici on n’utilise pas l’opérateur * → le pointeur est modifié
• int codé sur 4 octets → @ décalée de 8 octets (2 entiers)
• Attention : p pointe sur un autre emplacement en mémoire
• Utilisation
• Accès aux cases successives des structures de données (voir plus loin)
• On peut aussi soustraire des pointeurs
• Permet de savoir combien d’emplacement mémoire les séparent par exemple
87
Le langage C – le type pointeur
• Attention
• Manipulation d’@  Manipulation de valeurs (numériques notamment)
int a, b, *p, *q;

88
Le langage C – le type pointeur
• Attention
• Manipulation d’@  Manipulation de valeurs (numériques notamment)
int a, b, *p, *q;
a = 1; b = 2;
p = &a; q = &b;
p = p + 2; /*  3 */
b = q – p; /* très certainement  1 */

89
Le langage C – le type pointeur
• Attention
• Manipulation d’@  Manipulation de valeurs (numériques notamment)
int a, b, *p, *q;
a = 1; b = 2;
p = &a; q = &b;
p = p + 2; /*  3 */
b = q – p; /* très certainement  1 */
• Un pointeur est toujours codé sur 4 octets (ou 8)
• Peu importe sur quoi il pointe
→ C’est une @

90
Le langage C – le type pointeur
• Attention : la valeur d’un pointeur non initialisée est indéfinie
int a = 33;
int *p;

91
Le langage C – le type pointeur
• Attention : la valeur d’un pointeur non initialisée est indéfinie
int a = 33;
int *p;
• Initialisation d’un pointeur
• Au pointeur particulier NULL int *p = NULL;
• À l’@ d’une autre variable int *p = &a;
• Attention également
int *p ;
*p = 33;
• Pointeur universel

92
Le langage C – le type pointeur
• Pointeur universel
• Pointeur sur un type non déterminé
void *p ;
• p pointe sur « n’importe quoi » et on pourra le forcer à pointer sur un autre
type quand nécessaire

93
Le langage C – le type void
• Correspond à un type "vide"
• Introduit pour rendre le langage syntaxiquement cohérent
• Déclaration de fonction qui ne renvoie pas de résultat

94
Le langage C – le type void
• Correspond à un type "vide"
• Introduit pour rendre le langage syntaxiquement cohérent
• Déclaration de fonction qui ne renvoie pas de résultat
• Signifie "vide" et pas "erreur"
• Introduit par la norme ANSI
• Une fonction de type void peut avoir une instruction return

95
Le langage C – le type void
• Correspond à un type "vide"
• Introduit pour rendre le langage syntaxiquement cohérent
• Déclaration de fonction qui ne renvoie pas de résultat
• Signifie "vide" et pas "erreur"
• Introduit par la norme ANSI
• Une fonction de type void peut avoir une instruction return
• Déclaration de variable de type void
void *mon_pointeur ;
→ Uniquement des pointeurs

96
Le langage C – l’alternative
• si (condition) alors …
if(condition) { if(i > 0) {
… /* i est positif ici */
} }

97
Le langage C – l’alternative
• si (condition) alors …
if(condition) { if(i > 0) {
… /* i est positif ici */
} }
• si (condition) alors … sinon …
if(condition) { if(i > 0) {
… /* i est positif ici */
} }
else { else {
} /* i est négatif ou nul ici */
}
98
Le langage C – l’alternative
int a, b;

if(a >= b) {
/* a supérieur ou égal à b */
}

99
Le langage C – l’alternative
int a, b; int a, b;
… …
if(a >= b) { if(a >= b) {
/* a supérieur ou égal à b */ /* a supérieure à b */
} }
else {
/* b supérieur (strict) à a */
}

100
Le langage C – l’alternative
int a, b; int a, b;
… …
if(a >= b) { if(a >= b) {
/* a supérieur ou égal à b */ /* a supérieure à b */
} }
else {
/* b supérieur (strict) à a */
}

int a, b;

if(a >= b) ; {
/* passe toujours ici */
}

101
Le langage C – l’alternative
int a, b; int a, b;
… …
if(a >= b) { if(a >= b) {
/* a supérieur ou égal à b */ /* a supérieure à b */
} }
else {
/* b supérieur (strict) à a */
}

int a, b; int a, b;
… …
if(a >= b) ; { if(a >= b) ; {
/* passe toujours ici */ /* erreur de compilation */
} }
else {

} 102
Le langage C – l’alternative
• Les "if" peuvent être imbriqués et/ou combinés avec des "else"
if(note >= 50) {
if(note >= 75) {
/* niveau satisfaisant */
}
else if(note > 60) {
/* niveau acceptable */
}
else {
/* doit progresser */
}
}
else { /* niveau insuffisant */
}
103
Le langage C – l’alternative
• Les "if" peuvent être imbriqués et/ou combinés avec des "else"
int a, b;

if(a % 2 == 0) {
/* a est pair */
}
else {
/* a est impair */
if(b % 2 == 0) {
/* b est pair */
}
else {
/* b est impair */
}
}
104
Le langage C – l’alternative
• Les conditions peuvent être combinées via && ||
if(i >= 0. && i <= 20.) {
/* valeur ok */
}
else {
/* valeur incohérente */
}

105
Le langage C – l’alternative
• Les conditions peuvent être combinées via && ||
if(i >= 0. && i <= 20.) { int a, b;

/* valeur ok */ if(a % 2 == 0 && b % 2 == 0) {
} /* a et b sont pairs */
else { }
else {
/* valeur incohérente */ if(a % 2 != 0) {
} if(b % 2 != 0) {
/* a et b sont impairs */
}
else {
/* a impair, b pair */
}
}
else {
/* a pair, b impair */
}
} 106
Le langage C – l’alternative
• Attention
int a;

if(a % 2 = 0) {
/* erreur de compilation */
}

107
Le langage C – l’alternative
• Attention
int a; int a, b;
… …
if(a % 2 = 0) { b = a % 2;
/* erreur de compilation */ if(b = 0) {
} /* jamais exécuté */
}

int a, b;

b = a % 2;
if(b = 1) {
/* toujours exécuté */
}
108
Le langage C – l’alternative
• Opérateur particulier ? … : … ;
• Sorte de raccourci de if … else
• Forme simple (condition) ? valeur_si_vrai : valeur_si_faux

109
Le langage C – l’alternative
• Opérateur particulier ? … : … ;
• Sorte de raccourci de if … else
• Forme simple (condition) ? valeur_si_vrai : valeur_si_faux

int i = 1, j = 2, k ;

k = (i > j) ? i : j;

110
Le langage C – les boucles
• La boucle "pour" "for" Forme simple
for (initialisation ; condition ; évolution) {
/* actions */
}

111
Le langage C – les boucles
• La boucle "pour" "for" Forme simple
for (initialisation ; condition ; évolution) {
/* actions */
}
• initialisation
• Expression qui initialise la variable compteur
• Effectuée une seule fois au départ
• condition
• Expression de la condition d’arrêt, testée au début de chaque passage dans la boucle
• évolution
• Expression utilisée pour modifier la variable de la boucle
• Peut prendre des formes très différentes : ++, *, /, etc.

112
Le langage C – les boucles
• La boucle "pour" "for" Forme simple
for (initialisation ; condition ; évolution) {
/* actions */
}

for(i = 1; i <= 10; i++) { /* écrire i */ }

for(i = 100; i > 0; i/= 10) { /* écrire i */ }

for(i = 10; i > 0; i*= 2) { /* écrire i */ }

113
Le langage C – les boucles
• La boucle "pour" "for" Flexibilité
• Chacune des trois parties peut contenir à peu près ce que l’on veut

114
Le langage C – les boucles
• La boucle "pour" "for" Flexibilité
• Chacune des trois parties peut contenir à peu près ce que l’on veut
• On peut simuler une boucle "tant que" en omettant l’initialisation
int i = 1;
for( ; i <= 10; i++) { … }

115
Le langage C – les boucles
• La boucle "pour" "for" Flexibilité
• Chacune des trois parties peut contenir à peu près ce que l’on veut
• On peut simuler une boucle "tant que" en omettant l’initialisation
int i = 1;
for( ; i <= 10; i++) { … }
• On peut utiliser une fonction dans la partie évolution
char c;
for(c = ‘ ’; c != ‘\n’; c = getchar()) { … }

116
Le langage C – les boucles
• La boucle "pour" "for" Flexibilité
• Chacune des trois parties peut contenir à peu près ce que l’on veut
• On peut simuler une boucle "tant que" en omettant l’initialisation
int i = 1;
for( ; i <= 10; i++) { … }
• On peut utiliser une fonction dans la partie évolution
char c;
for(c = ‘ ’; c != ‘\n’; c = getchar()) { … }
• On peut combiner plusieurs évolutions
for(i=0, j=10 ; i < j ; i++, j--) { /* écrire i, j */ }

117
Le langage C – les boucles
• La boucle "pour" "for" Flexibilité
• Chacune des trois parties peut contenir à peu près ce que l’on veut
• La condition de la boucle peut elle-même être modifiée dans la boucle
for(i = 1 ; i <= limite; i++) {
if(…) {
limite *= 2;
}
}

118
Le langage C – les boucles
• La boucle "pour" "for" Flexibilité
• Chacune des trois parties peut contenir à peu près ce que l’on veut
• La condition de la boucle peut elle-même être modifiée dans la boucle
for(i = 1 ; i <= limite; i++) {
if(…) {
limite *= 2;
}
}
• On peut créer une boucle "infinie"
for( ; ; ) { … }

119
Le langage C – les boucles
• La boucle "pour" "for" Flexibilité
• Chacune des trois parties peut contenir à peu près ce que l’on veut
• La condition de la boucle peut elle-même être modifiée dans la boucle
for(i = 1 ; i <= limite; i++) {
if(…) {
limite *= 2;
}
}
• On peut créer une boucle "infinie"
for( ; ; ) { … }
• Trois instructions utiles dans les boucles : break, continue,
return

120
Le langage C – les boucles
• Arrêt d’une boucle
• break
• La boucle s’arrête immédiatement et l’exécution code reprend juste après
for(i=1; ; i++) {
if(stop(i)) { /* avec stop() une fonction qui détermine */
break; /* si la boucle doit être stoppée */
}
}

121
Le langage C – les boucles
• Arrêt d’une boucle
• break
• La boucle s’arrête immédiatement et l’exécution code reprend juste après
for(i=1; ; i++) {
if(stop(i)) { /* avec stop() une fonction qui détermine */
break; /* si la boucle doit être stoppée */
}
}
• return
• La boucle s’arrête immédiatement et arrête l’exécution de la fonction dans laquelle elle se
trouve
for(i=1; ; i++) {
if(stop(i)) { /* avec stop() une fonction qui détermine */
return i; /* si la boucle doit être stoppée */
}
}
122
Le langage C – les boucles
• Accélération d’une boucle
• continue
• La boucle interrompt l’itération courante et passe à la suivante

for(i=-10; i<= 10 ; i++) {


if(i == 0) {
continue ;
}
/* écrire i/10 */
}

123
Le langage C – les boucles
• Exemples
int i;
for(i=0; i<10; i++) {
/* écrire i+1 */
}

124
Le langage C – les boucles
• Exemples
int i;
for(i=0; i<10; i++) {
/* écrire i+1 */
}

int i;
for(i=0; i<10; i++) {
/* écrire i+1 */
i = i + 1;
}

125
Le langage C – les boucles
• Exemples
int i; int i;
for(i=0; i<10; i++) { for(i=0; i<10; i++) {
/* écrire i+1 */ /* boucle "infinie" */
} i = i - 1;
}
int i;
for(i=0; i<10; i++) {
/* écrire i+1 */
i = i + 1;
}

126
Le langage C – les boucles
• Exemples
int i; int i;
for(i=0; i<10; i++) { for(i=0; i<10; i++) {
/* écrire i+1 */ /* boucle "infinie" */
} i = i - 1;
}
int i; int i;
for(i=0; i<10; i++) {
for(i=0; i<10; i++) ; {
/* écrire i+1 */
i = i + 1; /* affiche 10 */
} }

127
Le langage C – les boucles
• La boucle "faire … tant que" "do … while"
• On répète les actions tant que la condition est vérifiée
•  "répéter … jusqu’à"
• La boucle est toujours exécutée au moins une fois

128
Le langage C – les boucles
• La boucle "faire … tant que" "do … while"
• On répète les actions tant que la condition est vérifiée
•  "répéter … jusqu’à"
• La boucle est toujours exécutée au moins une fois

i = 100;
do {
/* écrire i/10 */
i--;
} while(i > 0);

129
Le langage C – les boucles
• Exemple
int i = 0;
do {
/* écrire i+1 */
i = i + 1;
} while(i < 10) ;

130
Le langage C – les boucles
• Exemple
int i = 0;
do {
/* écrire i+1 */
i = i + 1;
} while(i < 10) ;

int i = 0;
do {
/* écrire i+1 */
i = i + 1;
} while(i >= 10) ;

131
Le langage C – les boucles
• Exemple
int i = 0; int i = 0;
do { do ; {
/* écrire i+1 */ /* erreur de compilation */
i = i + 1; i = i + 1;
} while(i < 10) ; } while(i < 10) ;

int i = 0;
do {
/* écrire i+1 */
i = i + 1;
} while(i >= 10) ;

132
Le langage C – les boucles
• Exemple
int i = 0; int i = 0;
do { do ; {
/* écrire i+1 */ /* erreur de compilation */
i = i + 1; i = i + 1;
} while(i < 10) ; } while(i < 10) ;

int i = 0; int i = 0;
do { do ;
/* écrire i+1 */ while(i < 10) ;
i = i + 1; /* boucle infinie */
} while(i >= 10) ;

133
Le langage C – les fonctions
• Une fonction est caractérisée par un identifiant
• Mêmes règles de nommage que pour les variables

134
Le langage C – les fonctions
• Une fonction est caractérisée par un identifiant
• Mêmes règles de nommage que pour les variables
• Avec ou sans résultats
• Pas de mot clef pour traduire "fonction"
• Identification par son nom et le type du résultat

135
Le langage C – les fonctions
• Une fonction est caractérisée par un identifiant
• Mêmes règles de nommage que pour les variables
• Avec ou sans résultats
• Pas de mot clef pour traduire "fonction"
• Identification par son nom et le type du résultat
• Exemple de fonction : int main()
• int indique le type du résultat de la fonction
• Les ( ) permettent de spécifier les paramètres

136
Le langage C – les fonctions
• Une fonction est caractérisée par un identifiant
• Mêmes règles de nommage que pour les variables
• Avec ou sans résultats
• Pas de mot clef pour traduire "fonction"
• Identification par son nom et le type du résultat
• Exemple de fonction : int main()
• int indique le type du résultat de la fonction
• Les ( ) permettent de spécifier les paramètres
• Autre exemple : int fait_addition(int a, int b)
• Pas de mots clefs pour indiquer le mode de passage des paramètres
• Par défaut en entrée → passage par valeur

137
Le langage C – les fonctions
• Mot clef pour retourner une valeur
• return
• Cette instruction interrompt la fonction immédiatement

138
Le langage C – les fonctions
• Mot clef pour retourner une valeur
• return
• Cette instruction interrompt la fonction immédiatement
• Une fonction sans résultat a le type void
• void affiche_addition (int a, int b)
• void affiche (double a)

139
Le langage C – les fonctions
• Mot clef pour retourner une valeur
• return
• Cette instruction interrompt la fonction immédiatement
• Une fonction sans résultat a le type void
• void affiche_addition (int a, int b)
• void affiche (double a)
• Lorsque la fonction a plusieurs résultats on passe par les pointeurs
• Passage par adresse

140
Le langage C – les fonctions
• Exemples
int f1() {
return 1;
}

141
Le langage C – les fonctions
• Exemples
int f1() {
return 1;
}
int f2(int a, int b) {
int c = a – b;
return c;
}

142
Le langage C – les fonctions
int f3() {
• Exemples int c;
do {
int f1() { c = getchar();
return 1; } while((c < ‘a’ || c > ‘z’)
} && (c < ‘A’ || c > ‘Z’));
return c;
int f2(int a, int b) {
}
int c = a – b;
return c;
}

143
Le langage C – les fonctions
int f3() {
• Exemples int c;
do {
c = getchar();
} while((c < ‘a’ || c > ‘z’)
&& (c < ‘A’ || c > ‘Z’));
return c;
}

int main
{
int c ;

c = f3();
printf("%d %c\n", c, c);
return c;
}
144
Le langage C – les fonctions
int f3() {
• Exemples int c;
do {
int f1() { c = getchar();
return 1; } while((c < ‘a’ || c > ‘z’)
} && (c < ‘A’ || c > ‘Z’));
return c;
int f2(int a, int b) {
}
int c = a – b;
return c;
}

int f4(int a, int b) {


int c;
if(a <= b) { c = a; }
else { c = b; }
} /* !! */

145
Le langage C – les fonctions
int f3() {
• Exemples int c;
do {
int f1() { c = getchar();
return 1; } while((c < ‘a’ || c > ‘z’)
} && (c < ‘A’ || c > ‘Z’));
return c;
int f2(int a, int b) {
}
int c = a – b;
return c; int f5(int a) {
} int i = 2, s = 0;
while(i < a/2) {
int f4(int a, int b) { if(a % i == 0) {
int c; s = s + i;
if(a <= b) { c = a; } return i; /* arrêt prématuré ?? */
else { c = b; } }
} /* !! */ i = i + 1;
}
} 146
Le langage C – les fonctions
• Exemples
void p1() {

147
Le langage C – les fonctions
• Exemples
void p1() {

void p2(int a, int b) {


int c = a – b;
/* écrire c */
}

148
Le langage C – les fonctions
• Exemples
void p1() { void p3() {
int c;
} do {
c = getchar();
} while((c < ‘a’ || c > ‘z’)
void p2(int a, int b) {
&& (c < ‘A’ || c > ‘Z’));
int c = a – b;
putchar(c);
/* écrire c */
}
}

149
Le langage C – les fonctions
• Exemples
int f2(int a, int b);
char f3();
void p2(int a, int b);

150
Le langage C – les fonctions
• Exemples
int f2(int a, int b); int main()
char f3(); {
int i, j, resultat;
void p2(int a, int b); char c;
resultat = f2(2, 5);
/* écrire resultat */
c = f3();
/* écrire c */
p2(1, 2);
resultat = p2(1, 2); /* !! */
return 0;
}

151
Le langage C – les fonctions
• Dans ces exemples les paramètres sont passés par valeurs
int fait_addition (int a, int b)
{
return a + b;
}

152
Le langage C – les fonctions
• Dans ces exemples les paramètres sont passés par valeurs
int fait_addition (int a, int b)
{
return a + b;
}
• a et b sont utilisés dans la fonction mais ne sont pas modifiés
int main()
{
int x = 2, y = 1, z;
z = fait_addition(x, y);
/* écrire z */
return 0;
}
153
Le langage C – les fonctions
• Considérons une variante de la fonction d’addition
int fait_addition_bis (int a, int b)
{
a+= b;
return a + b;
}

154
Le langage C – les fonctions
• Considérons une variante de la fonction d’addition
int fait_addition_bis (int a, int b)
{
a+= b;
return a + b;
}

int main()
{
int x = 2, y = 1, z;
z = fait_addition_bis(x, y);
/* écrire x, z */
return 0;
}
• a est modifié localement dans la fonction
→ la fonction travaille sur une copie des variables reçues en arguments
155
Le langage C – les fonctions
• Illustration
void exempleval(int p) int main()
{ {
int a = 2 ; int n = 4 ;
p = a * p; exempleval(n);
/* écrire p */ /* écrire n */
} Le p ici est une copie de la return 0;
valeur passée en argument }

• Le principe est le même pour les types simples


• char, sort, int, long, double

156
Le langage C – les fonctions
• Un paramètre peut être modifié grâce à l’utilisation des
pointeurs
• Passage des paramètres par adresse

157
Le langage C – les fonctions
• Un paramètre peut être modifié grâce à l’utilisation des pointeurs
• Passage des paramètres par adresse
int fait_addition_ter (int *a, int b)
{
(*a)+= b;
return *a + b;
}
int main()
{
int x = 2, y = 1, z;
z = fait_addition(&x, y);
/* écrire x, z */ → Exemple de fonction à effet de bord
return 0;
}
158
Le langage C – les fonctions
• Passage de paramètre par adresse
• Le paramètre est alors en entrée et en sortie
• Ca n’est plus la valeur de la variable qui est envoyée mais son @

159
Le langage C – les fonctions
• Passage de paramètre par adresse
• Le paramètre est alors en entrée et en sortie
• Ca n’est plus la valeur de la variable qui est envoyée mais son @
void exempleadd(int *p) int main()
{ {
int a = 2 ; int n = 4 ;
*p = a * (*p); exempleadd(&n);
/* écrire p */ /* écrire n */
} return 0;
}

160
Le langage C – les fonctions
• Passage de paramètre par adresse
• La règle de pointage s’applique même lorsqu’un pointeur pointe vers une
variable d’une autre fonction / procédure

161
Le langage C – les fonctions
• Passage de paramètre par adresse (par référence)
• La règle de pointage s’applique même lorsqu’un pointeur pointe vers une
variable d’une autre fonction / procédure
→ les modifications faites à l’intérieur sont automatiquement reportées

162
Le langage C – les fonctions
• Passage de paramètre par adresse (par référence)
• La règle de pointage s’applique même lorsqu’un pointeur pointe vers une
variable d’une autre fonction / procédure
→ les modifications faites à l’intérieur sont automatiquement reportées

void exempleadd(int *p) int main()


{ {
int a = 2 ; int n = 4 ;
*p = a * (*p); printf("n= %d\n", n);
printf("p= %d\n", *p) ; exempleadd(&n);
} printf("n= %d\n", n);
return 0;
}

163
Le langage C – lecture / écriture
• Fonctions prédéfinies dans stdio.h
• Ecriture à l’écran printf
• Du texte seul
printf("ceci est du texte");

164
Le langage C – lecture / écriture
• Fonctions prédéfinies dans stdio.h
• Ecriture à l’écran printf
• Du texte seul
printf("ceci est du texte");
• La valeur d’une variable
int i = 2;
printf("%d", i);
• %d indique au compilateur que l’on va lui passer une valeur entière à afficher

165
Le langage C – lecture / écriture
• Fonctions prédéfinies dans stdio.h
• Ecriture à l’écran printf
• Du texte seul
printf("ceci est du texte");
• La valeur d’une variable
int i = 2;
printf("%d", i);
• %d indique au compilateur que l’on va lui passer une valeur entière à afficher
• Autres formats (il y en a d’autres)
• %c pour le type char
• %ld pour le type long
• %lf pour le type double
• %s pour une chaîne de caractères (voir plus loin)

166
Le langage C – lecture / écriture
• Ecriture à l’écran printf
• On peut combiner texte et valeurs de variables
printf("la valeur de i est %d, celle de j est %lf", i, j);

167
Le langage C – lecture / écriture
• Ecriture à l’écran printf
• On peut combiner texte et valeurs de variables
printf("la valeur de i est %d, celle de j est %lf", i, j);
• Quelques éléments de formatage du texte
• \n pour un retour à la ligne
• \t pour une tabulation horizontale
• \v pour une tabulation verticale

168
Le langage C – lecture / écriture
• Ecriture à l’écran printf
• On peut combiner texte et valeurs de variables
printf("la valeur de i est %d, celle de j est %lf", i, j);
• Quelques éléments de formatage du texte
• \n pour un retour à la ligne
• \t pour une tabulation horizontale
• \v pour une tabulation verticale
• Il existe d’autres fonctions d’écriture
• putchar, putc, fputc, etc.

169
Le langage C – lecture / écriture
• Lecture / saisie de valeur scanf
• Attend l’adresse de la (ou les) variable où écrire les valeurs lues
int i;
printf("Entrer un entier : ");
scanf("%d", &i);

170
Le langage C – lecture / écriture
• Lecture / saisie de valeur scanf
• Attend l’adresse de la (ou les) variable où écrire les valeurs lues
int i;
printf("Entrer un entier : ");
scanf("%d", &i);
• Autres formats : idem printf (%c, %ld, %lf, %s)
• scanf est une fonction
• Passage par adresse
• Nombre de paramètres variable, séparés par des virgules
int i ; long j ; double k ;
scanf("%d%ld%lf", &i, &j, &k);

171
Le langage C – lecture / écriture
• Lecture / saisie de valeur scanf
• Attend l’adresse de la (ou les) variable où écrire les valeurs lues
int i;
printf("Entrer un entier : ");
scanf("%d", &i);
• Autres formats : idem printf (%c, %ld, %lf, %s)
• scanf est une fonction
• Passage par adresse
• Nombre de paramètres variable, séparés par des virgules
int i ; long j ; double k ;
scanf("%d%ld%lf", &i, &j, &k);
• Attention : ne pas mettre de \n à la fin ni d’espace entre les %
172
Le langage C – effets de bord
• scanf est un bon exemple de fonction à effets de bord
• "side effect" selon la terminologie anglaise
• Plusieurs définitions plus ou moins strictes
• Signifie que la fonction modifie au moins une variable qui est extérieure à son
environnement local
• Exemple le plus simple : variable globale
• Risque
• Utiliser une variable qui n’a pas la valeur attendue

173
Le langage C – effets de bord
• Une fonction sans effet de bord donne à chaque fois le même
résultat si elle est appelée avec les mêmes paramètres

174
Le langage C – effets de bord
• Une fonction sans effet de bord donne à chaque fois le même
résultat si elle est appelée avec les mêmes paramètres
• L’effet de bord est parfois nécessaire
int i;
scanf("%d", &i);

scanf("%d", &i);

175
Le langage C – effets de bord
• Une fonction sans effet de bord donne à chaque fois le même
résultat si elle est appelée avec les mêmes paramètres
• L’effet de bord est parfois nécessaire
int i;
scanf("%d", &i);

scanf("%d", &i);
• L’effet de bord peut être voulu par le programmeur
→ Il doit être connu et contrôlé

176
Exemples

#include <stdio.h>

void affiche_prix(double v, double t);


double calcul_prix(double p, double t);

void affiche_prix(double v, double t)


{
double prix;
prix = calcul_prix(v, t);
printf("prix = %lf\n", prix);
}

177
Exemples

#include <stdio.h> double calcul_prix(double p, double t)


{
void affiche_prix(double v, double t); return p * t;
double calcul_prix(double p, double t); }

void affiche_prix(double v, double t) int main()


{ {
double prix; double x, y;
prix = calcul_prix(v, t); printf("Entrer prix et taux: ");
printf("prix = %lf\n", prix); scanf("%lf%lf", &x, &y);
} affiche_prix(x, y);
return 0;
}

178
Exemples

#include <stdio.h>

const int facteur_x = 3;


const int facteur_y = 2;

void saisies(int *x, int *y);


void calculs(int *x, int *y);

void saisies(int *x, int *y)


{
scanf("%d%d", x, y);
}

179
Exemples

#include <stdio.h> void calculs(int *x, int *y)


{
const int facteur_x = 3; *x *= facteur_x;
const int facteur_y = 2; *y *= facteur_y;
}
void saisies(int *x, int *y);
void calculs(int *x, int *y); int main()
{
void saisies(int *x, int *y) int a, b;
{ saisies(&a, &b);
scanf("%d%d", x, y); calculs(&a, &b);
} printf("%d %d\n", a, b);
return 0;
}

180
Exemples

#include <stdio.h> scanf("%lf", &v);


if(v < *mi) { *mi = v; }
void permute (int *a, int *b) else if(v > *ma) { *ma = v; }
{ }
int t = *a; int main()
*a = *b; {
*b = t; int a, b; double mini, maxi;
} scanf("%d%d", &a, &b);
void min_max(int n, double *mi, double *ma) permute(&a, &b);
{ printf("%d %d\n", a, b);
int i=1; min_max(10, &mini, &maxi);
double v; printf("%lf %lf\n", mini, maxi);
scanf("%lf", &v); *mi = v; *ma = v; return 0;
for(; i<=n; i++) { }

181
Exemples

#include <stdio.h>

int choix();

int choix()
{
int c = getchar();
if(c == ‘o’ || c == ‘O’) {
return 1;
}
return 0;
}

182
Exemples

#include <stdio.h> int main()


{
int choix(); int a, b;
do {
int choix() printf("Entrer 2 entiers: ");
{ scanf("%d%d", &a, &b);
int c = getchar(); printf("a= %d b= %d\n", a, b);
if(c == ‘o’ || c == ‘O’) { printf("Encore ? (o/n) ");
return 1; } while(choix()) ;
} return 0;
return 0; }
}

183
Exemples

#include <stdio.h> }
}
int compte(int c); return cpt;
}
int compte(int c)
{ int main()
int cpt = 0; {
int ch; int c;
printf("Entrer une ligne: "); printf("Carac. a chercher ? ");
ch = getchar(); c = getchar();
for(; ch != ‘\n’; ch = getchar()) { printf("%d\n", compte(c));
if(ch == c) { return 0;
cpt++; }
→ Problème à l’exécution
184
Exemples

#include <stdio.h> int compte(int c)


{
void nettoyage_buffer(); int cpt = 0;
int compte(char c); int ch;
printf("Entrer une ligne: ");
void nettoyage_buffer() ch = getchar();
{ for(; ch != ‘\n’; ch = getchar()) {
int c; if(ch == c) {
do { cpt++;
c = getchar(); }
} while(c != ‘\n’ && c != EOF) ; }
} return cpt;
}

185
Exemples

#include <stdio.h>

void nettoyage_buffer();
int compte(char c);

int main()
{
int c;
printf("Carac. a chercher ? ");
c = getchar();
nettoyage_buffer();
printf("%d\n", compte(c));
return 0;
}

186

Vous aimerez peut-être aussi