Vous êtes sur la page 1sur 34

17/10/2021

Université Ibn Zohr Agadir Année universitaire: 2021-2022


Ecole Nationale des Sciences Appliqué Section: ENSA -3
Département: Génie Informatique Module: Programmation C++
Responsable: Prof. A. Elyousfi

Abderrahmane ELYOUSFI Département


elyousfiabdo@yahoo.fr Génie Informatique

Fonctions

Abderrahmane ELYOUSFI
2 2

1
17/10/2021

Introduction
 Comme dans la plupart des langages, on peut en C++ découper
un programme en plusieurs fonctions.

 Une seule de ces fonctions existe obligatoirement ; c'est la


fonction principale appelée main.

 Cette fonction principale peut, éventuellement, appeler une


ou plusieurs fonctions secondaires.

 De même, chaque fonction secondaire peut appeler d'autres


fonctions secondaires ou s'appeler elle-même  fonction
récursive.

Abderrahmane ELYOUSFI 3

Exemple d’une fonction


 Exemple

Abderrahmane ELYOUSFI 4

2
17/10/2021

fonction
Une fonction possède trois aspects :

 le prototype : c’est la déclaration nécessaire avant tout;

 l’appel : c’est l’utilisation d’une fonction à


l’intérieur d’une autre fonction (par exemple le programme
principal);

 la définition : c’est l’écriture proprement dite de la


fonction, en-tête et corps.

Abderrahmane ELYOUSFI 5

Prototype
 prototype de la fonction indique uniquement le type
des données transmises et reçues par la fonction.

type nom-fonction(type-1,...,type-n);

Abderrahmane ELYOUSFI 6

3
17/10/2021

Définition d'une fonction


 La définition d'une fonction est la donnée du texte de son
algorithme, qu'on appelle corps de la fonction.
 Elle est de la forme :

type nom-fonction (type-1 arg-1,...,type-n


arg-n)
{
[déclarations de variables locales ]
liste d'instructions
}
 La première ligne de cette définition est l' en-tête de la
fonction. 7

Abderrahmane ELYOUSFI 7

Renvoyer un résultat
 Par définition, toutes les fonctions fournissent un
résultat d'un type que nous devons déclarer.

 Son type doit être le même que celui qui a été spécifié
dans l'en-tête de la fonction.

 Plusieurs instructions return peuvent apparaître dans une


fonction.

 Le retour au programme appelant sera alors provoqué par


le premier return rencontré lors de l'exécution.

 Si la fonction ne retourne pas de valeur, la fonction est


de type void;
8

Abderrahmane ELYOUSFI 8

4
17/10/2021

Renvoyer un résultat
 L’instruction return

return <expression>;

 évaluation de l'<expression>
 conversion du résultat de l'expression dans le type
de la fonction
 terminaison de la fonction

Abderrahmane ELYOUSFI 9

Renvoyer un résultat
 L’instruction return
int max(int x, int y)
{
if(x>y)
return x;
else
return y;
printf("fin du prog "); //!!!!!!!!!!!!
}

Abderrahmane ELYOUSFI 10

5
17/10/2021

Renvoyer un résultat
 Le type void:

void max(int x, int y)


{
if(x>y)
printf(" le max de x et y:%d",x) ;
else
printf(" le max de x et y:%d",y) ;
}

Abderrahmane ELYOUSFI 11

Appel d'une fonction


 L'appel d'une fonction se fait par l'expression

nom-fonction(para-1,para-2,...,para-n)

 Les paramètres sont séparés par la virgule.

12

Abderrahmane ELYOUSFI 12

6
17/10/2021

Appel d'une fonction


#include <stdio.h>
main()
{
void affiche_puissance (int, int) ; // prototype
int X = 5, N = 10 ;
affiche_puissance (X, N) ; //* Appel
return 0;
}
void affiche_puissance (int d, int f)
{
int i, p=1 ;
for (i=1 ; i<=f ; i++)
p*=d;
printf ("%d a la puissance de %d est %d:\n", d, f, p) ;
}
13

Abderrahmane ELYOUSFI 13

Déclaration

7
17/10/2021

Déclaration d'une fonction

 Le C++ n'autorise pas les fonctions imbriquées.

 La définition d'une fonction secondaire doit donc être


placée soit avant, soit après la fonction principale
main.

 Toutefois, il est indispensable que le compilateur


"connaisse" la fonction au moment où celle-ci est
appelée.

15

