TP C1.2 (obligatoirement dans un Terminal Linux)

Objectifs :
- terminer le TP C1.1
- apprendre quelques notions nouvelles  


I. Les types de base (les parties en orange sont données juste pour information)

Les types fournis par C sont proches des types primitifs Java (historiquement, c'est plutôt l'inverse). Mais les différences sont suffisantes pour nous poser problème si on ne les connaît pas.

1) int est bien le type entier (signé), mais alors qu'il est toujours sur 32 bits en Java, son empreinte mémoire peut varier d'une machine à l'autre en C. De même pour long. Par contre byte et short devraient bien occuper respectivement 8 et 16 bits.

2) float et double sont comme en Java (les fonctions mathématiques calculent aussi en double, donc les réels simple précision float sont peu utilisés).

3) char (pour stocker un seul caractère) n'occupe que 8 bits et est signé (-128 à +127), alors qu'il en occupe 16 en Java et n'est pas signé (0 à 65535).

4) Le type booléen n'existe pas en standard, même si des versions récentes fournissent le bool du C++.
On a coutume d'utiliser le type int (32 fois trop coûteux !) en prenant comme conventions :
- à la lecture, =0 vaut FAUX, et ≠0 vaut VRAI (dans les if et les while, par exemple)
- à l'écriture, 0 pour FAUX, et 1 pour VRAI

5) Il est possible d'utiliser des types plus exotiques tels que long int (équivalent de long), long long (dépendant de la machine), long double (sur 80 bits).

6) Il est également possible d'ajouter unsigned devant un type pour obtenir un type non signé (allant de 0 à 2n-1 au lieu de -n à +n-1).
Exemple : si int est équivalent à 'entier relatif', unsigned int est équivalent à 'entier naturel'.


II. La définition de type

Si vous trouvez fastidieux de répéter unsigned int à chaque fois que vous avez besoin d'une variable du type entier naturel, il est possible de définir un nouveau type par l'instruction :
typedef unsigned int  Naturel;
Ensuite, il suffira d'écrire Naturel n; pour déclarer une variable de ce type.

Cette possibilité bien plus générale
typedef definition_de_type  nouveau_nom ;
nous servira énormément lors du prochain TP.

Exception à la règle ci-dessus : pour définir un type tableau d'entiers, il faut écrire : typedef int TableauI[]; (donc avec les crochets à la fin), puis pour l'utiliser : TableauI vTab; par exemple.


III. Manipulations de tableaux

Lors du TP C1.1, vous avez remarqué qu'on ne pouvait pas obtenir le nombre de cases d'un tableau (sauf dans le bloc dans lequel il est créé). Cela explique pourquoi on est presque toujours obligé d'ajouter un paramètre supplémentaire aux fonctions de manipulation des tableaux pour leur passer sa taille.

Attention ! Ne pas confondre le nombre de cases et le nombre d'éléments utiles dans le tableau : celui-ci pourrait être en partie vide ...

1) Écrire un programme C comportant une fonction vmin retournant la valeur minimale d'un tableau de réels (passé en paramètre, ainsi que le nombre de valeurs à examiner) et un main comportant :
- la déclaration/initialisation d'un tableau de réels (d'au moins 7 valeurs)
- l'affichage du résultat de vmin avec en 2ème paramètre la taille du tableau (préalablement calculée)
- l'affichage du résultat de vmin avec en 2ème paramètre 3 ou 4 (de telle sorte que le résultat soit différent)

2) Écrire un programme C comportant une fonction imin (n'appelant pas la fonction vmin) retournant l'indice du minimum d'un tableau de réels (passé en paramètre, ainsi que le nombre de valeurs à examiner) et un main comportant :
- la déclaration/initialisation d'un tableau de réels (d'au moins 7 valeurs, avec au moins 2 fois la valeur minimale)
- l'affichage du résultat de imin avec en 2ème paramètre la taille du tableau (préalablement calculée)
Contrainte : Si la valeur minimale apparaît plusieurs fois dans le tableau, imin doit retourner le plus grand indice, tout en n'affectant pas la variable contenant la valeur minimale courante si celle-ci ne change pas !

3) Pour ceux qui ont montré leur solution des deux premiers exercices à l'intervenant, écrire un programme C comportant une procédure affiche2 qui devra afficher dans l'ordre croissant des valeurs provenant de 2 tableaux de réels (de taille différente) triés par ordre croissant. affiche2 aura donc 4 paramètres : 2 x (un tableau + son nombre d'éléments).
Contrainte : Définir le type tableau et l'utiliser aux 4 endroits où il peut être utilisé.
Conseils : Comme cet algorithme n'est pas simple, il est conseillé (dans la boucle) de séparer la partie où l'on choisit dans quel tableau on va prendre la prochaine valeur, de la partie où l'on prend la valeur et fait évoluer les indices. D'autre part, la boucle 'Faire ... Tantque' semble bien adaptée ici :
do { instructions } while (condition); 
Exemple pour tester : { -5.0, -5.0, -4.44, -2.2, 1.1, 3.0, 6.6, 7.77 } et { -11.1, -3.0, -2.2, 5.5, 8.8, 9.9 }