1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait...

129

Transcript of 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait...

Page 1: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.
Page 2: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

2

Convention sur les acétates

• Concernant la présentation des acétates :– malgré le fait qu’elles soient relativement bien remplies, les

acétates tentent de présenter un contenu :• cohérent• facile à suivre • avec un contenu pouvant servir de référence

• Concernant les exemples :– plusieurs exemples sont inclus afin d’illustrer les différents

concepts enseignés– certains exemples contiennent quelques notions plus

avancés à titre de référence– afin d’illustrer davantage les notions du langage C, peu

d’exemple sont en pseudo code

Page 3: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

3

Convention sur les acétates

• Coloration du texte en fonction des éléments du langage C

Mots réservés en bleu Constantes en rougeInstructions en mauve Commentaires en vert

• Format des exemplesStéréotypes de :

déclarations, fonctions, éléments de langage, ...

Exemples de :déclarations, fonctions, éléments de langage, portions de code, programmes, ...

Exemple de pseudo code pour représenter des :algorithmes, éléments logiques, ...

Page 4: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

4

Généralité du langage C

• Importance de la programmation– Que permet la programmation?– Outil technologique incomparable– Donne une longueur d’avance à ceux qui la connaisse– Exemples concrets d’application

• Informatique « utilitaire »– Automatisation de tâches routinières ()

• Informatique de gestion– Gestion de projet

gestion des dépassements de coût, gestion des feuilles de temps, ...– Gestion des ressources – gestion du matériel, gestion du personnel, ...– Gestion de l’information – sauvegarde d’information, base de connaissance, ...

• Informatique industriel– Contrôle de procédé

contrôle industriel, optimisation de systèmes de production, ...– Manipulation de données

acquisition, interprétation, prise de décision, représentation, ...robotique industriel, représentation graphique, vision, réseaux de neurones, ***

Page 5: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

5

Généralité du langage C

• Historique– 1960 – Algol60

très abstrait, donne le Pascal, PL/I et CPL

– 1967 – BCPL par Martin RichardsBasic Combined Programming Language

– 1970 – Langage B par Ken Thompsonafin d’assurer l’évolution de Unix écrit en assembleur, son créateur crée ce langage inspiré du BCPL

– 1972 – Langage C par Dennis Ritchie et Ken Thompsonaprès modification du langage B

Page 6: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

6

Généralité du langage C

• Près du langage machine– initialement destiné à la programmation de système– assembleur évolué

• Langage typé faible– permet l’affectation de types différents– contrairement au langage C++

Page 7: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

7

Généralité du langage C

• Constituants d’un programme– Essentiel

• Fonction main• Utilisation d’instructions de contrôle, de branchement et

d’itération• Utilisation d’instructions d’accès mémoire, d’arithmétique et de

logique

– Possible• Plusieurs fichiers sources référencés par #include• Déclaration, définition et utilisation de fonctions personnalisées• Appel de fonctions provenant des

– déclarations personnalisées– bibliothèques standard

Page 8: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

8

Généralité du langage C

• Exemple d’un programme très simple#include "stdio.h"

/* début du programme */void main(void){

printf("Ceci est un programme simple!");

return;}

Ceci est un programme simple!Ceci est un programme simple!

- aucune entrée -- aucune entrée -Entrée

Sortie

Page 9: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

9

Généralité du langage C

• Exemple d’un programme#include "stdio.h"

/* début du programme */void main(void){

char C;

do {C = getch();printf("%c - %d - %x\n", C, C, C);

} while (C != EOF);

return;}

G - 71 - 47P - 80 - 50A - 65 - 416 - 54 - 366 - 54 - 365 - 53 - 35, - 44 - 2c - 32 - 20J - 74 - 4a' - 39 - 27a - 97 - 61d - 100 - 64o - 111 - 6fr - 114 - 72e - 101 - 65

G - 71 - 47P - 80 - 50A - 65 - 416 - 54 - 366 - 54 - 365 - 53 - 35, - 44 - 2c - 32 - 20J - 74 - 4a' - 39 - 27a - 97 - 61d - 100 - 64o - 111 - 6fr - 114 - 72e - 101 - 65

GPA665, J’adoreGPA665, J’adoreEntrée

Sortie

Page 10: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

10

Généralité du langage C

• Exemple d’un programme#include "stdio.h"