Abderrahmane ELYOUSFI 15

Définition des fonction en ‘top-down’


// Définition de main
main()
{
int FA (int, int); // Déclaration locale de FA
...
I = FA(2, 3); // Appel de FA */
...
}
// Définition de FA
int FA(int X, int Y)
{
int FB (int, int); // Déclaration locale de FB
...
J = FB(20, 30); // Appel de FB
...
}

// Définition de FB
int FB(int N, int M)
{
...
} Abderrahmane ELYOUSFI 16

8
17/10/2021

Définition 'bottom-up' sans déclarations :


/* Définition de FA */
int FA(int X, int Y)
{
...
J = FB(20, 30); /* Appel de FB */
...
}
/* Définition de FB */
int FB(int N, int M)
{
...
}

/* Définition de main */
main()
{
...
I = FA(2, 3); /* Appel de FA */
...
}
Abderrahmane ELYOUSFI 17

Déclaration globale et définition 'top-down'


// Déclaration globale de FA et FB
int FA (int X, int Y);
int FB (int N, int M);

// Définition de main
main()
{
...
I = FA(2, 3); // Appel de FA
...
}

// Définition de FA
int FA(int X, int Y)
{
...
J = FB(20, 30); // Appel de FB
...
}
// Définition de FB
int FB(int N, int M)
{
...
}
Abderrahmane ELYOUSFI 18

9
17/10/2021

La fonction inline

La fonction inline

le code exécutable correspondant à une fonction est généré une


seule fois par le compilateur.

pour chaque appel de cette fonction, le compilateur doit prévoir,


non seulement le branchement au code exécutable correspondant,

mais également des instructions utiles pour établir la


communication entre le programme appelant et la fonction.

Dans le cas de « petites fonctions », ces différentes instructions


de « service » peuvent représenter un pourcentage important du
temps d’exécution de la fonction.

10
17/10/2021

La fonction inline

À chaque appel de la fonction précédée par inline, le compilateur


devra incorporer au sein du programme les instructions
correspondantes.

Le mécanisme habituel de gestion de l’appel et du retour


n’existera plus (il n’y a plus besoin de sauvegardes,
recopies...), ce qui permet une économie de temps.

En revanche, les instructions correspondantes seront générées à


chaque appel, ce qui consommera une quantité de mémoire croissant
avec le nombre d’appels.

La fonction inline

11
17/10/2021

Les noms de fonction surchargés

Les noms de fonction surchargés


Il est conseillé d’utiliser des noms distincts à des fonctions
différents .

Lorsque les fonctions effectuent la même tache sur des objets de


type différent, il est pratique de leur attribuer un nom identique.

L’utilisation d’un même nom pour des opérations sur des types
différents est nommée surcharge.

12
17/10/2021

Les noms de fonction surchargés


Il est conseillé d’utiliser des noms distincts à des fonctions
différents .

Lorsque les fonctions effectuent la même tache sur des objets de


type différent, il est pratique de leur attribuer un nom identique.

L’utilisation d’un même nom pour des opérations sur des types
différents est nommée surcharge.

Les noms de fonction surchargés

13
17/10/2021

Les noms de fonction surchargés

Les noms de fonction surchargés

Compte tenu de son ambiguïté, le dernier appel conduit à une erreur de


compilation. En effet, deux possibilités existent ici :
convertir p en double sans modifier n et appeler essai I ou,
convertir n en double sans modifier p et appeler essai II.

14
17/10/2021

Les noms de fonction surchargés

Les noms de fonction surchargés

 Vous obtiendrez une erreur de compilation.


 En effet, C++ n’a pas prévu de distinguer int de const
int.
 Cela se justifie par le fait que, les deux fonctions
recevant une copie de l’information à traiter, il n’y a
aucun risque de modifier la valeur originale.

15
17/10/2021

Les noms de fonction surchargés

Cette fois, la distinction entre int & et const int & est
justifiée.
En effet, on peut très bien imaginer que chose I modifie la
valeur de la variable dont elle reçoit la référence, tandis
que chose II n’en fait rien.

Règles de recherche d’une fonction surdéfinie


Cas des fonctions à un argument

Correspondance exacte :
 Les différents types de base,
 L’attribut de signe(en C++, char est différent de signed char et de unsigned
char);
 L’attribut const peut intervenir dans le cas de références (il en
ira de même pour les pointeurs).

Correspondance avec promotions numériques:

16
17/10/2021

Transmission d’arguments

Transmission par valeurs

