---
jupytext:
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
kernelspec:
  display_name: C++17
  language: C++17
  name: xcpp17
---

+++ {"tags": ["solution"]}

# Exercice : Structures et passage par référence

:::{todo} 2025-2026

Extraire le code dans un fichier pour le compiler.

:::

Considérons la définition ci-dessous du type structuré "Point", qui
utilise deux champs $x$ et $y$, qui sont les coordonnées d'un point
dans le plan.

``` cpp
struct Point {
    float x, y;
};
```

On va utiliser la procédure suivante qui permet de créer et de
transmettre en résultat une variable de type `Point`, à partir de ses
coordonnées lues auprès de l'utilisateur. Notez qu'au lieu de
transmettre des `float` ou des `int`, on transmet un `Point` !!.

``` cpp
void litPoint (Point &p) {
    cout << "abscisse ? "; cin >> p.x ;
    cout << "ordonnee ? "; cin >> p.y ;
}
```

La notation pointée permet d'écrire dans les champs d'une structure,
mais également d'accéder à ces champs, comme le montre la fonction
suivante :

``` cpp
float abscisse(Point p) {
    return p.x ;
}
```

1.  Mettez dans un nouveau fichier la définition du type `Point`, puis
    définissez une fonction qui renvoie l'ordonnée d'un point.

    BEGIN SOLUTION

    ``` cpp
    float ordonnee(Point p) {
        return p.y;
    }
    ```

    END SOLUTION

2.  Écrivez une procédure qui affiche les coordonnées d'un point puis
    réalisez un programme principal utilisant cette procédure.

    BEGIN SOLUTION

    ``` cpp
    void affichePoint(Point p) {
        cout << "abscisse = " <<  abscisse(p) << endl ;
        cout << "ordonnee = " <<  ordonnee(p) << endl ;
    }
    ```

    END SOLUTION

3.  Réalisez une fonction `distance` qui renvoie la distance entre
    deux points donnés.

    Rappel : $dist_{AB}$ = $\sqrt{(x_B -x_A)^2 + (y_B - y_A)^2}$

    BEGIN SOLUTION

    ``` cpp
    float distance(Point a, Point b) {
        float dx, dy ;
        dx = b.x - a.x ;
        dy = b.y - a.y ;
        return sqrt(dx * dx + dy * dy);
    }
    ```

    END SOLUTION

4.  Définissez une fonction qui étant donnés deux points $A$ et $B$,
    renvoie `true` si les deux points ne sont pas confondus, et
    transmet en résultat le point situé au milieu du segment $AB$.

    BEGIN SOLUTION

    ``` cpp
    bool milieu(Point a, Point b, Point &m){
        bool res = ((a.x != b.x) or (a.y != b.y));
        m.x = (x.a + x.b)/2 ;
        m.y = (y.a + y.b)/2 ;
        return res ;
    }
    ```

    END SOLUTION

5.  Utilisez la fonction `EgalApproché` donnée ci-dessous pour
    vérifier dans le `main` que le milieu calculé par la fonction
    précédente est bien à égale distance des deux extrémités du
    segment.

    ``` cpp
    const float e = 1e-6 ;
    bool EgalApproche(float x, float y) {
        return (fabs(x-y) < e*fabs(x)) && (fabs(x-y) < e*fabs(y));
    }
    ```

    où `fabs()` est la fonction valeur absolue pour les réels.

    BEGIN SOLUTION

    ``` cpp
    int main () {
        Point pa, pb, pm;
        litPoint(pa); litPoint(pb);
        if (not milieu(pa,pb,pm)) {
            cout << "vos 2 points sont confondus" << endl;
        } else {
            if (egalApproche(distance(pa, pm), distance(pb, pm))) {
                cout << " le milieu est en : " << endl;
                affichePoint(pm);
            } else {
                cout << "rate ! votre point est en : " << endl;
                affichePoint(pm);
            }
        }
    }
    ```

    END SOLUTION
