---
jupytext:
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
kernelspec:
  display_name: C++17
  language: C++17
  name: xcpp17
rise:
  auto_select: first
  autolaunch: false
  centered: false
  controls: false
  enable_chalkboard: true
  height: 100%
  margin: 0
  maxScale: 1
  minScale: 1
  scroll: true
  slideNumber: true
  start_slideshow_at: selected
  transition: none
  width: 90%
---

# Cycle de vie d'un programme

## Revenons à la recette de la mousse au chocolat

**Ingrédients :**

250 g de chocolat, 125 g de beurre, 6 œufs, 50 g de sucre, café

**Étapes :**

-   Faire fondre le chocolat avec deux cuillères d'eau

-   Ajouter le beurre, laisser refroidir puis ajouter les jaunes

-   Ajouter le sucre et comme parfum un peu de café

-   Battre les blancs jusqu'à former une neige uniforme

-   Ajouter au mélange

+++ {"slideshow": {"slide_type": "fragment"}}

**Est-ce bien un programme ?**

+++ {"slideshow": {"slide_type": "fragment"}}

Pour répondre à cette question, revenons à la définition :

**Programme** (rappel) : séquence d'**instructions** qui spécifie,
étape par étape, les opérations à effectuer pour obtenir, à partir des
**entrées**, un résultat, la **sortie**.

+++ {"slideshow": {"slide_type": "slide"}}

### Oui, mais c'est quoi une instruction ?

Prenons quelques candidats :

-   « Lever le bras de 10 cm, tendre la main vers la gauche,
    prendre la casserole rouge, ... »  
    Trop détaillé, illisible, non portable

+++ {"slideshow": {"slide_type": "fragment"}}

-   « Préparer une mousse au chocolat »  
    Trop abstrait et non informatif

+++ {"slideshow": {"slide_type": "fragment"}}

-   « avec deux cuillères d'eau »  
    Ambigu : c'est combien une cuillère ?

+++ {"slideshow": {"slide_type": "fragment"}}

-   « Zwei Eiweiß in Eischnee schlagen »  
    Dans quelle langue ?

+++ {"slideshow": {"slide_type": "fragment"}}

Cela nous amène naturellement à la question suivante :

**Quelles sont les instructions compréhensibles par un ordinateur ?**

+++ {"slideshow": {"slide_type": "slide"}}

## Au commencement était l'« assembleur »

L'assembleur est le langage que comprend directement l'ordinateur.
Chaque instruction correspond à une opération élémentaire que peut
effectuer le processeur :

``` nasm
  mov    -0x1c(%rbp), %edx
  mov    -0x1c(%rbp), %eax
  imul   %edx, %eax
  mov    %eax, -0x18(%rbp)
  mov    -0x18(%rbp), %eax
  imul   -0x18(%rbp), %eax
  mov    %eax, -0x14(%rbp)
```

Voyons cet exemple de plus près.

+++ {"slideshow": {"slide_type": "fragment"}}

**Exercice :**

Exécuter ce fragment d'*assembleur* en suivant les indications
suivantes :

-   `%eax, %edx` sont des registres (cases mémoire du processeur)  
    l'analogue des variables
-   `-0x14(%rbp), ..., -0x1c(%rbp)` : autres cases mémoire
-   `mov a, b` : copier le contenu de la case a dans la case b
-   `imul a, b` : multiplier le contenu de a par celui de b et mettre le
    résultat dans b
-   Initialiser le contenu de la case `%-0x1c(%rbp)` à $3$

+++ {"slideshow": {"slide_type": "fragment"}}

Vous avez réussi ? Bravo, vous pourrez dire que vous avez fait de
l'assembleur ! Comme vous le constatez, rien de magique. Mais on est
bien content de ne pas avoir à programmer tout le temps en assembleur.

+++ {"slideshow": {"slide_type": "slide"}}

## Cycle de vie d'un programme

+++ {"slideshow": {"slide_type": "fragment"}}

### Motivation

**Ce que je veux :**

« Calculer la puissance 4 d'un nombre »

+++ {"slideshow": {"slide_type": "fragment"}}

**Ce que l'ordinateur sait faire :**

``` nasm
  ...
  mov    -0x1c(%rbp), %edx
  mov    -0x1c(%rbp), %eax
  imul   %edx, %eax
  mov    %eax, -0x18(%rbp)
  mov    -0x18(%rbp), %eax
  imul   -0x18(%rbp), %eax
  mov    %eax, -0x14(%rbp)
  ...
```

+++ {"slideshow": {"slide_type": "fragment"}}

**Passer de l'un à l'autre ne va pas se faire tout seul**. Il va
falloir un peu de méthode ; c'est le cycle de vie d'un programme.

+++ {"slideshow": {"slide_type": "slide"}}

### Cycle de vie d'un programme

Nous allons passer en revue les différentes étapes du cycle de vie
d'un programme, partant d'un problème à résoudre jusqu'à un programme
fonctionnel.

+++ {"slideshow": {"slide_type": "fragment"}}

#### Problème

« Calculer la puissance 4 d'un nombre »

+++ {"slideshow": {"slide_type": "fragment"}}

#### Formalisation

Spécification des **entrées** et des **sorties**

Scénario d'utilisation : « l'utilisateur rentre au clavier un nombre
entier $x$ ; l'ordinateur affiche en retour la valeur de $x^4$ à l'écran »

+++ {"slideshow": {"slide_type": "fragment"}}

#### Recherche d'un algorithme

- Comment on résout le problème ?
- Quel **traitement** appliquer à l'entrée pour obtenir la sortie
  désirée ?

+++ {"slideshow": {"slide_type": "fragment"}}

On note que $x^4=x * x * x * x = (x^2)^2$