La transmission par valeurs, ne permet pas à une fonction de modifier la


valeur d’un argument.

17
17/10/2021

Transmission par référence

C++ dispose de la notion de référence,


laquelle correspond à celle d’adresse :
 considérer la référence d’une variable revient à
considérer son adresse, et non plus sa valeur.

Transmission par référence

18
17/10/2021

Transmission par adresse avec un pointeur

Transmission par adresse avec un pointeur


Dans la transmission par référence, le type de l’argument effectif
doit être le même que celui de l’argument muet.

Cas d’un argument effectif constant

void fct (int &) ;


fct (3) ; // incorrect : f ne peut pas modifier une constante
const int c = 15 ;
.....
fct (c) ; // incorrect : f ne peut pas modifier une constante

19
17/10/2021

Transmission par adresse avec un pointeur


Cas d’un argument muet constant
void fct1 (const int &) ;
const int c = 15 ;
.....
fct1 (3) ; // correct ici
fct1 (c) ; // correct ici

Un appel tel fct1 (exp) sera accepté quel que soit le type de exp. En
effet, dans ce cas, il y a création d’une variable temporaire (de
type int) qui recevra le résultat de la conversion de exp en int.

void fct1 (const int &) ;


float x ;
.....
fct1 (x) ; // correct : f reçoit la référence à une variable temporaire
// contenant le résultat de la conversion de x en int

Pointeur de fonction

20
17/10/2021

Pointeur de fonction

 Un pointeur de fonction contient l’adresse du début


du programme constituant la fonction.

 Il est possible d’appeler une fonction dont


l’adresse est contenue dans un pointeur de fonction.

Pointeur de fonction

Syntaxe de la déclaration

type (*identificateur)(paramètres) ;

 type est le type de la valeur renvoyée par la fonction,

 identificateur est le nom du pointeur de la fonction

 paramètres est la liste des types des variables que la


fonction attend comme paramètres, séparés par des virgules

21
17/10/2021

Pointeur de fonction

int (*pf)(int, int); /* Déclare un pointeur de fonction. */

pf est un pointeur de fonction attendant comme paramètres


deux entiers et renvoyant un entier.

Il est possible d’utiliser typedef pour créer un alias du


type pointeur de fonction :

typedef int (*PtrFonct)(int, int) ;


PtrFonct pf ;

PtrFonct est le type des pointeurs de fonctions.

Pointeur de fonction
#include <iostream>
using namespace std;
int f(int i, int j) /* Définit une fonction. */
{
return i+j;
}
int (*pf)(int, int); /* Déclare un pointeur de fonction. */
int main()
{
int l=1, m=5; /* Déclare deux entiers. */
pf = &f; /* Initialise pf avec l’adresse de la fonction */
/* Utilise le pointeur pf pour appeler la fonction f et affiche le résultat : */
cout << (*pf)(l,m)<<endl;
return 0;
}

22
17/10/2021

Pointeur de fonction
#include <iostream>
using namespace std;
int somme(int i, int j){ return i+j;}
int multiplication(int i, int j){return i*j;}
int quotient(int i, int j){return i/j;}
typedef int (*fptr)(int, int);
int main(void)
{
int i=3,j=9;

fptr ftab[]={&somme, &multiplication, &quotient};

cout << "s="<<(*(ftab[0]))(i,j) )<<"Mult="<<(*(ftab[1]))(i,j) )<<endl;


return 0;
}

Les variables

23
17/10/2021

Les variables globales


En C++, plusieurs fonctions (dont, bien entendu le programme
principal main) peuvent partager des variables communes qu’on
qualifie alors de globales.

La portée des variables globales


Les variables globales ne sont connues que par la partie du
programme source qui suit leur déclaration

Les variables n et x sont accessibles aux fonctions fct1 et fct2,


mais pas au programme principal.

24
17/10/2021

La classe d’allocation des variables globales

 Les variables globales existent pendant toute l’exécution du


programme dans lequel elles apparaissent.

 Les variables globales font partie de la classe d’allocation


statique.

 Les variables globales sont initialisées par zéro.(sauf, bien


sûr, si vous leur attribuez explicitement une valeur initiale au
moment de leur déclaration).

Les variables locales

 Les variables locales ne sont connues du compilateur qu’à


l’intérieur de la fonction où elles sont déclarées.

 Leur portée est donc limitée à cette fonction.

25
17/10/2021

Les variables locales


 Les variables locales n’ont aucun lien avec des variables