/* début du programme */void main(void){

int i, n, Sum;float Mean;

n = 15;Sum = 0;Mean = 0.0f;for (i = 0; i < n; i++) {

Sum += i;printf("Somme cumulative a l'element

%02d : %03d\n", i, Sum);}

Mean = (float) Sum / n;printf("\nMoyenne des %d element(s) :

%0.2f", n, Mean);

return;}

Somme cumulative a l'element 00 : 000Somme cumulative a l'element 01 : 001Somme cumulative a l'element 02 : 003Somme cumulative a l'element 03 : 006Somme cumulative a l'element 04 : 010Somme cumulative a l'element 05 : 015Somme cumulative a l'element 06 : 021Somme cumulative a l'element 07 : 028Somme cumulative a l'element 08 : 036Somme cumulative a l'element 09 : 045Somme cumulative a l'element 10 : 055Somme cumulative a l'element 11 : 066Somme cumulative a l'element 12 : 078Somme cumulative a l'element 13 : 091Somme cumulative a l'element 14 : 105

Moyenne des 15 element(s) : 7.00

Somme cumulative a l'element 00 : 000Somme cumulative a l'element 01 : 001Somme cumulative a l'element 02 : 003Somme cumulative a l'element 03 : 006Somme cumulative a l'element 04 : 010Somme cumulative a l'element 05 : 015Somme cumulative a l'element 06 : 021Somme cumulative a l'element 07 : 028Somme cumulative a l'element 08 : 036Somme cumulative a l'element 09 : 045Somme cumulative a l'element 10 : 055Somme cumulative a l'element 11 : 066Somme cumulative a l'element 12 : 078Somme cumulative a l'element 13 : 091Somme cumulative a l'element 14 : 105

Moyenne des 15 element(s) : 7.00

- aucune entrée -- aucune entrée -Entrée

Sortie

Page 11: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

11

Généralité du langage C

• Compilateur et éditeur de liens

Compilateur

Fichiers sources

Fichiers objets

Éditeur de liens

Le compilateur transforme les fichiers sources en fichiers objets

L’éditeur de liens transforme les fichiers objets pour générer un programme exécutable

Page 12: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

12

Types de base

• 5 types de base– char, int, float, double et void

• 2 modificateurs de type– Signe (pour les entiers seulement char et int : où b représente le nombre de bit)

• signed (par défaut) : variable [ -2b/2, 2b/2 – 1 ]• unsigned : variable [ 0, 2b – 1]

– Taille mémoire• short : réduit le domaine des valeurs possibles

– uniquement pour int

• long : augmente l’intervalle [min, max] – uniquement pour int et float selon la norme ANSI– certains compilateurs supportent aussi le type double

• Attention au type bool

Page 13: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

13

Types de base

• Le type char– Un seul type, deux interprétations :

• caractère lorsque utilisé en conjonction avec les fonctions de gestion de chaîne de caractères et la table Ascii

• entier autrement

1 bit de signe

7 bits de données

8 bits - 1 octets

signed- 128 £ X £ 127

8 bits de données

8 bits - 1 octets

unsigned0 £ X £ 255

Page 14: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

14

Types de base

• Le type int (16 bits) ou short int

16 bits - 2 octets

15 bits de données

1 bit de signe

signed- 32 768 £ X £ 32 767

16 bits - 2 octets

16 bits de données

unsigned0 £ X £ 65 535

Page 15: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

15

Types de base

• Le type int (32 bits) ou long int

32 bits de données

32 bits - 4 octets

unsigned0 £ X £ 4 294 967 295

31 bits de données

1 bit de signe

32 bits - 4 octets

signed- 2 147 483 648 £ X £ 2 147 483 647

Page 16: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

16

Types de base

• Le type float

32 bits - 4 octets

23 bits de données pour la mantisse

8 bits de données pour l'exposant

1 bit de signe

3.4 ́10-38 £ | X | £ 3.4 ́1038

Page 17: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

17

Types de base

• Le type long float ou double

52 bits de données pour la mantisse

11 bits de données pour l'exposant

1 bit de signe

64 bits - 8 octets

1.7 ́10-308 £ | X | £ 1.7 ́10308

Page 18: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

18

Types de base

• Le type long doubleCe n’est pas un type standard du C ou du C++, il est seulement disponible sur certains compilateurs (par exemple : VisualC++ et C++Builder)

60 bits de données pour la mantisse

19 bits de données pour l'exposant

1 bit de signe

80 bits - 10 octets

3.4 ́10-4932 £ | X | £ 3.4 ́104932

Page 19: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

19

Types de base

• Le type void– Ne permet pas de déclarer une variable– Permet d’indiquer au compilateur que le type est indéfini

pour les cas suivants :• retour de fonction

(aucune valeur de retour)• paramètres d’une fonction

(aucun paramètre passé à la fonction) • pointeur de type indéfini

Page 20: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

20

Éléments du langage et règles d’écriture

• Les identificateurs– Sert à nommer les :

• variables• étiquettes• fonctions

– Constitués d’une suite de lettres et de chiffres commençant par une lettre

• le seul autre caractère permis : '_'

– Il faut faire attention à :• le langage C distingue les majuscules des minuscules• la liste des mots réservés• Les types externes peuvent être restreint à un maximum de 8

caractères pour certains compilateurs

Page 21: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

21

Éléments du langage et règles d’écriture

• Les mots réservés du langage C

auto break case char const continue

default do double else enum extern

float for goto if int long

register return short signed sizeof static

struct switch typedef union unsigned void

volatile while

Page 22: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

22

Éléments du langage et règles d’écriture

• Les commentaires– Pour déterminer une zone de commentaires, on utilise :

• /* pour le début• */ pour la fin

– Attention aux :• imbrications de commentaires• commentaires commençant par //

Page 23: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

23

Éléments du langage et règles d’écriture

• Les instructions– Appel d’un opérateur ou d’une fonction– Plusieurs instructions peuvent être regroupées par un bloc

• Les blocs d’instructions– Défini par des accolades

• { marque le début d’un bloc• } marque la fin d’un bloc

{ /* début d’un bloc d’instructions */

/* instruction 1 *//* ... *//* instruction n */

} /* fin d’un bloc d’instructions */

Page 24: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

24

Éléments du langage et règles d’écriture

• Les expressions– Correspondent à une combinaison d’éléments tel que des :

• identificateurs• constantes• variables• tableaux• pointeurs• structures• unions• appels de fonctions• opérateurs unaires ou binaires• ...• chaque ligne de code excluant celles ayant uniquement des

commentaires

Page 25: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

25

Éléments du langage et règles d’écriture

• Les constantes– Entier :

• octal : commençant par un zéro0145376

• décimal : tel quel 51966

• hexadécimal : commençant par un zéro et un x0xCAFEles majuscules et minuscules fonctionnent

0Xcafe

– Nombre réel• de type float : terminant par f

3.141593f• de type double : tel quel

3.141593

Page 26: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

26

Éléments du langage et règles d’écriture

• Les constantes– Caractère(s)

• un seul caractère selon la table de caractères ASCII : entre apostrophes '0'le caractère zéro est équivalent à l’entier 48

• une chaîne de caractères respectant les normes établies : entre guillemet "GPA665"la chaîne de caractères "GPA665" correspond au tableau de caractères : 71-80-65-54-54-53-0

• il existe plusieurs caractères spéciaux :\a - beep - \\ barre oblique inverse\b retour arrière \' apostrophe\f chargement de page \" guillemet\n saut de ligne \? point d’interrogation\r retour en début ligne \nnn valeur ASCII en

octal\t tabulation horizontale \xnnn valeur ASCII en

hexadécimal\v tabulation verticale \0 fin de la chaîne de caractère

Page 27: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

27

Éléments du langage et règles d’écriture

• Les opérateurs– Unaires – Sont évalués de droite à gauche

• ++ var effectue une pré incrémentation• -- var effectue une pré décrémentation• var ++ effectue une post incrémentation (de gauche à

droite)• var -- effectue une post décrémentation (de gauche à

droite)• (type) exp spécifie une modification de type (« type cast »)• Sizeof() ou sizeof(var ou type) retourne la taille en octet d’une variable ou d’un

type• & var retourne l’adresse de la variable• * exp retourne le contenu de l’adresse spécifiée

(déréférence)• + exp retourne la valeur d’une variable (type numérique)• - exp retourne la valeur négative d’une variable (type

numérique)• ~ exp retourne le complément bit à bit d’une variable• ! exp retourne le complément logique d’une variable

Page 28: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

28

Éléments du langage et règles d’écriture

• Les opérateurs– Binaires – Sont évalués de gauche à droite

• Opérateurs multiplicatifs– exp1 * exp2 retourne le résultat de la multiplication– exp1 / exp2 retourne le résultat de la division– exp1 % exp2 retourne le résultat du modulo (reste de la division

entière)

• Opérateurs additifs– exp1 + exp2 retourne le résultat de l’addition– exp1 - exp2 retourne le résultat de la soustraction

• Opérateurs de décalage de bits– exp1 << exp2 retourne le résultat du décalage à gauche *– exp1 >> exp2 retourne le résultat du décalage à droite *

• Opérateurs relationnels– exp1 < exp2 retourne le résultat de la comparaison est plus petit

que– exp1 > exp2 retourne le résultat de la comparaison est plus grand

que– exp1 <= exp2 retourne le résultat de la comparaison plus petit ou

égal– exp1 >= exp2 retourne le résultat de la comparaison plus grand ou

égal– exp1 == exp2 retourne le résultat de la comparaison est égal à– exp1 != exp2 retourne le résultat de la comparaison est différents de

Page 29: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

29

Éléments du langage et règles d’écriture

• Les opérateurs– Binaires – Sont évalués de gauche à droite (suite)

• Opérateurs sur les bits– exp1 & exp2 retourne le résultat du ET logique bit à bit– exp1 | exp2 retourne le résultat du OU logique bit à bit– exp1 ^ exp2 retourne le résultat du OU EXCLUSIF logique

bit à bit

• Opérateurs logiques– exp1 && exp2 retourne le résultat du ET logique– exp1 || exp2 retourne le résultat de OU logique

• Opérateur d’évaluation séquentielle– exp1 , exp2 effectue les expressions séquentiellement

– Ternaire – Est évalué de gauche à droite– exp ? val1 : val2 retourne val1 si exp est vraie sinon val2

Page 30: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

30

Éléments du langage et règles d’écriture

• Les opérateurs– D’assignation – Sont évalués de droite à gauche

• var = exp assignation directe

• var *= exp assignation suite à la multiplication• var /= exp assignation suite à la division• var %= exp assignation suite au modulo• var += exp assignation suite à l’addition• var -= exp assignation suite à la soustraction• var <<= exp assignation suite au décalage de bits à gauche• var >>= exp assignation suite au décalage de bits à droite• var &= exp assignation suite au ET logique bit à bit• var |= exp assignation suite au OU logique bit à bit• var ^= exp assignation suite au OU EXCLUSIF logique bit à bit

• Ils sont tous équivalent à : var = var opérateur exp

Page 31: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

31

Éléments du langage et règles d’écriture

• Les opérateurs– Autres opérateurs

• ( exp ) - appel de fonction- spécification de priorité dans une expression

• [ exp ] - retourne un élément spécifique d’un tableau (décalage plus déréférence)

• var . élément - retourne l’élément spécifié d’une structure (indirection) ou d’un type union

• var -> élément - retourne l’élément spécifié par le pointeur d’une structure

(indirection)

Page 32: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

32

Éléments du langage et règles d’écriture

• Priorité des opérateursOrdre Opérateurs

1 ( ) [ ] . ->

2 ++ -- +(signe) -(signe) *(déréférence) &(adresse) ! ~ (type)(« type cast ») sizeof

3 *(multiplication) / %

4 +(addition) -(soustraction)

5 >> <<

6 == !=

7 &

8 ^

9 |

10 &&

11 ||

12 ? :

13 = += -= *= /= %= &= ^= |= <<= >>=

14 ,

Si deux opérateurs possèdent la même priorité, ils seront exécuté de gauche à droite selon l’ordre d’apparition sur la ligne d’instruction

Page 33: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

33

Éléments du langage et règles d’écriture

• Les instructions de contrôle– L’instruction conditionnelle if

Attention aux if imbriqués. Utilisez les définitions de bloc.

if ( exp ) inst1 [ else inst2 ]

if (n != 0) {Mean = Sum / n;

} else {printf("Erreur : division par 0");

}

inst1

exp

inst2

vrai faux

Page 34: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

34

Éléments du langage et règles d’écriture

• Les instructions de contrôle– L’instruction conditionnelle switch

switch ( integer-exp ) { [ case constexp1 : inst1 [ break ;] ]...[ case constexpn : instn [ break ;] ][ default : instd ]

}

inst2

exp

inst3

const exp 2

const exp 3

...inst1

const exp 1

instd

sans

bre

ak

sans

bre

ak

sans

bre

ak

sans

bre

ak

const exp ...

default

avec break avec break avec break avec break avec break

Page 35: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

35

Éléments du langage et règles d’écriture

#include <stdio.h>#include <ctype.h>#include <conio.h>#include "Customfunctions.h"

void main(void){

while (1) {printf("Quelle operation voulez-vous faire ?\n");printf("\t1 (Q)uitter\n\t2 (S)auvegarder\n\t 3 (P)oursuivre\n\t4 (M)ettre en veille\n");char Reponse = toupper(getch()); /* Attention */

switch (Reponse) {case 1 :case 'Q' : return;case 2 :case 'S' : SaveData();

case 3 :case 'P' : GetNewData();

AnalyseNewData();break;

case 4 :case 'M' : GotoSleep();

}}

}

Page 36: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

36

Éléments du langage et règles d’écriture

• Les instructions de contrôle– L’instruction itérative while

while ( exp ) inst

while (Answer == 'Y' || Answer == 'y') {DoSomething();

printf("Voulez-vous poursuivre?");Answer = getch();

}

inst

exp

vrai

faux

Page 37: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

37

Éléments du langage et règles d’écriture

• Les instructions de contrôle– L’instruction itérative do

do inst while ( exp );

do {DoSomething();

printf("Voulez-vous poursuivre?");Answer = getch();

} while (Answer != 'N' && Answer != 'n');

inst

expvrai

faux

Page 38: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

38

Éléments du langage et règles d’écriture

• Les instructions de contrôle– L’instruction itérative for

for ( inst1; exp; inst2 ) inst3

#define N 65535int i, Sum, Data[N];

for ( i = 0, Sum = 0; i < N; i++) {Sum += Data[i];

}

inst1

exp faux

inst3

inst2

vrai

Page 39: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

39

Éléments du langage et règles d’écriture

• Les instructions de contrôle– Les commandes de

terminaison sont :• break termine

l’instruction do, for, switch ou while le plus près

• continue passe à la prochaine itération des instructions do, for ou while

• goto passe directement à l’étiquette spécifiée

inst1

exp faux

inst3

inst2

vrai

goto .

bre

ak .

co

ntin

ue .

Page 40: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

40

Éléments du langage et règles d’écriture

• La déclaration d’étiquettes– La fonction goto doit indiquer une étiquette existante dans

le programme.– Les étiquettes sont définies par le deux points

– Les étiquettes doivent obligatoirement être mises devant une instruction pour être valide

identificateur :

Erreur007:

Page 41: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

41

Éléments du langage et règles d’écriture

• La déclaration de nouveaux types– Types synonymes avec typedef

En fait, ceci ne permet pas la déclaration d’un nouveau type mais plutôt d’un synonyme pratique ou pertinent pour l’usager

– Types énumérés avec enumType consistant à contraindre l’affectation de variable à un ensemble de constantes appelées énumérateursenum [ type ] { liste-enumerations } [ variable ] ;typedef enum [ type ] { liste-enumerations } [ type ] ;

typedef declaration-de-type synonyme;

typedef unsigned int uint;typedef unsigned char uchar;typedef uchar Pixel;

enum JourSemaine { Lundi, Mardi, Mercredi, Jeudi, Vendredi } AujourdHui;typedef enum { Rouge, Vert, Bleu } CouleursPrimairesAdditif;typedef enum CouleursPrimaireSoustractif { Jaune, Magenta, Cyan };

Page 42: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

42

Éléments du langage et règles d’écriture

• La déclaration de nouveaux types– Types structurés avec struct

• Nouveau type permettant de contenir plusieurs types existants (sous-types) simultanément pour une même variable.

• Tous les sous-types sont disponibles simultanément.• La taille du nouveau type correspond au minimum à la somme

des tailles de chacun des sous-types.

struct [ type ] { liste-membres } [ variable ] ;typedef struct [ tag ] { liste-membres } type ;

struct Individu { char Nom[64]; int Age; float Taille; } Nicolas, Yan, Philippe;typedef struct refNode { float Data; refNode *Next; } LinkedListNode;

Page 43: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

43

Éléments du langage et règles d’écriture

• La déclaration de nouveaux types– Types unis avec union

• Nouveau type permettant de contenir différents types existants (sous-types) pour une même zone mémoire.

• Puisque tous les sous-types partagent la même zone mémoire, un seul de ces sous-types est disponible à la fois.

• La taille du nouveau type correspond au minimum à la taille du plus grand sous-type.

union [ type ] { liste-membres } [ variable ] ;typedef union [ tag ] { liste-membres } type ;

union Data { float LowPrecision; double HighPrecision; } Temperature;typedef union { char Answer; float Value; } QuestionResult;

Page 44: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

44

Éléments du langage et règles d’écriture

• La déclaration de variables– La déclaration d’une seule variable :

– La déclaration d’un tableau unidimensionnel :

– La déclaration d’un tableau multidimensionnel :

on reviendra plus tard sur les classes de mémorisation

[ classe_de_mémorisation ] type identificateur ;

type identificateur[ taille du tableau ] ;

type identificateur[dim1][dim2][dim_n]... ;

static int Sum;

float Vector[256];

unsigned char ColorImage[640][480][3];

Page 45: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

45

Éléments du langage et règles d’écriture

• La déclaration de variables– La déclaration d’un pointeur :

– On peut déclarer plusieurs variables simultanément :

Attention à la déclaration simultanée de pointeurs!

[ classe_de_mémorisation ] type * identificateur ;

type ident1, ident2, ident3;

int *PtrData;

float n, Sum, Mean, StdDev, Data[256];

Page 46: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

46

Éléments du langage et règles d’écriture

• La déclaration de variables– La déclaration d’une variable constante :

Une variable constante doit être initialisée à même sa déclarationet ne peut jamais être modifiée.

[ classe_de_mémorisation ] const type identificateur = valeur;

const float PI = 3.141592654;

Page 47: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

47

Éléments du langage et règles d’écriture

• L’initialisation de variables– Selon la norme ANSI, le langage C n’initialisent aucun type

automatiquement lors de l’instanciation de variables– Malgré tout, les compilateurs modernes comme VisualC++

initialisent à 0 uniquement les variables provenant des types de base

• char, int, float et double• les pointeurs, tableaux et types personnalisés ne sont pas

initialisés

• malgré tout, faites attention aux optimisateurs de code

Page 48: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

48

Éléments du langage et règles d’écriture

• L’initialisation de variables– Les variables provenant des types de base peuvent être

explicitement initialisées lors de leur déclaration• Pour les variables standard :

• Pour les variables de type union

• Pour les variables de type struct

[ classe_de_mémorisation ] type identificateur = exp;

int IPos = 10, INeg = -10;void *RefPtr = NULL;

typedef union { float NbrReel; int NbrEntier; } Nombre;Nombre N1 = { 3.1416f }, N2 = { 101 }; // les bons types ont été assignés

[ classe_de_mémorisation ] type identificateur = { exp };

typedef struct { char Nom[256]; int Age; float Taille; } Individu;Individu Pianiste = { "Julius Katchen", 43, 1.80 };

[ classe_de_mémorisation ] type identificateur = { exp1, exp2, ... };

Page 49: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

49

Éléments du langage et règles d’écriture

• L’initialisation de variables• Pour un tableau unidimensionnel :

• Pour un tableau multidimensionnel :

type identificateur[ [taille du tableau] ] = { exp1, exp2, exp3, ... };

type ident[dim 1][dim n]... = { ... { exp1, ... }, { expn, ... }, ... };

float ResultatsLabGPA665[3] = { 89.0f, 97.0f, 100.0f };float ResultatsExamGPA665[] = { 78.0f, 84.5f }; /* intéressant */

int Input[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };

Page 50: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

50

Éléments du langage et règles d’écriture

• Éléments de langage particuliers aux pointeurs– Opérateurs d’adressage et de déréférence

• On utilise & pour obtenir l’adresse d’une variable ou d’une fonction préalablement allouée

• On utiliser * (la déréférence) pour accéder au contenu « pointé » par une adresse

int Nombre1, Nombre2;int *PtrNbr;

Nombre1 = 666;PtrNbr = &Nombre1;

Nombre2 = *PtrNbr;

Page 51: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

51

Éléments du langage et règles d’écriture

• Éléments de langage particuliers aux types composés– Accès aux membres des types composés union ou struct

• On utilise l’opérateur d’indirection . (point) pour accéder à un membre particulier

• Pour les accès via un pointeur, on peut utiliser :– une combinaison du point et de la déréférence – l’opérateur d’indirection ->

typedef struct { char Nom[256]; int Age; float Taille; } Individu;

Individu Employe1, Employe2, *RefEmp1, *RefEmp2;

Ref1Emp = &Employe1;Ref2Emp = &Employe2

RefEmp1->Age = 2 * (*RefEmp2).Age;

Page 52: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

52

Éléments du langage et règles d’écriture

• Éléments de langage particuliers aux tableaux– Accès aux éléments d’un tableau

• On utilise l’opérateur de déréférence avec décalage [ ] pour accéder à un élément spécifique d’un tableau

• On peut aussi utiliser l’opérateur de déréférence avec l’arithmétique des pointeurs

float NotesExam[] = { 84.0f, 68.0f, 90.5f };float PonderationsExam[] = { 0.30f, 0.30f, 0.40f };

float ResultatFinal = 0.0f;

for (int i = 0; i < 3; i++) { /* Attention a la declaration de i */ResultatFinal += NotesExam[i] * PonderationsExam[i];

}

Page 53: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

53

Éléments du langage et règles d’écriture

• Éléments de langage particulierstypedef char String[256];

typedef union {String Nom;int NoRef;

} IDRef;

struct Individu { IDRef ID;int Age; String SignesDistinctifs;

} Professeur, ChargeDeCours, ChargeDeLab;Individu *Ref[3] = { &Professeur, &ChargeDeCours, &ChargeDeLab };

strcpy(Professeur.ID.Nom, "Mohamed Cheriet");ChargeDeCours.ID.NoRef = 12345;strcpy(ChargeDeLab.ID.Nom, "Yan Levasseur");ChargeDeLab.Age = 25;strcpy(ChargeDeLab.SignesDistinctifs, "Intellectuellement superieur");

(*Ref[0]).Age = Ref[2]->Age << 1;

Page 54: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

54

Éléments du langage et règles d’écriture

• Les fonctions– Les fonctions sont des entités permettant de regrouper

plusieurs instructions et expressions en un sous-ensemble disjoint, autonome et fonctionnel.

– Entre autre, elles aident à la lisibilité, la modularité et la réutilisabilité du code /* Syntaxe moderne */[ classe-mémorisation ] type-retour identificateur( [ type1 param1, ... ] ){

exp1exp2...

[ return [ ( ] [ exp-retour ] [ ) ] ; ]}

float Square(float Data){

return Data * Data;}

Page 55: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

55

Éléments du langage et règles d’écriture

• Les instructions au préprocesseur– Ces instructions servent à donner des instructions

préalables au compilateur. – Elles sont faciles à reconnaître car elles sont tous précédés

de #• Inclusion de fichiers avec #include. Permet de faire référence

au contenu d’un ou plusieurs autres fichiers externes.#include "nom_de_fichier" /* recherche locale + catalogue système */#include <nom_de_fichier> /* recherche catalogue système uniquement */

#include "mes_propres_fonctions.h"#include <math.h>

void main(void){

printf("Le racine carre de 9 est : %lf", sqrt(9.0));printf("La racine cubique de 27 est : %lf", cubicroot(27.0));

}

Page 56: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

56

Éléments du langage et règles d’écriture

• Les instructions au préprocesseur• Les commandes de compilation conditionnelle sont :

– #if équivalent du if– #elif équivalent à un else if– #else équivalent au else– #endif indique la terminaison du bloc if– #ifdef si une étiquette est définie– #ifndef si une étiquette n’est pas définie

#if exp1inst1

#elif exp2inst2

#elseinst3

#endif

Page 57: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

57

Éléments du langage et règles d’écriture

• Les instructions au préprocesseur– #define et #undef permettent de déclarer de nouvelles

définitions ou d’annuler des définitions existantes. Ces définitions permettent au programmeur de nommer des éléments du programme comme des constantes et des étiquettes de référence.

#define identificateur expression#undef identificateur

#include "Constantes.h"

void main(void){

printf("Le nombre pi est : %0.6lf", PI);}

#ifndef _CONSTANTES_H#define _CONSTANTES_H

#define PI 3.141592654

#endifConstantes.h

Programme.c

Page 58: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

58

Éléments du langage et règles d’écriture

• Les instructions au préprocesseur• #define permet aussi de définir des macro. Les macros

ressemblent à des fonctions sans définition de type.

#define nom_macro(param1, param2, ...) expression

#define Max(Val1, Val2) ((Val1) > (Val2) ? (Val1) : (Val2))

void main(void){

int N1 = 100, N2 = 500;printf("Le maximum entre les nombres %d et %d est : %d",

N1, N2, Max(N1, N2));}

Page 59: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

59

Éléments du langage et règles d’écriture

• Les instructions au préprocesseur• Pourquoi éviter les macros ?

• En fait, l’utilisation du #define correspond à un copier/coller avant la compilation.

#define Max(Val1, Val2) ((Val1) > (Val2) ? (Val1) : (Val2))#define Square(Val) a*a

void main(void){

int A, *B;A = Max('a', B); /* Compile malgré les types incompatibles */

int i = 1, j = 2;A = Max(++i,++j); /* On s’attend à 3 alors qu’on obtient 4 */

double X = 3, Y;Y = Square(X + 1); /* On s’attend à 16 alors qu’on obtient 7 */

}

Page 60: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

60

Principales fonctions provenant des bibliothèques standard

• stdio.h– fopen ouverture d’un fichier– fclose fermeture d’un fichier– ferror vérifie si il y a eu une erreur avec un fichier– feof vérifie si un fichier est arrivé à la fin– fgetpos détermine un indicateur pour la position courante

d’un fichier

– fsetpos positionne un fichier selon un indicateur de position– ftell retourne la position d’un fichier– fseek positionne un fichier selon un décalage spécifié– fread lit des données provenant d’un fichier à partir de la

position courante– fwrite écrit des données dans un fichier

Page 61: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

61

Principales fonctions provenant des bibliothèques standard

• stdio.h– fgets lit une chaîne de caractères provenant d’un fichier– gets lit une chaîne de caractères provenant de l’entrée

standard– fputs écrit une chaîne de caractères dans un fichier– puts écrit une chaîne de caractères à la sortie standard– fgetc lit un caractère provenant d’un fichier– getc lit un caractère provenant de l’entrée standard– fputc écrit un caractère dans un fichier– putc écrit un caractère à la sortie standard– stdin constante de redirection vers l’entrée standard– stdout constante de redirection vers la sortie standard– stderr constante de redirection vers la sortie d’erreur

standard

Page 62: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

62

Principales fonctions provenant des bibliothèques standard

• stdio.h– printf* écrit une chaîne de caractères mise en forme vers la

sortie standard– sprintf écrit une chaîne de caractères mise en forme dans une

variable de type chaîne de caractères– fprintf écrit une chaîne de caractères mise en forme dans un

fichier– scanf* lit une chaîne de caractères mise en forme provenant de

l’entrée standard– sscanf lit une chaîne de caractères mise en forme provenant

d’une variable de type chaîne de caractères– fscanf lit une chaîne de caractères mise en forme provenant

d’un fichier

Page 63: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

63

Principales fonctions provenant des bibliothèques standard

• stdlib.h– NULL déclaration du pointeur NULL– malloc allocation d’un bloc de mémoire – calloc allocation d’un bloc de mémoire initialisé à zéro– realloc réallocation d’un bloc de mémoire– free libération d’un bloc de mémoire alloué– system exécute une commande du système d’exploitation– exit termine l’exécution du programme en cours– atoi conversion d’une chaîne de caractères en valeur

numérique entière– atof conversion d’une chaîne de caractères en valeur

numérique réelle

Page 64: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

64

Principales fonctions provenant des bibliothèques standard

• memory.h– memcpy copie un bloc mémoire d’un endroit à un autre– memcmp compare deux blocs mémoire caractère par

caractère – memset initialise chaque octet d’un bloc mémoire par la

valeur d’un octet spécifié

Page 65: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

65

Principales fonctions provenant des bibliothèques standard

• math.h– cos retourne le cosinus d’un angle en radian– acos retourne, en radian, l’arcosinus d’un nombre– cosh retourne le cosinus hyperbolique d’un angle en

radian– sin retourne le sinus d’un angle en radian– asin retourne, en radian, l’arcsinus d’un nombre – sinh retourne le sinus hyperbolique d’un angle en radian– tan retourne, la tangente d’un angle en radian– atan retourne, en radian, la tangente d’un nombre– atan2 retourne, en radian, la tangente d’un nombre– tanh retourne la tangente hyperbolique d’un angle en

radian

Page 66: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

66

Principales fonctions provenant des bibliothèques standard

• math.h– pow calcule un nombre à la puissance d’un autre– exp calcule l’exponentiel d’un nombre (en)– log calcule le logarithme naturelle d’un nombre– log10 calcule le logarithme en base 10 d’un nombre– sqrt calcule la racine carrée d’un nombre– abs calcule la valeur absolue d’un nombre entier– fabs calcule la valeur absolue d’un nombre réel– div effectue une division entière– floor retourne l’arrondi inférieur d’un nombre– ceil retourne l’arrondi supérieur d’un nombre– srand détermine un point de départ pour la génération d’un

nombre pseudo aléatoire– rand génère un nombre pseudo aléatoire

Page 67: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

67

Principales fonctions provenant des bibliothèques standard

• string.h– strlen retourne la longueur d’une chaîne de caractères– strset initialise une chaîne de caractères à un caractère

spécifique– strcpy copie une chaîne de caractères– strncpy copie n caractères provenant d’une chaîne de

caractères – strcmp compare deux chaînes de caractères– strncmp compare n caractères provenant de deux chaînes

de caractères

– strcat concatène deux chaînes de caractères– strncat concatène n caractères d’une chaîne de caractères

dans une autre

Page 68: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

68

Principales fonctions provenant des bibliothèques standard

• string.h– strchr recherche un caractère spécifique dans une chaîne

de caractères

– strstr recherche une chaîne de caractères spécifique à l’intérieur d’une chaîne de caractères

– strtok recherche la prochaine occurrence d’un « token » dans

une chaîne de caractères

Page 69: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

69

Principales fonctions provenant des bibliothèques standard

• ctype.h– isdigit identifie si un caractère est numérique– isalpha identifie si un caractère est alphabétique– islower identifie si un caractère est en minuscule– isupper identifie si un caractère est en majuscule– tolower convertie un caractère à un caractère minuscule– toupper convertie un caractère à un caractère majuscule

Page 70: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

70

Portée et durée de vie des variables

• Gestion d’une variable par le compilateur C– Les 2 points essentiels suivants :

• le domaine de validité d’une variable (couramment appelé le « scope », la portée ou la visibilité)

• la durée de vie de la variable (c’est-à-dire la durée pendant laquelle la variable existe vraiment)

sont déterminés par :• l’emplacement de la définition de la variable• la classe de mémorisation utilisée à sa déclaration

(« storage class »)

Page 71: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

71

Portée et durée de vie des variables

• La notion de variable globale et locale est directement liée à l’emplacement de la déclaration– Par définition, une variable est visible par toutes les

fonctions et les expressions de code qui suit sa déclaration si ces dernières sont à un niveau de bloc égal ou inférieur.

– Les variables globales :• Elles sont déclarées hors de toute fonction• Elles sont donc connues, valides et utilisables dans tout le

fichier où elle est définie; cela à partir de l’endroit de sa déclaration. Selon sa classe de mémorisation, elle peut même s’étendre à d’autres fichiers.

– Les variables locales :• Elles sont définies à l’intérieur d’un bloc ou d’une fonction. Par

définition, elles sont donc visibles, valides et utilisables uniquement pour ces blocs ou fonctions.

Page 72: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

72

Portée et durée de vie des variables

• Description des classes de mémorisation– Chaque variable possède une seule classe de mémorisation

parmi les suivantes :• auto• static• extern• register

– Les variables globales ne peuvent être que des classes extern ou static

Page 73: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

73

Portée et durée de vie des variables

• Description des classes de mémorisation pour les variables locales :– auto (pour « automatic ») est la classe de mémorisation par

défaut. Le bloc dans laquelle elles sont définie détermine leur visibilité et leur durée de vie.

– static Cette classe de mémorisation indique que la portée d’une variable est la même que pour une variable auto mais que sa durée de vie correspond à celle du programme.

[ auto ] type identificateur ;

auto int Sum;float Average;

static type identificateur ;

static int Flag;

Page 74: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

74

Portée et durée de vie des variables

• Description des classes de mémorisation pour les variables locales (suite) :– extern Cette classe de mémorisation est particulière car

elle n’entraîne pas d’allocation mémoire. Elle fait plutôt référence à une autre variable existante du même nom ailleurs dans le programme.

– register Ces variables obéissent aux même règles que celles de type auto. La différence vient du fait que le compilateur tente de la placé à même les registres du CPU plutôt que dans la mémoire de travail.

extern type identificateur ;

extern int VersionNoSofware;

register type identificateur ;

register int i, j, k, l;

Page 75: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

75

Portée et durée de vie des variables

• Description des classes de mémorisation pour les variables globales :– extern Est la classe de mémorisation par défaut. Leur

portée est au moins le fichier où elle sont déclarées et peut être étendue à plusieurs fichiers. Leur durée de vie sont celle du programme.

– static Leur durée de vie est la même que pour les variables globales extern. Leur portée inclue le fichier de leur déclaration mais ne peut être étendue à d’autres fichiers.

extern type identificateur ;

extern int GlobalInformation;

static type identificateur ;

static int RegionalInformation;

Page 76: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

76

Portée et durée de vie des variables

• Résumé sur la portée et la durée de vie des variables :

auto*

static

register

extern*

static

Variables locales

Variables globales

Classe de mémorisation Portée Durée de vie

bloc

bloc

bloc

Fichier source + fichiers référencés

Fichier source

bloc

programme

bloc

programme

programme

Page 77: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

77

Portée et durée de vie des variables

#include <stdio.h>

int VarGlobale1 = 1; /* Variable globale */

void main(void){

int VarLocaleMain = 2; /* Variable locale au main */

if (VarLocaleMain >= 0) {int VarLocalBlocIf = 321; /* Variable locale */

} /* visible dans le bloc if */

printf("%d, %d, %d\n", VarGlobale1, VarLocaleMain, Fonction(54321));}

int VarGlobale2 = 123; /* Variable globale invisible par le main */

int Fonction(int Val){

int VarLocaleFonction = Val; /* Variable locale à la fonction */

return VarLocaleFonction * VarGlobale1 * VarGlobale2;}

Page 78: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

78

Rappel général sur les pointeurs

• Un pointeur est une variable dont le contenu a pour valeur une adresse en mémoire.

• Le type du pointeur correspond au type de la variable pointée. En fait, ce typage ne sert au compilateur qu’à souligner au programmeur les erreurs potentielles lorsqu’elles surviennent.

• Tous les pointeurs sans exception ont 32 bits (en considérant un environnement 32 bits tel que Windows)

• Attention à l’opérateur * puisqu’il est le seul élément syntaxique du langage C à avoir 3 sens différents selon le contexte :– La multiplication dans une expression mathématique– La déclaration d’un pointeur dans une déclaration de variable– La déréférence d’un pointeur pour accéder au contenu de l’adresse

mémoire référencée

Page 79: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

79

Représentation schématique de la mémoire

• Afin de bien comprendre l’état des pointeurs il est pratique de schématiser l’état de la mémoire.

• Une astuce efficace consiste à observer l’évolution d’un programme ligne par ligne en faisant le suivi de toutes les variables par la représentation par case.

• Pour chaque allocation ou libération d’une variable, on crée ou détruit une case représentant la variable à suivre.

• Ensuite, pour chaque affectation, comparaison ou manipulation de ces variables, on s’assure que les types sont compatibles et que chacune des instructions correspondent bien à ce qui est souhaité. Variable standard Variable de type constant

• On assigne les adresses arbitrairement à titre de référence.

Adresse

Type de la var.

Nom de la variable

Valeur

-

Type de la var.

Nom de la variable

Valeur

Page 80: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

80

Représentation schématique des pointeurs

• Que pensez-vous de ce petit programme?void main(void){

int V1, *P1; /* 01 */int *P2, V2; /* 02 */

/* 03 */P1 = &V1; /* 04 */P2 = &V2; /* 05 */

/* 06 */V1 = 100; /* 07 */V2 = *P1; /* 08 */*P2 = 2.0 * *P1; /* 09 */

/* 10 */int V3 = P1; /* 11 */ /* Attention! Est-ce que ça compile? */int *P3 = V1; /* 12 */ /* Attention! Est-ce que ça compile? */

}

Page 81: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

81

Pointeurs multiples

• Partant du fait qu’un pointeur est une variable dont le contenu indique l’endroit en mémoire du contenu d’une autre variable de n’importe quel type. Qu’arrive-t-il si nous désirons utiliser un pointeur indiquant un autre pointeur?

• On déclare les pointeurs multiples par l’utilisation de plusieurs *. En fait, on utilise autant d’astérisque que d’indirection nécessaire. [ Classe_de_memorisation ] type ***...* identificateur ;

int Value;int *PtrLevel1, **PtrLevel2, ***PtrLevel3;

PtrLevel1 = &Value;PtrLevel2 = &PtrLevel1; PtrLevel3 = &PtrLevel2Value = 10;*PtrLevel1 = 100;**PtrLevel2 = 1000;***PtrLevel3 = 10000;

Page 82: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

82

Pointeurs et structures

• On revient sur les opérateurs d’indirection pour s’assurer de bien les maîtriser.

typedef struct {int NoCivique; /* No civique */char Rue[256]; /* Nom de la rue */char Ville[128]; /* Nom de la ville */

} Adresse;

typedef struct {char Nom[256]; /* Nom de l’individu */int Age; /* Age en annee de l’individu */int *RefNoCoursGPA; /* Numero du cours suivi en GPA */Adresse *RefAd; /* Reference vers une adresse */

} Individu;

/* Declaration et initialisation */Adresse Residence1 = { 1100, "Notre-Dame Ouest", "Montreal" };Adresse Residence2 = { 666, "Rue de la fin du monde", "St-Isidor de l’Apocalypse" };int CoursInteressantDeGPA = 665;Individu Justin = { "Justin B. Sil", 24, &CoursInteressantDeGPA, &Residence1 };Individu Jay = { "Jay Latrouille", 23, &CoursInteressantDeGPA, &Residence2 };Individu *Personne = &Jay;

int NoCiviqueQuelconque = Jay.RefAd->NoCivique; /* ou (*Jay.RefAd).NoCivique */int AgeQuelconque = Personne->RefAd.Age; /* ou (*Personne).RefAd.Age */int NoCoursQuelconque = *Justin.RefNoCoursGPA; /* est-ce correct? */

Page 83: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

83

Rappel général sur les tableaux

• Un tableau est un ensemble de variable de même type. • Un tableau est toujours constitué de deux parties :

– l’espace des données qui est toujours contiguë en mémoire– une référence de type pointeur indiquant toujours le début du

tableau

int Tableau[5] = { 10, 100, 1000, 10000, 1000000 };

-

const int*

Tableau

0x1000

0x1000

int

-

10

0x1004

int

-

100

0x1008

int

-

10000

0x100C

int

-

100000

0x1010

int

-

1000000

Page 84: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

84

Rappel général sur les tableaux

• Contrairement aux allocations dynamiques que nous verrons plus loin, les allocations statiques de tableaux ne génèrent pas d’allocation mémoire pour le pointeur de référence.

• Ce pointeur est constant et ne peut être modifié.• Les tableaux réservent le nombre d’octets suivant :

taille tableau = sizeof(type) * nombre d’éléments

• Quels sont les tailles des tableaux suivants?unsigned short int Data1[5];int Data2[] = { 0, 1, 2, 3, 4, 5, 6, 7 };double Data3[10][10];

typedef struct { char Nom[256]; char Age; float Poids; int NoReference; } Individu;Individu Pierre[1], Jean[100], Jacques[5][10][2];

Page 85: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

85

Relation étroite entre pointeurs et tableaux

• Puisque tous les tableaux sont référencés par un pointeur, il est souvent pratique et pertinent d’affecter l’adresse de départ d’un tableau à un pointeur.

• Les tableaux sont toujours passés aux fonctions par leur adresse de départ. Il est impossible de passer un tableau par son contenu à une fonction.

• Il est aussi impossible qu’une fonction retourne le contenu d’un tableau, elle ne peut que retourner l’adresse du tableau

• Dans le but d’accélérer certains processus, il est parfois efficace d’exécuter certaines opérations sur un tableau à l’aide des pointeurs et de ne pas utiliser les opérateurs [ ] pour chaque accès au tableau.

Page 86: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

86

Arithmétique sur les pointeurs

• Les opérateurs d’addition, de soustraction, d’incrémentation ou de comparaison sont permis sur les pointeurs. Ils permettent le calcul de décalage entre une adresse de base et une adresse souhaitée.

• Tous ces calculs sont automatiquement gérés par le compilateur en fonction de la taille du type de référence du pointeur.#define TABLE_SIZE 5const float CND_TO_USD = 1.2ffloat CNDCost[TABLE_SIZE] = { 10.25f, 2.12f, 399.99f, 32.77f, 0.12f };short int Quantity[TABLE_SIZE] = { 3, 12, 2, 8, 193 };float GlobalUSDCost;unsigned short int i;

/* Cout global en dollard americain */GlobalUSDCost = 0.0f;for (i = 0; i < TABLE_SIZE; i++) {

GlobalUSDCost += CNDCost[i] * CND_TO_USD * Quantity[i];}

i = 0;GlobalUSDCost = 0.0f;short int *CurrentQuantity = Quantity, *PostLastQuantity = Quantity + TABLE_SIZE;while (CurrentQuantity < PostLastQuantity) {

GlobalUSDCost += *(CNDCost + i++) * CND_TO_USD * *CurrentQuantity++;}

Page 87: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

87

Arithmétique sur les pointeurs

• Que se passe-t-il exactement avec ces lignes de code?pour faire le suivi, on retire les lignes qui ne compilent pas et celles qui causent un débordement de mémoire

int A[] = { 1, 2, 3, 4, 5 };int a = 0x100;int *pA = A, *pa = &a, **ppA = &pA;

a = A; /* 01 */a = *A; /* 02 */a = A[0] * 0; /* 03 */a = pA; /* 04 */a = *pA; /* 05 */a = pA[0] + 0; /* 06 */a = pa; /* 07 */a = *pa * 0; /* 08 */a = pa[0]; /* 09 */*pa = *pA; /* 10 */*(pA + 3) = *(pa + 3); /* 11 */A[3] = a[3]; /* 12 */a = A[5]; /* 13 */A[1] = A[2]; /* 14 */*(pA – 1) = a; /* 15 */A = pA[2]; /* 16 */a *= *A * *(A + *(pA + 1)); /* 17 */a = --*pA++; /* 18 */(A + 2)[2] = (*pa + 2) * *(pA – 1); /* 19 */*(ppA[0] + 3) = (*ppA + 2)[0]; /* 20 */

Page 88: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

88

Particularité des chaînes de caractères

• Le langage C et même le langage C++ n’offrent aucun type de base correspondant à une chaîne de caractères (string).(par contre, il existe plusieurs implémentations de classes performantes pour en faire la gestion en C++ – voir la bibliothèque STL à titre d’exemple)

• La façon de gérer les chaînes de caractères est simplement par l’usage d’un tableau de type char.

• Par convention, on utilise le caractère '\0' (correspondant à la valeur 0) pour identifier la fin d’une chaîne de caractères.

• Ainsi, la longueur d’une chaîne de caractères ne correspond pas nécessairement à la place qu’elle prend en mémoire.

• La déclaration d’une chaîne de caractères constante et toutes les fonctions des bibliothèques standard respectent cette convention. C’est pourquoi il est important de la suivre.char Discipline[] = "Gymnastique";char Prenom[256] = "Kassandra";

Page 89: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

89

Comment le C gère les allocations mémoire

• Les compilateurs basés sur le langage C gèrent automatiquement toutes les allocations mémoire provenant des déclarations standard.

• Ils gèrent à la fois les allocations, les initialisations (lorsque pratiquées) et les libérations de la mémoire au moment opportun.

• Puisque toutes ces opérations sur la mémoire sont connues au moment de la compilation, le programme, lorsqu’il est compilé et généré, contient déjà toutes les instruction de gestion de la mémoire (gestion fixe et immuable)

• C’est ce mécanisme qu’on appel la gestion statique de la mémoire.

Page 90: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

90

Comment le C gère les allocations mémoire

• Avec les fonctions malloc et free, il est possible de faire soi même la gestion de la mémoire au moment opportun – c’est ce qu’on appel la gestion dynamique de la mémoire.

• Il est essentiel de libérer soi même la mémoire réservée. Sans quoi votre programme présentera des fuites de mémoire (« memory leak »).

• Aucune allocation dynamique ne fait l’initialisation du contenu des variables créées.

void * malloc(int taille-en-octet);

void free(void * bloc-memoire);

int *VariableQuelconque = (int*) malloc(sizeof(int));...*VariableQuelconque = 10;...free(VariableQuelconque);

Page 91: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

91

Comment le C gère les allocations mémoire

• Alors pourquoi utiliser la gestion dynamique de la mémoire?

• Cette liberté supplémentaire, malgré le fait qu’elle complexifie la lecture du code, permet de créer des programmes :– plus flexibles;– plus performants;– plus modulaires; – mieux structurés.

Page 92: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

92

Comment le C gère les allocations mémoire

• L’un des exemples les plus flagrant est l’instanciation d’un tableau :– Les allocations statiques de tableaux nécessitent de connaître la

taille du tableau au moment de la compilation (« compile time »). Puisqu’il arrive souvent qu’on ne connaisse pas la taille réelle requise pour un tableau à ce moment, il est courrant de déterminer la taille de ce dernier égal au pire des cas possibles. Ainsi, cette pratique engendre souvent des contraintes importantes :

• mémoire réservée inutilement qui peut ne jamais servir (ou très rarement)

• le tableau alloué peut ne pas pouvoir accueillir toutes les données requises pour une application => le programme est limité et ne peut réaliser toutes les tâches auxquelles il est destiné

– Les allocations dynamiques permettent d’allouer un tableau de la taille voulue à l’instant voulu (au « run time »). Les possibilités sont vastes et permettent d’allouer exactement la mémoire requise et de gérer celle-ci de façon optimale.

Page 93: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

93

La différence entre les deux types d’allocation

• On se sert souvent des allocations dynamiques pour allouer des tableaux dont la taille est indéfinie au moment de la compilation.

• Il existe une différence notable entre un tableau alloué statiquement et dynamiquement : la référence du tableau nécessaire à l’exécution du programme.int TableauStatique[3] = { 0, 1, 2 };int *TableauDynamique = (int*) malloc(sizeof(int) * 3);

0x30CA

int*TableauDynamique

0x2000

-

const int*TableauStatique

0x1000

0x1000

int-

1

0x1004

int-

2

0x1008

int-

3

0x2000int

-?

0x2004int

-?

0x2008int

-?

Page 94: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

94

La différence entre les deux types d’allocation

• Puisque le contenu de tout les tableaux statique est contiguë en mémoire (qu’il soit unidimensionnel ou multidimensionnel), c’est le compilateur qui gère les décalages selon l’adresse de départ pour chaque accès mémoire.

• Pour les allocations dynamiques de tableaux multidimensionnels, le compilateur ne peut calculer les décalages souhaités étant donné qu’il ne connaît pas la taille nominale de chacune des dimensions au moment de la compilation. Il existe alors deux solutions qui se présentent :– la gestion explicite des décalages par le programmeur;– la déclaration

de plusieurs tableaux en cascade.

int int int int int int int int

int int int int int int int int

int int int int int int int int

int int int int int int int int

int int int int int int int int

int*

int*

int*

int*

int*

int**

Page 95: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

95

La différence entre les deux types d’allocation

const int TABLE_SIZE_X = 2, TABLE_SIZE_Y = 3;float StaticMatrix[TABLE_SIZE_X][TABLE_SIZE_Y];float *DynMatrixByOffset;float **DynMatrixByCascade;int i, x, y;

/* Allocation dynamique par gestion de décalage */DynMatrixByOffset = (float*) malloc(sizeof(float) * TABLE_SIZE_X * TABLE_SIZE_Y);/* Allocation dynamique par cascade */DynMatrixByCascade = (float**) malloc(sizeof(float*) * TABLE_SIZE_X);for (i = 0; i < TABLE_SIZE_X; i++)

DynMatrixByCascade[i] = (float*) malloc(sizeof(float) * TABLE_SIZE_Y);

/* Initialisation de tous les elements de chaque matrices a 0 */for (x = 0; x < TABLE_SIZE_X; x++) {

for (y = 0; y < TABLE_SIZE_Y; y++) {StaticMatrix[x][y] = 0;DynMatrixByOffset[x + y * TABLE_SIZE_X] = 1; /* gestion explicite des décalages

*/DynMatrixByCascade[x][y] = 2;

}}

/* Liberation de la matrice dynamique par gestion de décalage */free(DynMatrixByOffset);/* Liberation de la matrice dynamique par cascade */for (i = 0; i < TABLE_SIZE_X; i++)

free(DynMatrixByCascade[i]);free(DynMatrixByCascade);

Page 96: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

96

La différence entre les deux types d’allocation

-

const float*StaticMatrix

0x1000

0x1000

float-

0

0x1004

float-

0

0x1008

float-

0

0x100C

float-

0

0x1014

float-

0

0x2000

float-

1

0x2004

float-

1

0x2008

float-

1

0x200C

float-

1

0x2014

float-

1

0xA000

float*DynMatrixByOffset

0x2000

0x2010

float-

1

0x1010

float-

0

0x3000

float*-

0x5000

0x3004

float*-

0x4000

0x5000

float-

2

0x5004

float-

2

0x4B80

float**DynMat.ByCascade

0x3000

0x5008

float-

2

0x4000

float-

2

0x4004

float-

2

0x4008

float-

2

Page 97: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

97

En général

• Paramètres d’une fonction :– on appel la signature la liste des types qui sont passés à

une fonction– tous les types peuvent être passés à une fonction à titre

d’argument mais :• les tableaux doivent être passés par leur adresse• les structures sont copiés bit à bit

– il est possible de spécifier l’absence de paramètre à une fonction par :

• l’usage du mot clé void • en laissant l’intérieure des parenthèses vide

– on appel fonctions ellipsis celles dont le nombre d’argument est variable (comme printf et scanf)

Fonction1(); /* retourne : int - parametres : aucun */void Fonction2(void); /* retourne : rien - parametres : aucun */void* Fonction3(void*); /* retourne : pointeur void – parametres : pointeur void */float Fonction4(int, int); /* retourne : float - parametres : 2 int */

Page 98: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

98

En général

• Type de retour :– une fonction doit retourner :

• un des types élémentaires ou un pointeur quelconque• le langage C++ permet de retourner tous les types• les tableaux sont toujours retournés par leur adresse• les types structurés sont copié bit-à-bit

– si aucun type de retour n’est spécifié, le type de retour par défaut est l’entier – int

– l’usage du mot clé void comme type de retour indique que la fonction ne retourne aucune valeur

Page 99: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

99

En général

• Terminer une fonction– l’instruction return permet la terminaison d’une fonction à

n’importe quel endroit– return peut retourner une valeur ou non dépendamment du

type de retour spécifié lors de la déclarationreturn; /* l’utilisation du return a la fin d’une fonction est facultatif */return Resultat; /* lorsqu’on retourne une valeur, on peut la mettre ou non entre ...

*/return(Result); /* parenthèse */

Page 100: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

100

Portée des fonctions

• De façon semblable à la déclaration des variables, l’accessibilité ou la visibilité des fonctions est déterminée par :– l’emplacement de la déclaration– la classe de mémorisation utilisée à sa déclaration

(« storage class ») • L’emplacement de la déclaration d’une fonction

détermine le point à partir duquel celle-ci peut être utilisée.

• Comme certains types de données, une fonction peut être déclarée avant d’être définie. On utilise souvent les « header files » (*.h) pour déclarer les fonctions.

Page 101: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

101

Portée des fonctions

#include <stdio.h>

struct Individu; /* Individu est declare avant sa definition */int Age(Individu *I, int AnneeCourante);

struct Individu { char Prenom[32]; char Nom[32]; int AnneeNaissance; };

void main(void){ char* Nom(Individu*, char*); /* Le nom des variables ne sont pas

necessaires */

Individu Scientifique = { "Albert", "Einstein", 1879};char Temp[256];

printf("Monsieur %s a %d an(s)", Nom(&Scientifique, Temp), Age(&Scientifique, 2006));}

int Age(Individu *I, int AnneeCourante){

return AnneeCourante - I->AnneeNaissance;}

char* Nom(Individu *I, char *CC){

sprintf(CC, "%s %s", I->Prenom, I->Nom);return CC;

}

Monsieur Albert Einstein a 127 an(s)Monsieur Albert Einstein a 127 an(s)

- aucune entrée -- aucune entrée -Entrée

Sortie

Page 102: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

102

Portée des fonctions

• Description des classes de mémorisation des fonctions :– extern (par défaut) La fonction est une entité globale et

peut être utilisée partout où elle est référencée.

– static L’utilisation de la fonction est limitée dans le module où elle a été définie.

[ extern ] type-retour identificateur( [ type1 param1, ... ] ) ...

extern int NombreDeCaractere(char *ChaineCaracteres);

[ static ] type-retour identificateur( [ type1 param1, ... ] ) ...

static void InverserChaineCaracteres(char *ChaineCaracteres);

Page 103: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

103

Mécanismes d’appel d’une fonction

• De par la nature des microprocesseurs, lorsqu’une fonction est appelée, il est essentiel de sauvegarder plusieurs informations nécessaires au déroulement du programme.

• On utilise la pile du système pour y enregistrer momentanément les informations pertinentes.

• Tous les appels de fonction gérés par le compilateur fonctionnent de la même façon, peu importe leur nature.

• On nomme :– fonction appelante celle qui appel– fonction appelée celle qui est appelée

Page 104: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

104

Mécanismes d’appel d’une fonction

• Pour chaque appel de fonction :– Un ensemble d’information sur l’état courant du

programme, nommé enregistrement d’activation, est mis sur la pile. On y retrouve principalement :

• L’adresse de retour de la fonction appelante• Le résultat de la fonction appelée• Tous les paramètres de la fonction appelée• Toutes les variables locales de la fonction appelée• L’état courant des registres de la fonction appelante qui sont

utilisés par la fonction appelée – Trois registres sont systématiquement utilisés :

• ESP – stack pointer• EBP – Base pointer• EIP – Instruction Pointer

Page 105: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

105

Mécanismes d’appel d’une fonction

• Les étapes du mécanisme d’appel d’une fonction sont :

• Que manque-t-il?

Empile et met à jour le registre EIP(l’adresse de retour de la fonction appelante est empilée et l’adresse de la fonction appelée par le registre EIP est ajustée )

Empile et met à jour le registre EBP(l’adresse de référence -BP- de la fonction appelante est empilé et celui de la fonction appelée par le registre EBP est ajusté)

EIP

EBP

77

88

99

1010

1111

1212

11

22

33

44

55

66

Exécute la fonction appelée

XYZ Empile l’état des registres de la fonction appelante

(seulement ceux qui sont utilisés par la fonction appelée)

Alloue les variables locales de la fonction appelée à même la pile(il suffit d’incrémenter ESP de la taille nécessaire aux variables)

Empile tous les paramètres de la fonction appelée(de droite à gauche)

EIP Dépile et met à jour l’adresse de retour dans le registre

EIP

Dépile tous les paramètres de la fonction appelée

Exécute la suite de la fonction appelanteXYZ

EBP

Dépile et met à jour l’état des registres de la fonction appelante

Relâche la mémoire réservée pour les variables locales(il suffit de décrémenter ESP de la taille prise par les variables)

Dépile et met à jour le registre EBP

Page 106: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

106

Mécanismes d’appel d’une fonction

• La valeur de retour est passée à titre de premier paramètre de la fonction. c’est-à-dire, comme dernier élément empilé sur la pile

• Par convention, ce paramètre possède toujours 4 octets (32 bits). Qu’arrive-t-il si la valeur de retour spécifiée ne correspond pas aux 4 octets utilisés?– Si la valeur de retour est plus petite (comme un char), on

utilise tout de même les 4 octets.– Si la valeur de retour est plus grande (comme un double),

on porte en mémoire haute la valeur de la variable et on utilise les 4 octets réservés comme pointeurs pour indiquer cette position.

Page 107: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

107

Le passage des paramètres à une fonction

• Il existe trois méthodes de passage de paramètres à une fonction :– Passage par valeur (« call by value »)

• les valeurs des paramètres d'appel sont recopiés dans la fonction appelée

• ainsi la fonction appelée travaille avec une copie des paramètres

• en fait, c'est le seul mode de passage de paramètres réellement existant en C

Page 108: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

108

Le passage des paramètres à une fonction

• … trois méthodes de passage de paramètres (suite):– Passage par référence ou par adresse (« call by reference »)

• dans ce mode de passage de paramètres, la fonction appelée travail avec les références des paramètres d'appel

• il existe deux avantages importants de ce mode de transmission

– il évite des copies coûteuses des paramètres de moyennes et grandes tailles

– il permet la modification de variables externes à la fonction• fondamentalement, ce type de passage est inexistant en C

(contrairement au C++ avec ses références)• c’est l’utilisation des pointeurs qui permet, indirectement,

d’obtenir un comportement qui s’approche du passage par référence

Page 109: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

109

Le passage des paramètres à une fonction

• … trois méthodes de passage de paramètres (suite):– Passage par nom (« call by name »)

• c'est le mode de transmission utilisé par le préprocesseur avec les arguments des macros

• dans ce mode, les paramètres de l'appel seront textuellement substitués aux diverses occurrences des paramètres formels (sans validation aucune – ni même la vérification de compatibilité des types)

Page 110: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

110

Le passage des paramètres à une fonction

#include <stdio.h>

void IncrementAndShow(int V1, int V2){

V1++; V2++;printf("Valeur des variables dans IncAndShow : \t%d\t%d\n", V1, V2);

}void Swap(int *V1, int *V2){

int VTemp = *V2;*V2 = *V1;*V1 = VTemp;

}#define Show(V1, V2)

printf("Valeur des variables dans Show : \t%d\t%d\t(%d)\n", V1, V2, V1*V2)

void main(void){

int V1 = 5, V2 = 10;

printf("Valeur des variables dans main (1) : \t%d\t%d\n", V1, V2);IncrementAndShow(V1, V2);printf("Valeur des variables dans main (2) : \t%d\t%d\n", V1, V2);Swap(&V1, &V2);printf("Valeur des variables dans main (3) : \t%d\t%d\n", V1, V2);Show(--V1, V2++);printf("Valeur des variables dans main (4) : \t%d\t%d\n", V1, V2);

}

Valeur des variables dans main (1) : 5 10Valeur des variables dans IncAndShow : 6 11Valeur des variables dans main (2) : 5 10Valeur des variables dans main (3) : 10 5Valeur des variables dans Show : 8 5 (45)Valeur des variables dans main (4) : 8 7

Valeur des variables dans main (1) : 5 10Valeur des variables dans IncAndShow : 6 11Valeur des variables dans main (2) : 5 10Valeur des variables dans main (3) : 10 5Valeur des variables dans Show : 8 5 (45)Valeur des variables dans main (4) : 8 7

- aucune entrée -- aucune entrée -Entrée

Sortie

Page 111: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

111

Fonctions récursives

• Il existe deux types de solution pour résoudre des problèmes nécessitant plusieurs calculs similaires et répétitifs : les solutions itératives et récursives.

• Dans les deux cas, un mécanisme différent est mis en place afin d’exécuter plusieurs fois la même séquence d’instruction. Ces mécanismes se traduisent par :– des boucles de contrôle pour les solutions itératives

implique des solutions linéaires (des solutions non linéaires sont possibles avec des artifices)

– des fonctions qui s’appellent elles même implique des solutions linéaires et non linéaires

Page 112: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

112

Fonctions récursives

• D’un point de vue théorique, lorsqu’une solution récursive est bien structurée, elle est un moyen puissant et unique de résoudre des problèmes.

• Par définition, la récursivité est une technique de traitement d’une tâche T par le traitement d’une tâche T’– semblable à l’approche descendante– la différence réside dans le fait que la tâche T’ est de même

nature que la tâche T

• D’un point de vue applicatif, il est important de se rappeler que : T’ T mais que T’ < T

• Est-ce qu’une fonction récursive est meilleur qu’une solution itérative ?

Page 113: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

113

Fonctions récursives

• La question importante : Comment arrêter une fonction récursive?

• Les cas limites sont des éléments essentiels de toutes fonctions récursives :– ce sont les conditions qui cessent les appels récursifs et

permettent de terminer la fonction– ce sont des tests d’arrêt qui sont liés aux parties non

récursives de la fonction

• Il existe deux types de récursivité :– la récursivité directe correspond au cas où la fonction F

appel directement la fonction F– la récursivité indirecte correspond au cas où une fonction F

appel F1, qui appel F2, qui appel F3, ..., qui appel Fn, qui enfin appel la fonction F

Page 114: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

114

Fonctions récursives

• Un premier exemple : La recherche d’un mot dans le dictionnaire– la solution itérative, simple mais peu efficace, correspond à

parcourir dans l’ordre, du premier vers le dernier, tous les éléments du dictionnaire jusqu’à ce que le mot recherché soit identifié

– une solution plus efficace et plus élégante consiste à faire ce que nous faisons intuitivement : une recherche binaire (« binary search »)

Comment procède-t-on pour résoudre ce problème?

Page 115: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

115

Fonctions récursives

• Pseudo code d’un algorithme de recherche binaire :Fonction-Recherche-binaire (Dictionnaire, Mot)

SI Dictionnaire est réduit à une seule pageALORS parcourir la page pour localiser Mot

SINONTrouver la partie du Dictionnaire séparé par le milieu où se trouve MotSI Mot se trouve dans la première partie du Dictionnaire

Fonction-Recherche-Binaire( première partie de Dictionnaire, Mot)Sinon

Fonction-Recherche-Binaire( deuxième partie de Dictionnaire, Mot)

Page 116: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

116

Fonctions récursives

• Comment trouver une solution récursive?• Réponses clés à trouver pour construire une

solution récursive :– Est-ce que le problème peut être définie en terme

de sous problème de même nature?– Est-ce que chaque appel récursif diminue la taille

du problème?– Quel est le cas limite du problème?– Puisque la taille du problème diminue, est on

assuré d’atteindre le cas limite?

Page 117: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

117

Fonctions récursives

• Aussi, plusieurs algorithmes itératifs peuvent facilement être modifier en algorithmes récursifs

• Un exemple simple de transformation algorithmique : le parcours d’une bouclevoid AfficheTousLesNombres2Chiffres_Iteratif(int NombreDe){

for (int i = NombreDe; i < 100; i++) {printf("%d\n", i);

}}

void AfficheTousLesNombres2Chiffres_Recursif(int NombreDe){

if (NomreDe < 100) {printf("%d\n", NombreDe);AfficheTousLesNombres_Recursif(NombreDe + 1);

}}

Page 118: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

118

Fonctions récursives

• Un exemple un peu plus étayé de transformation algorithmique : le parcours d’une double bouclevoid InitDynamicArrayByCascade_Iterative(int **Array, int SizeX, int SizeY, int Value){

for (int iY = 0; iY < SizeY; iY++) {for (int iX = 0; iX < SizeX; iX++) {

Array[iX][iY] = Value;}

}}

void InitDynamicArrayByCascade_Recursive(int **Array, int SizeX, int SizeY, int Value){

if (SizeY > 0) {if (SizeX > 0) {

Array[SizeY - 1][SizeX - 1] = Value;InitDynamicArrayByCascade_Recursive(Array, SizeX - 1, SizeY, Value);

}InitDynamicArrayByCascade_Recursive(Array, SizeX, SizeY – 1, Value);

}}

Page 119: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

119

Fonctions récursives

• La méthode de représentation suivante permet de décrire simplement un problème récursif par l’identification systématique de toutes les tâches possibles pour chaque « itération » :– l’idée consiste à décrire tous les cas possibles du problème – il est important d’exprimer les tâches à faire et la nature

récursive des cas concernés– il est intéressant de voir que les cas limites apparaissent

clairement avec cette méthode

nn cas âcherésultat t

......

2 cas)F(x'résultat

1 cas1 âcherésultat t

F(x)

Page 120: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

120

Fonctions récursives

• Un autre exemple : le calcul de la factorielle.– La définition mathématique de la factorielle est connue et

simple :

0)1(...321

01

0indéfiniest

!

1

´´´´´

nnni

n

n

nn

i

´

0)1(Fact

01

0

)Fact(

nnn

n

nerreur

n

Page 121: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

121

Fonctions récursives

• Suite de l’exemple : le calcul de la factorielle

´

0)1(Fact

01

0

)Fact(

nnn

n

nerreur

n

Fonction-Factoriel (Nombre)SI Nombre < 0

retourne erreurSi Nombre = 0

retourne 1SINON

retourne Nombre * Fonction-Factoriel(Nombre – 1)

int Factoriel(int N){

if (N < 0) { /* Parametre d’entree invalide */

return -1; /* -1 represente erreur */} else if (N == 0) {

return 1; /* Cas limite */} else {

return N * Factoriel(N – 1); /* Appel recursif */}

}

Page 122: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

122

Fonctions récursives

• Puisque chaque appel de fonction possède son propre espace de variable, chaque appel récursif possède le sien.

• Ceci implique un parcours descendant jusqu’au dernier appel récursif pour ensuite revenir au premier appel.

• La technique de représentation par boîtes est très efficace pour illustrer le comportement d’un programme récursif. Elle aide à :– déverminer les programmes récursifs (parfois

difficiles à suivre)– illustrer le comportement d’un algorithme

Page 123: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

123

Fonctions récursives

• Les étapes à suivre pour réaliser la technique de représentation par boîtes :– pour chaque appel récursif (parcours descendant), on crée

une boîte qui contient• l’appel de fonction incluant les valeurs de chaque paramètre• l’environnement local du sous programme associé• les instructions faites avant l’appel récursif• une flèche initiant le nouvel appel récursif

– pour chaque dernier appel récursif, on revient à l’appel de fonction appelante en créant une boîte contenant :

• l’environnement local du sous programme associé• les instructions faites après l’appel récursif• un flèche indiquant le retour de fonction avec la valeur

retournée s’il y a lieu

Page 124: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

124

Factoriel(3)

N = 2return N * Factoriel(N-1)

Factoriel(2)

N = 1return 1

Factoriel(1)

N = 3return N * Factoriel(N-1)

N = 2return 2 * 1 1

N = 3return 3 * 2 2

6

Factoriel(3)

N = 2return N * Factoriel(N-1)

Factoriel(2)

N = 1return 1

Factoriel(1)

N = 3return N * Factoriel(N-1)

N = 2return 2 * 1 1

N = 3return 3 * 2 2

Factoriel(3)

N = 2return N * Factoriel(N-1)

Factoriel(2)

N = 1return 1

Factoriel(1)

N = 3return N * Factoriel(N-1)

N = 2return 2 * 1 1

Fonctions récursives

• Exemple de représentation par boîte :int main(void){

printf("%d! = %d\n", 3, Factoriel(3));}

Factoriel(3)

N = 2return N * Factoriel(N-1)

Factoriel(2)

N = 1return 1

Factoriel(1)

N = 3return N * Factoriel(N-1)

Factoriel(3)

N = 2return N * Factoriel(N-1)

Factoriel(2)N = 3return N * Factoriel(N-1)

Factoriel(3)

N = 3return N * Factoriel(N-1)

3! = 63! = 6

- aucune entrée -- aucune entrée -Entrée

Sortie

Page 125: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

125

Fonctions récursives

• Un exemple : écrire une chaîne de caractères à l’envers (1ier)void Writebackward1(char *String, int Length){

if (Length > 0) {printf("%c", String[Length - 1]);Writebackward1(String, Length – 1);

}}

Writebackward1("allo", 4);WB1(allo, 4)

String = alloLength = 4printf String[3]WB1(allo, Length-1)

WB1(allo, 3)

String = alloLength = 3printf String[2]WB1(allo, Length-1)

WB1(allo, 2)

String = alloLength = 2printf String[1]WB1(allo, Length-1)

WB1(allo, 1)

String = alloLength = 1printf String[0]WB1(allo, Length-1)

WB1(allo, 0)

String = alloLength = 0

String = alloLength = 1

String = alloLength = 2

String = alloLength = 3

String = alloLength = 4

ollaolla

- aucune entrée -- aucune entrée -Entrée

Sortie

Page 126: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

126

Fonctions récursives

• Un exemple : écrire une chaîne de caractères à l’envers (2ième)void Writebackward2(char *String){

if (String[0] != '\0') {Writebackward2(String + 1); /* équivalent à WB2(&String[0] */printf("%c", String[0]);

}}

Writebackward2("allo", 4);

ollaolla

- aucune entrée -- aucune entrée -Entrée

Sortie

WB2(allo)

String = alloWB2(llo)

string = oprintf String[0]

WB2(llo)

String = lloWB2(lo)

WB2(lo)

String = loWB2(o)

WB2(o)

String = oWB2(“”)

WB2(“”)

String = “”

string = loprintf String[0]

string = lloprintf String[0]

string = alloprintf String[0]

Page 127: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

127

Fonctions récursives

• Un exemple : impression selon un ordre particuliervoid ImpressionEtrange(int *Data, int N){

if (N > 0) {ImpressionEtrange(Data + 1, N – 1);printf("%d \n", *Data);ImpressionEtrange(Data + 1, N – 1);

)}

int Data[3] = { 1, 2, 3 };ImpressionEtrange(Data, 3);

3231323

3231323

- aucune entrée -- aucune entrée -Entrée

Sortie

Page 128: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

128

Fonctions récursives

Data = { 2 3 } - N = 2printf 2ImpBiz(Data*, 1)

ImpBiz(Data, 3)

Data = { 1 2 3 } - N = 3ImpBiz(Data*, 2)

ImpBiz(Data, 2)

Data = { 2 3 } - N = 2ImpBiz(Data*, 1)

ImpBiz(Data, 1)

Data = { 3 } - N = 1ImpBiz(Data*, 0)

ImpBiz(Data, 0)

Data = { - } - N = 0

Data = { 3 } - N = 1printf 3ImpBiz(Data*, 0)

ImpBiz(Data, 0)

Data = { - } - N = 0

Data = { 3 } - N = 1

Data = { 3 } - N = 1ImpBiz(Data*, 0)

ImpBiz(Data, 0)

Data = { - } - N = 0

Data = { 3 } - N = 1printf 3ImpBiz(Data*, 0)

ImpBiz(Data, 0)

Data = { - } - N = 0

Data = { 3 } - N = 1

ImpBiz(Data, 1)

Data = { 2 3 } - N = 2

Data = { 1 2 3 } - N = 3printf 1ImpBiz(Data*, 2) ...

Page 129: 1 Convention sur les acétates Concernant la présentation des acétates : –malgré le fait quelles soient relativement bien remplies, les acétates tentent.

129

Fonctions récursives

...

Data = { 2 3 } - N = 2printf 2ImpBiz(Data*, 1)

ImpBiz(Data, 2)

Data = { 2 3 } - N = 2ImpBiz(Data*, 1)

ImpBiz(Data, 1)

Data = { 3 } - N = 1ImpBiz(Data*, 0)

ImpBiz(Data, 0)

Data = { - } - N = 0

Data = { 3 } - N = 1printf 3ImpBiz(Data*, 0)

ImpBiz(Data, 0)

Data = { - } - N = 0

Data = { 3 } - N = 1

Data = { 3 } - N = 1ImpBiz(Data*, 0)

ImpBiz(Data, 0)

Data = { - } - N = 0

Data = { 3 } - N = 1printf 3ImpBiz(Data*, 0)

ImpBiz(Data, 0)

Data = { - } - N = 0

Data = { 3 } - N = 1

ImpBiz(Data, 1)

Data = { 2 3 } - N = 2

Data = { 1 2 3 } - N = 3