Cela nous donne un **algorithme** :

-   calculer $x*x$
-   prendre le résultat et faire de même

+++ {"slideshow": {"slide_type": "slide"}}

#### Digression : La notion d'algorithme

**Définition : Algorithme**

-   Description formelle d'un procédé de traitement qui permet, à partir
    d'un ensemble d'informations initiales, d'obtenir des informations
    déduites

-   Succession finie et non ambiguë d'opérations clairement posées

+++ {"slideshow": {"slide_type": "fragment"}}

Quelle différence entre un **algorithme** et un **programme** ?

+++ {"slideshow": {"slide_type": "fragment"}}

Un algorithme
-   doit toujours se terminer !
-   est conçu pour communiquer entre humains
-   est un concept indépendant du langage dans lequel il est écrit

+++ {"slideshow": {"slide_type": "slide"}}

### Cycle de vie d'un programme : implantation

**Et maintenant ?**

L'algorithme s'adresse à un humain

On veut l'expliquer à un ordinateur ...

... qui est stupide ; et ne comprend pas le français !

+++ {"slideshow": {"slide_type": "fragment"}}

**Écriture d'un programme :**

En assembleur ???

-   Trop détaillé
-   Non portable
-   Illisible pour l'humain !

+++ {"slideshow": {"slide_type": "fragment"}}

En C++ :

Entrée :

```{code-cell}
    int x = 3;
```

Traitement :

```{code-cell}
    int xCarre = x * x;
    int xPuissanceQuatre = xCarre * xCarre;
```

Sortie :

```{code-cell}
    xPuissanceQuatre
```

+++ {"slideshow": {"slide_type": "slide"}}

#### Niveaux de langages de programmation

+++ {"slideshow": {"slide_type": "slide"}}

**Langage machine (binaire) :**

Un programme y est directement compréhensible par la machine

+++ {"slideshow": {"slide_type": "slide"}}

**Langage d'assemblage (ou assembleur) :**

Un programme y est traduisible mot-à-mot en langage machine

+++ {"slideshow": {"slide_type": "slide"}}

**Langage de programmation :**

En général, un programme doit être **transformé** pour être compris
par la machine

+++ {"slideshow": {"slide_type": "slide"}}

Comment faire cette transformation ? À la main ?

+++ {"slideshow": {"slide_type": "slide"}}

### Transformer en binaire

+++ {"slideshow": {"slide_type": "fragment"}}

#### Les interpréteurs

**Exemple : interpréteur C++ dans Jupyter (xeus-cling) :**

+++ {"slideshow": {"slide_type": "fragment"}}

**Chaîne de production :**

1. L'utilisateur saisit une **instruction source**
2. L'**interpréteur** la convertit en succession d'**instructions
   machine**
3. Le processeur exécute les instructions

+++ {"slideshow": {"slide_type": "fragment"}}

Exemples de langages de programmation avec un interpréteur :
Basic, Javascript, LISP, Perl, Python, C++, ...

+++ {"slideshow": {"slide_type": "slide"}}

#### Les compilateurs

**Exemple : compilation en C++ :**

-   Programme source : `puissance-quatre.cpp`
-   Compilation : `g++ puissance-quatre.cpp -o puissance-quatre`
-   Programme objet (ou binaire) : `puissance-quatre`
-   Exécution : `./puissance-quatre`
-   Fabrication de l'assembleur : `g++ -S puissance-quatre.cpp`
-   Programme en assembleur : `puissance-quatre.s`

+++ {"slideshow": {"slide_type": "fragment"}}

**Exemple :**

Observez le contenu de `puissance-quatre.s`, et retrouvez les
instructions assembleur étudiées plus haut.

+++ {"slideshow": {"slide_type": "fragment"}}

**Chaîne de production :**

1.  L'utilisateur saisit un **programme source**
2.  Le **compilateur** convertit tout le programme
    en un **programme objet** (écrit en binaire)
3.  L'utilisateur lance l'exécution du programme objet

Exemples de langages de programmation avec un compilateur :
ADA, C, C++, FORTRAN, Java, Pascal, ...

+++ {"slideshow": {"slide_type": "slide"}}

### Exécution et mise au point

**Exécuter le programme :**

-   Autant de fois que l'on veut !

+++ {"slideshow": {"slide_type": "fragment"}}

**Tester que le programme fonctionne :**

-   En n'oubliant pas les cas particuliers !!!

+++ {"slideshow": {"slide_type": "fragment"}}

**Mise au point :**

-   Correction d'erreurs
-   Optimisation du programme (consommation de ressources: temps, mémoire, énergie, ...)
-   Optimisation de l'algorithme
-   Amélioration du programme (lisibilité, généralisation)

+++ {"slideshow": {"slide_type": "fragment"}}

À chaque fois, on reboucle sur l'étape de compilation, voire de
conception, d'où le terme de cycle de vie.

+++ {"slideshow": {"slide_type": "slide"}}

## Cycle de vie d'un programme : résumé

Passer d'un **problème à résoudre** que l'on a en tête à un **programme
exécutable par l'ordinateur** est un grand saut. Heureusement, on peut
s'appuyer sur un peu de

+++ {"slideshow": {"slide_type": "fragment"}}

**Méthodologie :**

1.  Énoncé du problème
2.  Formalisation (quel est le problème précisément ?)
3.  Recherche d'un algorithme (comment résoudre le problème ?)
4.  Programmation (implantation)
5.  Interprétation / Compilation
6.  Exécution
7.  Mise au point (test, débogage, optimisation, diffusion)

+++ {"slideshow": {"slide_type": "skip"}}

## Suite

Maintenant que nous avons clarifié la notion de compilation, vous êtes
prêts pour la [compilation séparée](cours-modularite.md).