Modules et allocations dynamiques

Exercice 1 : Manipulation de vecteurs

Dans cet exercice, on veut construire un programme modulaire permettant de manipuler des vecteurs de double. Un vecteur sera défini comme une structure contenant sa dimension (sa taille) et ses valeurs. On prendra soin de n’allouer que la mémoire strictement nécessaire à l’exécution du programme, et de correctement libérer la mémoire ainsi allouée. Les fonctions de manipulation de vecteurs seront écrites dans un premier module vecteur. Si vous le souhaitez, vous ajouterez le mot-clé const partout où vous le jugerez utile.

  • On souhaite disposer de fonctions de saisie, d’affichage et de suppression d’un vecteur selon l’interface suivante :
struct vecteur *vecteur_saisir(int); 
void vecteur_afficher(struct vecteur *); 
void vecteur_detruire(struct vecteur *);
  • Ecrivez un fichier d’en-tête qui déclare cette interface, et définissez les fonctions ainsi déclarées dans un fichier d’implémentation. On prendra soin de demander la dimension de vecteur souhaitée avant d’appeler vecteur_saisir() pour récupérer les différents coefficients.

  • Afin de tester vos fonctions, vous écrirez un module principal qui demande la saisie d’un vecteur, l’affiche et le détruit.
  • On souhaite maintenant disposer de fonctions de calcul sur des vecteurs permettant d’obtenir le résultat de la multiplication d’un vecteur par un scalaire (en modifiant le vecteur), le produit scalaire de deux vecteurs ainsi que la norme euclidienne d’un vecteur1. L’interface est la suivante :
void vecteur_multiplication_scalaire(struct vecteur *, double); 
double vecteur_produit_scalaire(struct vecteur *, struct vecteur *); 
double vecteur_norme_euclidienne(struct vecteur *);
  • Complétez le fichier d’en-tête en déclarant cette interface, et implémentez-la.

  • On veut compter le nombre d’appels aux fonctions du module vecteur. Ajoutez une variable comptabilisant le nombre d’appels et écrivez une fonction pour récupérer cette valeur ainsi qu’une fonction pour la réinitialiser.
  • Testez vos fonctions en complétant le module principal, qui demande la saisie de deux vecteurs de même dimension, affiche leurs normes, leur produit scalaire, et enfin le nombre total d’appels à des fonctions du module.

Exercice 2 : Manipulation de matrices

  • Dans cet exercice, on veut disposer d’un module matrice de manipulation de matrices de double. Une matrice sera définie comme une structure contenant sa hauteur, sa largeur et ses vecteurs lignes. Vous utiliserez dès que possible les fonctions définies dans le module de l’exercice précédent.

  • Ecrivez une interface de saisie, d’affichage et de suppression d’une matrice, et implémentez-la. La saisie commencera par demander la dimension de la matrice souhaitée avant de récupérer les différents coefficients ligne à ligne.
  • Ecrivez une interface de manipulation de matrices qui permet de calculer la transposée d’une matrice, de multiplier une matrice par un scalaire (en modifiant la matrice), de calculer la norme de Frobenius d’une matrice2 et d’obtenir le produit matriciel de deux matrices.
  • Modifiez votre module principal pour demander la saisie de deux matrices et afficher leur multiplication par un scalaire, leurs normes de Frobenius et, si possible, leur produit matriciel.