globales de même nom ou avec d’autres variables locales à
d’autres fonctions.

si l’on souhaite utiliser dans fct1 la variable globale n, on


utilise l’opérateur dit « de résolution de portée » (::) en la
nommant ::n.

Les variables locales

 Les variables locales ont une durée de vie limitée à celle d’une
exécution de la fonction dans laquelle elles figurent.

 Un nouvel espace mémoire est alloué à chaque entrée dans la


fonction et libéré à chaque sortie.

 la classe d’allocation de ces variables est automatique.

26
17/10/2021

Les variables locales statiques

 Il est possible de demander d’attribuer un emplacement permanent


à une variable locale et de conserver ainsi sa valeur d’un appel
au suivant.

 Il suffit pour cela de la déclarer à l’aide du mot-clé static.

 Les variables locales de classe statique sont, par défaut,


initialisées à zéro.

Les variables locales statiques

27
17/10/2021

Variables locales à un bloc


 C++ vous permet de déclarer des variables locales à un bloc.
 Leur portée est limitée à ce bloc ; leur emplacement est alloué à
l’entrée dans le bloc et il disparaît à la sortie.

Initialisation des variables


En c++, il est possible d’initialiser explicitement une variable
lors de sa déclaration.

Les variables de classe statique


 Il s’agit des variables globales, ainsi que des variables
locales déclarées avec l’attribut static.
 Ces variables sont permanentes.
 Elles sont initialisées une seule fois avant le début de
l’exécution du programme.
 En l’absence d’initialisation explicite, ces variables
seront initialisées à zéro.

28
17/10/2021

Initialisation des variables


En c++, il est possible d’initialiser explicitement une variable
lors de sa déclaration.

Les variables de classe automatique

 Il s’agit des variables locales à une fonction ou à un bloc.

 Ces variables ne sont pas initialisées par défaut.

 Ces variables automatiques sont initialisées à chaque appel


de la fonction dans laquelle elles sont définies.

Les arguments par défaut

29
17/10/2021

Les arguments par défaut

C++ permet d’attribution de valeurs par défaut à des arguments non


fournis lors de l’appel.

Lorsqu’une déclaration prévoit des valeurs par défaut, les arguments


concernés doivent obligatoirement être les derniers de la liste.

float fexple (int = 5, long, int = 3) ; //cette déclaration est interdite

Le mécanisme proposé par C++ revient à fixer les valeurs par défaut
dans la déclaration de la fonction et non dans sa définition.

Les arguments par défaut


En c++, il est possible d’initialiser explicitement une variable
lors de sa déclaration.

30
17/10/2021

Les arguments par défaut


En c++, il est possible d’initialiser explicitement une variable
lors de sa déclaration.

La fonction main

31
17/10/2021

LA FONCTION MAIN

 La fonction principale main est une fonction


comme les autres.

 En fait la fonction main est de type int dont la


valeur est 0 si l'exécution se passe bien différente
de 0 sinon

Abderrahmane ELYOUSFI 63

LA FONCTION MAIN
 La fonction main peut également posséder des
paramètres formels.

 En effet un programme C++ peut recevoir une liste


d'arguments au lancement de son exécution.

 La ligne de commande est dans ce cas là est


composée du nom du fichier exécutable suivi par
des paramètres.

 main possède 2 paramètres formels appelés par


convention :

Abderrahmane ELYOUSFI 64

32
17/10/2021

La fonction main
 int main(int argc, char* argv[])
 argc
 variable fourni le nombre de mots composant la ligne de
commande y compris l'exécutable.
 argv
 tableau de chaînes de caractères correspondant chacune
à un mot de la ligne de commande.
 argv[0]: = program name
 argv[1]: = first argument
 …
 argv[argc-1]: last argument
Abderrahmane ELYOUSFI 65

La fonction main
#include <iostream>
Using namespace std;
int main(int argc, char *argv[])
{
int idx;
cout<< "le nombre d’arguments est:"<< argc;
for (idx = 0; idx < argc; idx++)
{
cout<<“argv[”<<idx<<“]=“<< argv[idx]<<endl;
}
return 0;
}

Si j'execute MyProg de la facon suivante :

MyProg param1 param2 param3


 Argv[0]= MyProg
 Argv[1]= param1
 Argv[2]= param2
 Argv[3]= param3
Abderrahmane ELYOUSFI 66

33
17/10/2021

Fin

34

Vous aimerez peut-être aussi