TP Informatique

28
UNSA/IUT de Nice - département GEII I1 - TP 1ère Année 08/08/2007 JLS page 1/56 Plan des TP Les TP durent 3 heures et se font sur machine. Un compte rendu de TP sera relevé en fin de séance. Ce compte rendu se fera sous OpenOffice (copie des sources des programmes et des copies d'écran d'exécution). A la fin des 7 séances de TP,vous aurez un partiel de TP d'une durée de 3 heures ou vous programmerez seul. Vous aurez donc 2 notes de TP: une note de séance qui sera la moyenne des notes des 7 séances (coeff 1/3) une note de partiel (coeff 2/3). Pour chaque TP (excepté le premier TP), la préparation est obligatoire. Un compte rendu de TP devra être remis à l'enseignant en debut de séance. Plan des TP 1 TP1 Premiers programmes 2 TP2 Résolution d'équation du second degré 18 TP3 Algorithmique 1 25 TP4 Algorithmique 2 29 TP5 Tableaux et chaînes de caractères 33 TP6 Les fonctions 37 TP7 Chaîne de compilation, fonctions et pointeurs 43 UNSA/IUT de Nice - département GEII I1 - TP 1ère Année 08/08/2007 JLS page 2/56 TP1 Premiers programmes Thèmes Programmation sous Visual C++ , notion de projet, d'exécutable Utilisation du débuggeur. Opérations arithmétiques et logiques. Règles de programmation. Premiers programmes, utilisation de puts, printf, putchar, boucle for. Utilisation de l'aide, exécution d'un programme d'exemple. Introduction à la boucle for. Préparation Lire les documents ressources en fin de TP. Règles de programmation : Tous les programmes que vous allez écrire vont être sauvés dans un fichier ayant comme nom TPi_exoj.c avec i le numéro du TP et j le numéro de l'exercice. Tous les fichiers du tp1 seront sauvés dans le répertoire i1/tp1 sous votre compte (i1/tp2 pour le tp2 etc…). Chaque programme devra avoir un en-tête dans lequel devra figurer le nom du fichier, l'auteur, la description du programme et la date de création ( et peut-être de modification). //************************************************************************ // // File........: nom_du_fichier.c // // Author(s)...: NOM_AUTEUR // // Description.: but du programme (à détailler) // // CREATION : 05/09/2006 MODIFICATION : // //************************************************************************* #include <stdio.h> #include <stdlib.h> int main(void) { // le programme system("PAUSE"); return 0; } Travail à faire : Prise en main de Visual C++ en mode console Créer le répertoire i1 sous votre compte. Lancer Visual Studio.

Transcript of TP Informatique

Page 1: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 1/56

Plan des TP Les TP durent 3 heures et se font sur machine. Un compte rendu de TP sera relevé en fin de séance. Ce compte rendu se fera sous OpenOffice (copie des sources des programmes et des copies d'écran d'exécution). A la fin des 7 séances de TP,vous aurez un partiel de TP d'une durée de 3 heures ou vous programmerez seul. Vous aurez donc 2 notes de TP:

� une note de séance qui sera la moyenne des notes des 7 séances (coeff 1/3)

� une note de partiel (coeff 2/3). Pour chaque TP (excepté le premier TP), la préparation est obligatoire. Un compte rendu de TP devra être remis à l'enseignant en debut de séance.

Plan des TP 1

TP1 Premiers programmes 2

TP2 Résolution d'équation du second degré 18

TP3 Algorithmique 1 25

TP4 Algorithmique 2 29

TP5 Tableaux et chaînes de caractères 33

TP6 Les fonctions 37

TP7 Chaîne de compilation, fonctions et pointeurs 43

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 2/56

TP1 Premiers programmes

Thèmes

� Programmation sous Visual C++ , notion de projet, d'exécutable � Utilisation du débuggeur. � Opérations arithmétiques et logiques. � Règles de programmation. � Premiers programmes, utilisation de puts, printf, putchar, boucle for. � Utilisation de l'aide, exécution d'un programme d'exemple. � Introduction à la boucle for.

Préparation

Lire les documents ressources en fin de TP.

Règles de programmation :

Tous les programmes que vous allez écrire vont être sauvés dans un fichier ayant comme nom TPi_exoj.c avec i le numéro du TP et j le numéro de l'exercice. Tous les fichiers du tp1 seront sauvés dans le répertoire i1/tp1 sous votre compte (i1/tp2 pour le tp2 etc…). Chaque programme devra avoir un en-tête dans lequel devra figurer le nom du fichier, l'auteur, la description du programme et la date de création ( et peut-être de modification). //************************************************* *********************** // // File........: nom_du_fichier.c // // Author(s)...: NOM_AUTEUR // // Description.: but du programme (à détailler) // // CREATION : 05/09/2006 MODIFICATION : // //************************************************* ************************ #include <stdio.h> #include <stdlib.h> int main( void ) { // le programme system( "PAUSE"); return 0; }

Travail à faire : Prise en main de Visual C++ en mode console

� Créer le répertoire i1 sous votre compte.

� Lancer Visual Studio.

Page 2: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 3/56

� Créer un nouveau projet tp1 (Fichier, Nouveau, Projet).

� Décocher "Créer le répertoire pour la solution"

Le fait de créer un nouveau projet va créer automatiquement le répertoire tp1.

� Dans la fenêtre suivante, dans paramètres de l'application choisir Application console et projet vide.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 4/56

A partir de là, VC++ a créé un répertoire tp1 et placé les fichiers permettant la gestion du projet. Pour créer un exécutable, il faut placer dans le projet un fichier source (xxx.c) avec l'extension ".c" contenant le code de l'application.

� Pour cela , clic droit sur fichier source, Ajouter, Nouvel élément,

� Dans la fenêtre suivante, le fichier à ajouter se nomme tp1_exo1.c où se trouvera le code du premier exercice. Cliquer sur Ajouter.

On obtient alors un fichier vide.

� Recopier le fichier modèle vu précédemment et modifier l'en-tête.

Page 3: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 5/56

programme à placer

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 6/56

� Placer à la place du commentaire les lignes suivantes : int n1=5; int nRes=6; printf( " j'ai une valeur a afficher :%d\n" ,n1); printf( " j'ai deux valeurs a afficher :%d et %d \n" ,n1,nRes); puts ( "operations aritmetiques" ); nRes=n1*3; printf( "%d*2=%d\n" ,n1,nRes); nRes=n1/2; printf( "%d/2=%d\n" ,n1,nRes); nRes=n1%2; printf( "%d%2=%d\n" ,n1,nRes); nRes=n1-2; printf( "%d-2=%d\n" ,n1,nRes); puts ( "operations logiques" ); nRes=n1&0x07; printf( "%d&2=%d\n" ,n1,nRes); nRes=n1|0x07; printf( "%d|2=%d\n" ,n1,nRes); nRes=n1^0x07; printf( "%d^2=%d\n" ,n1,nRes); puts ("fin du programme");

� Lancer le programme. Clic sur la flèche verte Une fenêtre s'affiche , cocher la case "Ne plus afficher cette boite de dialogue"., puis clic sur oui.

------ Début de la génération : Projet : tp1, Confi guration : Release Win32 ------ Compilation en cours... tp1_exo1.c Édition des liens en cours... Génération de code en cours Fin de la génération du code Incorporation du manifeste en cours... Le journal de génération a été enregistré à l'empla cement "file://g:\iut_courant\i1\programmes_2007_2008\tp1\ Release\BuildLog.htm" tp1 - 0 erreur(s), 0 avertissement(s) ========== Génération : 1 a réussi, 0 a échoué, 0 m is à jour, 0 a été ignoré ==========

1) Analyser chaque ligne affichée et expliquer le résultat obtenu (Compléter le tableau ci-dessous).

OPERATION RESULTAT

Page 4: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 7/56

nRes=n1*3 nRes=n1/2; nRes=n1%2; nRes=n1-2; nRes=n1&0x07; nRes=n1|0x07; nRes=n1^0x07;

Trouver les erreurs de compilation

Nous allons ici voir comment le compilateur peut aider à trouver les erreurs faites lors de la saisie du code. Pour cela nous allons faire un certain nombre d'erreurs classiques :

� Première erreur : oubli du point virgule. � Deuxième erreur : non déclaration d'une variable. � Troisième erreur : problème de l'apostrophe dans le "printf". � Quatrième erreur : appel à une fonction inconnue . � Cinquième erreur : oubli de la fonction "system".

Première erreur : l'oubli du point virgule.

� Enlever le point virgule à la fin de l'instruction : nRes=n1*3

� Puis lancer le programme Le programme affiche le même résultat qu'auparavant !!! Cela est tout simplement du au fait que lorsque vous lancez le programme, VC++ fait 2 opérations :

� appel au compilateur qui génère le fichier exécutable, � puis lancement de l'exécutable (avec le chargement des dll permettant l'exécution du programme).

Dans les 2 cas , l'affichage des informations issues de ces 2 étapes se fait dans la fenêtre "sortie" ( ALT+2 ou dans le menu ,Affichage, Sortie). Vous ne voyez donc que les informations issues du lancement de l'exécutable , les informations issues du compilateur sont masquées. Si le compilateur rencontre une erreur dans le fichier tp1_exo1.c, il est incapable de générer le fichier exécutable et c'est l'ancien exécutable qui est lancé. Vous avez donc l'impression que votre programme fonctionne alors que c'est l'ancien exécutable qui est lancé! Pour vérifier que la compilation s'est bien passée, il faut visualiser les messages issus du compilateur: Pour cela dans la fenêtre "sortie" choisir "Afficher la sortie à partir de Générer" pour avoir les messages issus de la compilation. Vous auriez pu plus simplement faire un F7 (Générer la solution) qui permet de lancer le compilateur sans lancer l'exécution à la suite. Par la suite il sera préférable de choisir cette solution qui a l'avantage de ne pas masquer les messages d'erreurs issus du compilateur.

Vous obtenez la ligne suivante : .\tp1_exo1.c(25) : error C2146: erreur de syntaxe : absence de ';' avant l'identificateur 'printf'

Ainsi qu'un marqueur vert sur la ligne ayant un problème :

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 8/56

Deuxième erreur : non déclaration d'une variable. Toutes les variables doivent être déclarées avant d'être utilisées. Quel message donne le compilateur fasse à ce type d'erreur ?

� Remplacer la ligne int n1=5; par n1=5;

� Générer la solution (F7) : Vous obtenez la ligne suivante : .\tp1_exo1.c(18) : error C2065: 'n1' : identificate ur non déclaré

D'autres erreurs à la suite de cette erreur sont vues par le compilateur. Ces erreurs sont dues à la première erreur et ne doivent donc pas être corrigées. Il faut toujours traiter les erreurs de compilation dans l'ordre et ne pas hésiter après avoir traité la première erreur à refaire une génération de code. Il est possible qu'un certain nombre d'erreurs disparaissent alors !!! troisième erreur : problème de l'apostrophe dans le printf

� Remplacer printf("%d-2=%d\n",n1,nRes); par printf("%d-2=%d\n,n1",nRes);

� Générer la solution Vous obtenez la ligne suivante :

.\tp1_exo1.c(31) : warning C4313: 'printf' : confli t entre '%d' dans la chaîne de format et l'argument 2 de type 'char [12]'

Il faut lire attentivement le message issu du compilateur. Ce message n'est pas un message d'erreur mais un Warning (avertissement). Un avertissement permet de donner une information au programmeur mais sans bloquer la génération du code. Le compilateur génère l'exécutable. Par contre l'affichage du résultat est incohérent.

2) Lancer le programme et donner le résultat affiché par cette ligne de code. Conclure sur l'importance des Warnings.

Quatrième erreur : appel à une fonction inconnue.

� Remplacer system("PAUSE"); par systeme("PAUSE");

l'erreur se situe ici !

Page 5: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 9/56

� Générer la solution : Vous obtenez les lignes suivantes :

.\tp1_exo1.c(42) : warning C4013: 'systeme' non déf ini(e) ; extern retournant int pris par défaut Compilation en cours... tp1_exo1.c .\tp1_exo1.c(42) : warning C4013: 'systeme' non déf ini(e) ; extern retournant int pris par défaut Édition des liens en cours... tp1_exo1.obj : error LNK2001: symbole externe non r ésolu _systeme

Le compilateur génère un warning à la ligne 42.Dans cet avertissement le compilateur informe que la fonction "systeme" n'est pas définie (dans les fichiers de déclaration #include""). Après la compilation, l'éditeur de lien vient assembler le code généré par tp1_exo1.c avec le code des fonctions appelées (printf, puts, systeme). C'est l'éditeur de lien qui stoppe la génération du code, puisqu'il ne trouve pas dans la bibliothèque des fonctions disponibles le code de la fonction systeme. Oubli de la fonction system("PAUSE");

3) Générez la solution. Existe-t-il une erreur de compilation ? Lancer le programme. Que se passe-t-il ? Expliquer et en déduire le rôle de la fonction system.

Travail à faire : Prise en main du Debug sous Visual C++ en mode console

Nous allons voir un outil très utilisé pour trouver les bugs du programme. Le bug ou bogue informatique est une erreur qui apparaît dans un programme. Les erreurs simples sont détectées par le compilateur, mais les erreurs de conceptions ne peuvent être détectées que lors de l'exécution du programme. Au moment ou une erreur apparaît, il peut être intéressant de stopper le programme juste avant l'arrivée de l'erreur et de visualiser les variables. C'est le débuggeur qui permet de faire cette opération.

� Dans la zone Explorateur de solution, cliquer sur Propriétés (ou projet, Propriétés du Projet)

� Et modifier dans C/C++ , Optimisation, le niveau d'optimisation du code : Désactivé. Pour visualiser le Débug en mode pas à pas comme nous voulons le faire, il est important que le code ne soit pas optimisé. En effet l'optimisation du code peut amener le compilateur à ne pas coder des instructions qui ne sont pas utiles pour la suite du programme.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 10/56

� Mettre un point d'arrêt (double-clic à gauche de la ligne ou l'on veut arrêter le code).Un point rouge apparaît.

� Lancer le programme

� Ajouter la fenêtre des variables locales ou ajouter un espion Ce qui va nous permettre de visualiser directement les variables nRes et n1.

� Exécuter le programme en mode pas en pas (F10) et vérifier qu' après chaque calcul (flèche jaune sur la fonction printf) la variable nRes est bien mise à jour. On rappelle qu'une valeur précédée de 0x est en hexadécimal.

Page 6: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 11/56

Après 4 appuis sur la touche F10.

On peut voir que l'affichage suit bien l'exécution en mode pas à pas.

4) En utilisant le débogueur donner le résultat des opérations 255 ET 0x80, 0 OU 1 et 0 OU EXC 1.Pour cela modifier le programme tp1_exo1.c et ajouter ces opérations au début du programme (le résultat de l'opération est stocké dans nRes). Ne pas pas placer de fonction printf après chaque calcul. Faire une copie d'écran.

5) Sans utiliser le débogueur, afficher les résultats de ces opérations en ajoutant à la fin de chaque calcul l'affichage de la valeur nRes (printf).Faire une copie d'écran dans le compte rendu.

utilisation des fonction d'affichages puts, printf, putchar : tp1_exo2.c

� Sous le même projet retirer le fichier tp1_exo1.c

nRes a été mise à jour (valeur en rouge)

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 12/56

� A la question Supprimer ou Enlever, choisir Enlever. En effet, il est important de garder le source tp1_exo1.c écrit précédemment. Tous les fichiers que vous allez créé ne devront pas être effacés !

� Puis clic droit sur fichier source, Ajouter, Nouvel élément et dans Nom: tp1_exo2.c

Page 7: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 13/56

� Copier le modèle de la page 2 (Règles de programmation) et modifier l'en-tête. Chaque nouveau programme devra avoir cet en-tête ! Modifier la description du programme de l'en-tête " tests des fonctions printf, puts, putchar". Rajouter les lignes suivantes dans le programme, puis tester. Compléter les commentaires pour chaque ligne.

puts("******************************************"); puts(" test "); //commentaire à faire puts(" \ttest \\t "); //commentaire à faire puts(" \ntest \\n "); //commentaire à faire puts(" \" test \" "); //commentaire à faire puts("_________________________________________");

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 14/56

6) Faire la copie d'écran du résultat affiché dans le compte rendu.

7) Rajouter les lignes suivantes et écrire les commentaires à chaque ligne. Attention placer les déclarations de variables nVal et f en début de programme ! Le compilateur n'accepte pas les déclarations dans le code.

int n = 32; //déclaration et initialisation entier double d=2.34; //déclaration et initialisation réel printf ( "n vaut %d.\n" , n); //commentaire à faire printf ( "n vaut %10d.\n" , n); //commentaire à faire printf ( "n vaut 0x%x.\n" , n); //commentaire à faire printf ( "hello" ); printf ( " hello\n" ); //commentaire à faire printf ( "%s \n" , "Coucou" ); //commentaire à faire printf ( "%12s \n" , "Coucou" ); //commentaire à faire printf ( "d vaut %f\n" , d); //commentaire à faire printf ( "d vaut %e\n" , d); //commentaire à faire printf ( "d vaut %10.3f\n" , d); //commentaire à faire printf ( "d vaut %g\n" , d); //commentaire à faire

Page 8: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 15/56

8) Rajouter les lignes suivantes à la suite. Donner le caractère ayant le code 0x5F et 0xB3. Donner le résultat affiché par chaque ligne.

int i; // a metre en début de code putchar( '_' ); putchar(0x5F); putchar( '-' ); puts( "" ); for (i=0; i<10; i++) putchar( 'A' ); puts( "" ); putchar( '|' ); putchar(0xB3); putchar( '\n' ); putchar( 'x' ); puts( "" );

9) Mettre la copie d'écran du résultat obtenu sur le compte rendu.

Mon premier programme : tp1_exo3.c

� En gardant les mêmes règles que précédemment : enlever le fichier tp1_exo2.c et le remplacer par un nouveau fichier tp1_exo3.c, avec en-tête et fonction main.

10) Ecrire un programme qui affiche : b (utilisation de putchar avec affichage d'un variable caractère notée c) AAA (utilisation de puts) 234 (utilisation de printf avec affichage d'une variable de type int notée n) 43.5 (utilisation de printf avec affichage d'une variable de type double notée d) bbbbbbbbbbbbbbb (utilisation d'une boucle for, afficher 15 b) 2 ET 3 = 2 (calcul + affichage du résultat du calcul, variable entière nRes) 3 <<1 = 6 (calcul + affichage du résultat du calcul, variable entière nRes)

Notion de table ASCII : tp1_exo4.c

La notion de table ASCII date du milieu des années 70 lorsqu'il a fallu transmettre les données à l'aide de la ligne téléphonique avec le télétexte (téléscripteurs). S'est alors posé le problème du codage des caractères envoyés. C'est le code ASCII qui s'est alors imposé et qui consistait à utiliser un code sur 7 bits pour transmettre les caractères et les caractères de contrôles (retour à la ligne, tabulation, ...). Ce code a ensuite été utilisé pour coder les caractères dans les ordinateurs. Le but du programme que l'on va lancer est de visualiser cette table ASCII.

� Dans le même projet, tester le code suivant dans le fichier tp1_exo4.c . int i; for (i=0;i<=127;i++){ printf("%d | 0x%X =",i,i); putchar(i);puts(""); }

Le caractère 7 de la table ASCII correspond au bip que vous entendez. On pourra tester avec l'instruction putchar(7).// pour entendre bip.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 16/56

11) Expliquer le résultat obtenu et compléter le tableau suivant. Valeur en décimal Valeur en hexadécimal lettre affichée

0x30 0x31 ... 0x39 ... 0x41 0x42 ... 0x59 0x5A ... 0x61 0x62 ... 0x7A

12) Modifier le code de la fonction ASCII avec le code ci-dessous . Conclure int i; for(i=0;i<=127;i++){ printf("%d | 0x%X = %c\n",i,i,i); }

13) Existe-t-il une différence entre putchar(i) et printf("%c",i) ?

14) Donner le résultat de la ligne suivante int n=48; printf("%c = %d",n,n);

Mon deuxième programme : tp1_exo5.c

15) En utilisant la boucle for ,écrire un programme qui affiche : 1 2 3 4 5 6 7 8 9

16) En utilisant la boucle for ,écrire à la suite un programme qui affiche les lettres de l'alphabet :

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Page 9: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 17/56

Ressources :Codage des données

TYPES BASE DECIMALES

BASE HEXADECIMALES

REPRESENTATIONS BINAIRES

char 100 0x64 0110 0100 unsigned char 255 0xFF 1111 1111

int -1 0xFFFFFFFF 8 fois 1111 unsigned int 2^32-1 0xFFFFFFFF 8 fois 1111

float 50,25 0x4249 0x0000

0100 0010 0100 1001 0000 0000 0000 0000

Pour un nombre réel : 2 types possibles float et double. Les nombres de type float sont codés sur 32 bits dont :

� 23 bits pour la mantisse

� 8 bits pour l'exposant

� 1 bit pour le signe (s) bit de signe : si (s)=0 valeur positive sinon valeur négative Mantisse codée sur 23 bits 1 ≤ Mantisse <2 Mantisse = 1 + m12

-1 + m22-2+ .. + m232

-23 Exposant codé sur 8 bits (-127=00000000 et 128=11111111) Exposant = e72

7 + e626+ .. + e02

0 -127

Les nombres de type double sont codés sur 64 bits dont :

� 52 bits pour la mantisse

� 11 bits pour l'exposant

� 1 bit pour le signe

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 18/56

TP2 Résolution d'équation du second degré

Thèmes

� Utilisation des structures de contrôles if et for . � Différences entre les types float et double. � Utilisation de l'aide de VC++. � Utilisation des fonctions mathématiques sin, cos, tan, pow et sqrt de la bibliothèque <math.h>. � Introduction aux pragmas.

Préparation

1) Expliquer ce que fait le programme ci-dessous et plus particulièrement l'utilisation faite de la fonction printf.

int main (void) { int i; char sz[]="toto"; int nAge=20; double dCompte=123.89; printf("\t|%10s|%5s|%10s|\n","nom","age","valeur" ); printf("\t|----------|-----|----------|\n"); printf("\t|%10s|%5d|%10.2f|\n",sz,nAge,dCompte); printf("\t|----------|-----|----------|\n"); while (1); return 0; }

2) Expliquer ce que fait le programme ci-dessous. Pourquoi le deuxième appel à la fonction getchar() renvoie toujours à l'écran "pas un chiffre" ? Pour répondre à la question on pourra se rappeler que l'utilisateur entre un chiffre suivi d'un retour chariot afin de débloquer la fonction getchar.

#include <stdio.h> int main ( void ) { char c; c=getchar(); if (c>='0' && c<='9') puts("un chiffre"); else puts("pas un chiffre"); c=getchar(); if (c>='0' && c<='9') puts("un chiffre"); else puts("pas un chiffre"); while (1); return 0; }

3) Ecrire un programme qui demande à l'utilisateur de taper un entier et qui affiche GAGNE si l'entier est entre 56 et 78 bornes incluses PERDU sinon.

Page 10: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 19/56

4) Commenter chaque ligne du programme ci-dessous .Donner les valeurs de CHAR_MIN, CHAR_MAX, INT_MIN, INT_MAX ainsi que la taille d'un int, float et double.

#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <math.h> int main( void ) { puts( "************************************************** *******" ); puts( " \ttaille en octet, valeur min et max pour chaque type " ); puts( "************************************************** *******" ); puts( "" ); printf( "type \t|%10s|%15s|%15s|\n" , "taille" , "min" , "max" ); puts( "__________________________________________________ _" ); printf( "char \t|%10d|%15d|%15d|\n" , sizeof ( char ),CHAR_MIN,CHAR_MAX); printf( "short \t|%10d|%15d|%15d|\n" , sizeof ( short ),SHRT_MIN,SHRT_MAX); printf( "int \t|%10d|%15d|%15d|\n" , sizeof ( int ),INT_MIN,INT_MAX); printf( "long \t|%10d|%15d|%15d|\n" , sizeof ( long ),LONG_MIN,LONG_MAX); printf( "float \t|%10d|%15e|%15e|\n" , sizeof ( float ),pow(2,-126),pow(2,+128)); printf( "double \t|%10d|%15e|%15e|\n" , sizeof ( double ),pow(2,-1023),pow(2,1023)); puts( "__________________________________________________ _" ); system( "PAUSE"); return 0; }

Travail à faire

� Comme pour chaque nouveau TP, créer un projet TP2 (Fichier , Nouveau, Projet, Application Console Win32, nom:tp2, puis fenêtre suivante , paramètres de l'application: projet vide). Pour chaque nouveau programme, ajouter le fichier créé au projet (Fichier source, clic droit, ajouter, nouvel élément et enlever le programme précédent.

5) Ecrire un programme tp2_exo5.c qui demande une valeur de début, une valeur de fin et qui affiche toutes les valeurs comprises entre début et fin sauf celle égale à debut+2

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 20/56

Différences entre les types float et double

6) Ecrire le programme suivant (tp2_exo6.c). Quelle est la valeur finale de fS ? #include <stdio.h> #include <stdlib.h> int main ( void ) { int i ; float fS ; fS = 1000.0 ; for (i=0; i<100000; i++) fS=fS+0.1; printf( "valeur theorique %f et valeur apres calc ul %f\n",11000.0,fS); system("PAUSE"); return 0; }

7) Rajouter à la suite de la boucle for le même calcul mais cette fois-ci en utilisant la variable dS de type double. Tester. Expliquer !

Calculs trigonométriques

� Questions préliminaires : ouvrir math.h dans le répertoire include. Le fichier math.h est un fichier de déclaration des fonctions mathématiques utilisables en C. Comme tous les fichiers de déclarations de fonctions celui-ci est placé dans le répertoire par défaut des "include".

� Rechercher la fonction sin. _CRTIMP double __cdecl sin ( double );

Cette ligne signifie que la fonction sin prend en argument un "double" et renvoie un "double".

8) Les fonctions cos, exp, log10,tan, cosh, sqrt existe-t-elle ? Si oui quel est le but de chacune de ces fonctions

� De la même façon rechercher (CTR+F) la ligne contenant PI (ne pas cocher mot entier). #define M_PI 3.14159265358979323846

9) Quelles sont les valeurs de M_E et M_PI_2 ?

L'utilisation du fichier de déclaration peut être une source d'information pour la compréhension et la découverte des fonctions utilisables par le programmeur. Une autre source d'information pour le programmeur est évidemment l'utilisation de l'aide (touche F1). Nous allons utiliser l'aide de VC++ express. L'aide de VC++ est très bien documentée et doit être utilisée le plus possible.

� Taper F1 pour ouvrir la fenêtre d'aide. Puis rechercher math routines puis math constant.

Page 11: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 21/56

L'aide en plus des explications sur les fonctions mathématiques vous fournit un exemple (clic sur example).

10) Ecrire un programme qui affiche le cosinus,le sinus et la tangente de 45 °. On pourra s'aider de l'exemple et le modifier.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 22/56

L'aide explique qu'il existe des constantes mathématiques utiles pour le programmeur. Pour pouvoir utiliser ces constantes, le programmeur doit taper les 2 lignes suivantes en début de programme :

#define _USE_MATH_DEFINES

#include <math.h>

Une autre solution consiste à utiliser les pragma ou directives. Ces pragma commencent par # . Dans l'exemple ci-dessous après l'insertion de la bibliothèque math.h se trouvant dans le répertoire par défaut des "include" les lignes suivantes définissent M_PI seulement si M_PI n'est pas défini. Le compilateur C issu du GNU (Linux) gcc possède lui une bibliothèque mathématique math.h dans laquelle M_PI est défini. Le code ci-dessous permet donc une compilation du programme avec VC++ ou bien avec gcc.

#include <math.h>

#ifndef M_PI

#define M_PI 3.14159265358979323846

#endif

Page 12: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 23/56

11) Tester le programme ci-dessous : #define _USE_MATH_DEFINES #include <math.h> #include <stdio.h> int main() { double dy; printf( "log10(%g)=%g\n" ,10.0,log10(10)); dy=exp(1); printf( "exp(%g)=%g\n" ,1.0,dy); printf( "M_E=%g\n" ,M_E); printf( "cos(10)=%g\n" ,cos(M_PI/180*10)); system( "PAUSE"); return 0; }

On désire écrire un programme qui affiche une table de trigonométrie. Le programme demande initialement les angles de début et de fin, ainsi que le pas, le tout en degré. L’organigramme du programme est le suivant:

OUI NON

entrée de inf, sup, step

deg = inf

deg<sup

deg = deg + step

calculer les valeurs des sin, cos tg et les afficher ...

Résultat du programme : On prendra soin d'utiliser les types qui conviennent pour le calcul des cos, sin et tan.

12) Ecrire le programme dont le cahier des charges a été donné ci-dessus.

13) Modifier le code pour que lorsqu'une valeur est supérieure à une constante MAX (par exemple 100000) le programme affiche INFINI.

lire les valeurs de inf, sup et step (en degré) Pour i=inf jusqu'à sup (par pas de step) k ← transformer i en radian calculer puis afficher sin(k),cos(k) et tg(k) FinPour

Algorithme

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 24/56

Résolution d'équation du second degré On désire écrire un programme de résolution d'équation du second degré. Ce programme résout l’équation ax2+bx+c=0 où les coefficients a,b,c sont entrés au clavier. Le résultat est ensuite affiché. Pour le calcul de la racine carrée, on utilise la fonction sqrt() définie dans la bibliothèque <math.h> double dy= sqrt(4.0); // résultat dy=2.0.

Si le coefficient a est non nul, l’organigramme du programme est le suivant :

d<0

d = b2 - 4ac

d==0

deux racines réelles x1 = -b - √d / 2a x2 = -b + √d / 2a

une racine réelle x1 = -b / 2a

pas de racines réelles

OUINON

OUINON

14) Ecrire le programme dont le cahier des charges est donné ci-dessus .

15) Modifier le programme pour que celui-ci fonctionne sans aucune restriction sur a, b et c. Faire l’organigramme de ce programme puis l'écrire et le tester.

Page 13: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 25/56

TP3 Algorithmique 1

Thèmes

� Algorithmique de base : utilisation de toutes les structures de contrôle. � Utilisation des fonctions ceil et floor et pow.

Préparation

1) Donner le résultat de l'extrait ci-dessous. Expliquer chacun des résultats affichés à l'écran.

int main() { int nA = 2, nB= 0,nRes ; nRes=(5==5)&&(6==2); printf( "1:%d\n" ,nRes); nRes=(5>1)||(6>8); printf( "2:%d\n" ,nRes); nRes=(nA == (nB+2)); printf( "3:%d\n" ,nRes); nB += 4; printf( "4:%d\n" ,nB); nA=5;nB=6; if (nA != nB) puts( "5:nA different de nB" ); nA %= 2; printf( "6:%d\n" ,nA); if ((nA>0)&&(nA<6)) puts( "7:nA compris entre 1 et 5" ); nA=0; if ((nA>0)||(nA<6)) puts( "8:nA compris entre 1 et 5" ); system( "PAUSE"); return 0; }

2) Evaluer nRes pour n =2 et n=10, on suppose que nRes et n sont des entiers. nRes= (n==1)||(n>=2); nRes= (n==0)||((n>=2)&&(n<9)); nRes= (n==1)||(n>=2)||(n<9); nRes= (n=1)||((n>=2)&&(n<9));

3) Donner le résultat affiché par l'extrait suivant (n est un entier) et expliquer. n=3; if (n=5) puts("n=5"); n=3; if (n) puts("n"); if (n<4) puts("n<4");

4) Ecrire un programme qui affiche tous les entiers de 8 jusqu’à 23 (bornes incluses) en utilisant une structure en for puis en while.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 26/56

Travail à faire :

5) En utilisant l'aide de VC++ rechercher la fonction pow. L'aide étant en anglais, expliquer les lignes suivantes tirées de l'aide :

The pow function computes x raised to the power of y.

double pow( double x, double y ); résultat de l'aide :

Page 14: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 27/56

6) Ecrire un programme qui lit une valeur entière et affiche les 10 premières puissances de cette valeur (prendre la fonction pow() définie dans <math.h>.

7) Grâce à l'aide de VC++ (touche F1) rechercher le but des fonctions ceil et floor. L'aide de la fonction floor fournit un exemple. Recopier et commenter cet exemple dans le compte-rendu.

8) Ecrire un programme qui demande à l'utilisateur d'entrer un chiffre à virgule et qui arrondit à l'entier le plus proche. On utilisera pour cela la fonction floor() pour récupérer la partie entière du chiffre et on comparera le chiffre à virgule à la valeur entière trouvée + 0.5.

Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées (questions 9, 10, 11 ). Demander à l'enseignant quelle question vous devez traiter.

9) Ecrire un programme qui demande à l’utilisateur de taper 10 entiers et qui affiche leur somme.

10) Ecrire un programme qui demande à l’utilisateur de taper 10 entiers et qui affiche le plus petit de ces entiers.

11) Ecrire un programme qui demande à l'utilisateur de taper un entier N et qui calcule u(N) défini par :

u(0)=3 u(n+1)=3.u(n)+4 Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées (questions 12, 13, 14 ). Demander à l'enseignant quelle question vous devez traiter.

12) Ecrire un programme qui demande à l'utilisateur de taper une valeur entière comprise entre 1 et 10 inclus et ce jusqu'à ce que l'utilisateur entre une valeur en dehors des limites. Le programme affiche alors la somme de tous les nombres saisis excepté le dernier (qui était en dehors des limites).

13) Ecrire un programme qui demande à l'utilisateur une lettre et ce tant que la lettre saisie n'est pas une voyelle. Le programme affiche alors le nombre de 'b' entrés par l'utilisateur. L'utilisateur devra saisir une lettre suivie du retour chariot à chaque nouveau passage dans la boucle. Utiliser getchar pour lire le caractère. Attention au retour chariot qui est vue comme un caractère!

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 28/56

14) Ecrire un programme qui calcule le carré de la valeur entière saisie par l'utilisateur et l'affiche. Le programme demande une valeur entière, calcule le carré de cette valeur, l'affiche et recommence tant que cette valeur est supérieure à 0. Ensuite le programme affiche la somme des carrés calculés.

Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées (questions 15, 16, 17 ). Demander à l'enseignant quelle question vous devez traiter.

15) Ecrire un programme qui permet de faire des opérations sur un entier (valeur initiale à 0). Le programme affiche la valeur de l'entier puis affiche le menu suivant :

1. Ajouter 1 2. Multiplier par 2 3. diviser par 2 4. Quitter

Le programme demande alors de taper un entier entre 1 et 4. Si l'utilisateur tape une valeur entre 1 et 3, on effectue l'opération, on affiche la nouvelle valeur de l'entier puis on réaffiche le menu et ainsi de suite jusqu'à ce qu'on tape 4. Lorsqu'on tape 4, le programme se termine.

16) Ecrire un programme qui permet d'afficher le code ASCII de certaines lettres de la table. Le programme affiche le menu suivant :

1. Afficher le code ASCII des chiffres 2. Afficher le code ASCII des lettres minuscules 3. Afficher le code ASCII des lettres majuscules 4. Quitter

Le programme demande alors de taper un entier entre 1 et 4. Si l'utilisateur tape une valeur entre 1 et 3, on affiche les codes ASCII demandés puis on réaffiche le menu et ainsi de suite jusqu'à ce qu'on tape 4. Lorsqu'on tape 4, le programme se termine.

17) Ecrire un programme qui permet d'afficher un certain nombre de calcul sur un entier préalablement saisi par l'utilisateur. Le programme après avoir lu la valeur entière n, affiche le menu suivant :

1. Afficher la somme de 1 à n 2. Afficher la somme des carré :1 + 2*2 + 3*3 + .. + n*n 3. Afficher si n est pair ou impair 4. Quitter

Le programme demande alors de taper un entier entre 1 et 4. Si l'utilisateur tape une valeur entre 1 et 3, le programme effectue le calcul demandé puis réaffiche le menu et ainsi de suite jusqu'à ce qu'on tape 4. Lorsqu'on tape 4, le programme se termine. La valeur n est saisie une seule fois en début de programme.

Page 15: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 29/56

TP4 Algorithmique 2

Thème

� Programmation avec toutes les structures de contrôles. � Utilisation des fonctions srand et rand.

Préparation

1) Ecrire un programme permettant d'afficher les 10 premiers nombres pairs. Utiliser un boucle for, while et do while.

Rappel sur les opérateurs modulo et ET logique: si a est impair a%2 renvoie 1 et si a est pair a%2 renvoie 0. Si a est impair a&1 renvoi 1 et si a est pair a&1 renvoi 0 (Cf TD3).

2) Que fait le programme suivant si on rentre 12 puis 23 ? Expliquer. #include <stdio.h> #include <stdlib.h> int main ( int argc, char *argv[]) { char c1,c2; printf("saisie de 2 caracteres>"); scanf("%c%c",&c1,&c2); printf("%c%c\n",c1,c2); printf("saisie de 2 caracteres>"); scanf("%c%c",&c1,&c2); printf("%c%c\n",c1,c2); system("PAUSE"); return 0; }

Remarque : comme il a été vu dans le TD2, les fonctions scanf() ou getchar() sont bloquantes.: tant que l'utilisateur n'a pas tapé sur le retour chariot, le programme reste bloqué sur la fonction de lecture. Les caractères tapés sont placés par le système d'exploitation dans un buffer qui est lu aprés saisi du retour chariot. Dans ce buffer se trouvent les caractères entrés mais aussi le code ASCII du retour chariot. Ainsi si l'utilisateur entre '1' , '2' suivi de , se trouvent dans le buffer de saisi 3 caractères (et non pas 2 comme on pourrait le supposer). Donc si l'on veut lire 2 caractères il faudra en fait lire les 2 caractères + le retour chariot.

3) Donner une solution à ce problème).

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 30/56

4) Que fait le programme suivant si on rentre 12 puis 23 ? Expliquer. #include <stdio.h> #include <stdlib.h> int main ( int argc, char *argv[]) { char c1,c2; printf("saisie de 2 caracteres>"); c1=getchar(); c2=getchar(); printf("%c%c\n",c1,c2); printf("saisie de 2 caracteres>"); c1=getchar(); c2=getchar(); printf("%c%c\n",c1,c2); system("PAUSE"); return 0; }

5) Donner une solution à ce problème en utilisant getchar().

6) Ecrire un programme qui demande à l'utilisateur d'entrer 2 caractères. Si le premier caractère est un 'a' et le deuxième est un 'z' alors sortir du programme et afficher le nombre de mauvaise réponse sinon redemander à l'utilisateur d'entrer 2 caractères (ne pas utiliser la fonction strcmp pour ce problème Cf TP7).

Travail à faire

Nombre d'Armstrong On dénomme nombre de Armstrong un entier naturel qui est égal à la somme des cubes des chiffres qui le composent.

Exemple : 153 = 1 + 125 + 27, est un nombre de Armstrong. SOLUTION 1 :

� On sait qu'il n'existe que 4 nombres de Armstrong, et qu'ils ont tous 3 chiffres (ils sont compris entre 100 et 500).

� L'idée consiste donc à balayer tous les nombres de 100 à 500 (1 boucle ) et pour chaque nombre de tester si celui-ci est un nombre d'Armstrong (somme des centaine, dizaine, unité)

� Pour décomposer un nombre en centaine, dizaine, unité, il suffit de se rappeler que 153/100 =1 et que 153 %100=53. 53/10=5 et 53%10=3. Donc grace à des divisions entières et à des restes de divisions (modulo) il est possible de trouver les 3 chiffres (centaine, dizaine et unité) constituant le nombre. Il ne reste plus qu'à calculer la somme des cubes de ces 3 chiffres et de tester le résultat au nombre.

SOLUTION 2 Sachant qu'un nombre est écrit ijk (i chiffre des centaines, j chiffres des dizaines et k chiffres des unités), il suffit simplement d'envisager tous les nombres possibles en faisant varier les chiffres entre 0 et 9 et de tester si le nombre est de Armstrong. (3 boucles for imbriqués). Nombres de Armstrong:

Page 16: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 31/56

153 370 371 407

7) Ecrire le programme qui affiche les nombres d'Armstrong selon la méthode de la solution 1.

8) Ecrire le programme qui affiche les nombres d'Armstrong selon la méthode de la solution 2.

Génération de nombres aléatoires La bibliothèque standard comprend un générateur de nombres pseudo-aléatoire et une fonction qui initialise l'amorce de cette série de nombres:

- int rand(void) : retourne un nombre entier pseudo-aléatoire compris entre 0 et 32767 - void srand(unsigned int amorce) : donne une valeur initiale à rand().

exemple d'une fonction qui remplit aléatoirement un tableau de 10 entiers compris entre MIN et MAX #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #define MAX 10 #define MIN 1 int main( void ) { int i; int nVal; srand(time(0)); /* utilisation de l'horloge pour initialiser la sui te */ for (i=0;i<10;i++) { nVal=rand()%MAX +MIN; // nVal compris entre 1 et N printf( "%d " , nVal); } puts( "" ); system( "PAUSE"); return 0; }

9) Faire 20 tirages aléatoires de nombres compris entre 0 et 3 et compter le nombre d'occurrence de chaque chiffre. Puis afficher sous forme d'histogramme, afficher le max et le min et la moyenne de la séquence.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 32/56

10) Ecrire un programme permettant de savoir si un nombre est premier (un nombre est premier s'il n'est divisible que par 1 et par lui-même).

Le principe est une boucle for, dans laquelle on calcule n%i avec i variant de 2 à n-1. Dés que ce modulo est égal à 0, le nombre n'est pas premier( il est au moins divisible par i). Il faut alors sortir de la boucle (break;). Si en sorti de la boucle for, i est égal à n cela veut dire que n n'est pas divisible et donc est un nombre premier.

11) Ecrire un programme qui saisit un nombre et affiche tous les nombres premiers inférieurs ou égaux à ce nombre.

Remarque :Un nombre pair ne peut pas être premier. On pourra utiliser ce principe pour réduire les tests de nombre premier.

Page 17: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 33/56

TP5 Tableaux et chaînes de caractères

Thème

� Programmation avec toutes les structures de contrôles. � Utilisation des tableaux et chaînes de caractères. � Méthodes de tri de tableau (tri par sélection et tri à bulle)

Préparation

1) Ecrire un programme qui initialise un tableau d'entier avec les valeurs 2,4,5,6,8,10 au moment de la déclaration du tableau et qui calcule la somme de ce tableau.

2) Ecrire un programme qui initialise une chaîne de caractère avec la valeur "bBoOnN23" au moment de la déclaration et qui n'affiche avec la fonction putchar que les caractères en minuscule (donc le programme affiche BON);

3) Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau ainsi qu'un entier V. Le programme doit rechercher si V se trouve dans le tableau et afficher "V se trouve dans le tableau" ou "V ne se trouve pas dans le tableau".

Travail à faire

Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées. Demander à l'enseignant quelle question vous devez traiter.

4) Ecrire un programme qui demande à l'utilisateur de saisir un entier N et qui affiche un triangle inversé de N lignes. Ce programme recommence une nouvelle saisie d'un entier N et affiche le triangle associé jusqu'à ce que l'utilisateur entre une valeur nulle ou inférieure à 0. Ci-dessous est affiché une copie d'écran du programme avec en GRAS la saisie de l'utilisateur.

N=>1 * N=>2 ** * N=>3 *** ** * N=>0 FIN DU PROGRAMME

5) Ecrire un programme qui demande à l'utilisateur de saisir un entier N et qui affiche tous les triangles inversés de 1 ligne jusqu'à N lignes, chaque triangle étant séparé par une ligne de N caractères '-'. Ci-dessous est affiché une copie d'écran du programme avec en GRAS la saisie de l'utilisateur.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 34/56

N=>3 --- * --- ** * --- *** ** * FIN DU PROGRAMME

6) Ecrire un programme qui demande à l'utilisateur de saisir un entier N . Si le nombre est pair et compris entre 1 et 10 le programme affiche un carré de N’*', si le nombre est impair et compris entre 1 et 10 le programme affiche un carré de N’#' . Le programme s'arrête si l'utilisateur entre une valeur inférieure à 1 ou supérieure à 10. Ci-dessous est affiché une copie d'écran du programme avec en GRAS la saisie de l'utilisateur.

N=>3 ### ### ### N=>2 ** ** N=>0 FIN DU PROGRAMME

Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées. Demander à l'enseignant quelle question vous devez traiter.

7) Ecrire un programme qui demande à l'utilisateur de saisir 10 notes comprises entre 0 et 20 qui seront stockés dans un tableau. Le programme doit alors traiter le tableau et compter et afficher le nombre de notes comprises entre 0 et 5,.comprises entre 6 et 10, entre 11 et 15 et entre 16 et 20.

8) Ecrire un programme qui demande à l'utilisateur de saisir 10 nombres réels qui seront stockés dans un tableau. Le programme doit alors traiter le tableau et afficher la somme de ces nombres, la moyenne et le nombre minimum de ce tableau.

9) Ecrire un programme qui demande à l'utilisateur de saisir 10 caractères qui seront stockés dans un tableau. Le programme doit alors traiter le tableau et compter le nombre de voyelles, de consonnes et de chiffres entrées.

Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées. Demander à l'enseignant quelle question vous devez traiter.

Page 18: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 35/56

10) Ecrire un programme qui demande à l'utilisateur d'entrer un phrase (utiliser gets) . Le programme donne la première lettre et la dernière lettre de la phrase.

11) Ecrire un programme qui demande à l'utilisateur d'entrer une phrase et qui compte le nombre d'espace dans la phrase.

12) Ecrire un programme qui demande à l'utilisateur de taper une lettre et qui affiche le nombre de fois ou la lettre est dans le mot caché.

Méthodes de tri de tableaux : Ne traiter qu'un problème sur 2. Demander à l'enseignant lequel vous devez traiter.

13) Ecrire un programme qui demande à l’utilisateur de taper 4 entiers qui seront stockés dans un tableau. Le programme doit trier le tableau par ordre croissant et doit afficher le tableau. Algorithme suggéré : Tri par sélection : On cherche l'indice du plus petit élément parmi les indices de 0 à 4 et on échange cet élément avec t[0]. On cherche l'indice du plus petit élément parmi les indices de 1 à 4 et on échange cet élément avec t[1]. On cherche l'indice du plus petit élément parmi les indices de 2 à 4 et on échange cet élément avec t[2]. On cherche l'indice du plus petit élément parmi les indices de 3 à 4 et on échange cet élément avec t[3].

Exemple de traitement : 24 5 100 9 recherche min de 0 à n-1 (ici la valeur 5, case 1), permutation de la case 1 et 0 5 24 100 9 recherche min de 1 à n-1,(ici la valeur 9, case 3) permutation de la case 3 et 1 5 9 100 24 recherche min de 2 à n-1, (ici la valeur 24, case 3) permutation de la case 3 et 2 5 9 24 100 fin du programme : indice courant = n-1

14) Ecrire un programme qui demande à l’utilisateur de taper 10 entiers qui seront stockés dans un tableau. Le programme doit trier le tableau par ordre croissant et doit afficher le tableau.

Algorithme suggéré: (tri bulle) On parcourt le tableau en comparant t[0] et t[1] et en échangeant ces éléments s'ils ne sont pas dans le bon ordre. on recommence le processus en comparant t[1] et t[2],... et ainsi de suite jusqu'à t[3] et t[4]. On compte lors de ce parcours le nombre d'échanges effectués. On fait autant de parcours que nécessaire jusqu'à ce que le nombre d'échanges soit nul : le tableau sera alors trié.

Exemple de traitement : 24 5 100 9 teste case 0 et 1 : 24>5 : permutation 5 24 100 9 teste case 1 et 2 : 24<100 :pas de permutation

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 36/56

5 24 100 9 teste case 2 et 3 : 100 > 9 : permutation On recommence 5 24 9 100 teste case 0 et 1 : pas de permutation 5 24 9 100 teste case 1 et 2 : permutation 5 9 24 100 teste case 2 et 3 :pas de permutation On recommence 5 9 24 100 teste case 0 et 1: pas de permutation 5 9 24 100 teste case 1 et 2: pas de permutation 5 9 24 100 teste case 2 et 3: pas de permutation Il n'a pas eu de permutation donc le tableau est trié.

Page 19: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 37/56

TP6 Les fonctions

Thèmes

� Les fonctions. � Variables locales et variables globales. � Les chaînes de caractères

Préparation

1) Compléter le programme ci-dessous. Pour cela écrire le code main permettant d'afficher le min, le max et la moyenne de 2 nombres saisis. On utilisera les 3 fonctions dont le code est donné ci-dessous :

#include <stdio.h> // code des fonctions int mini( int ia, int ib) { if (ia>ib) return ib; else return ia; } int maxi( int ia, int ib) { if (ib>ia) return ib; else return ia; } double moyenne( int ia, int ib) { // a compléter } // fonction principale int main( void ) { int ia,ib; //a compléter }

2) Étudier le programme suivant :

#include <stdio.h> int main( void ) { char com; int iMemoire,n; iMemoire=0; do {

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 38/56

printf( "\n>" ); scanf( " %c" ,&com); switch (com) { case '-' : scanf( "%d" ,&n); iMemoire=iMemoire-n; break ; case '+' : scanf( "%d" ,&n); iMemoire=iMemoire+n; break ; case '=' : printf( "%d" ,iMemoire); break ; case 'z' : iMemoire=0; break ; case 'q' : break ; default : printf( "?\n" ); } } while ( com != 'q' ) ; }

Dire ce qu'il se passe lorsque l'utilisateur entre ceci : -2 +3 = z = +3 +3 = q

3) Ajouter les fonctionnalités multiplication et division à ce programme.

4) Que se passe-t-il si on remplace l'instruction scanf(" %c",&com); par l'instruction com=getchar() ? Expliquer.

Page 20: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 39/56

On désire découper le programme précédent en fonctions. Pour cela 2 solutions :

� Utilisation d'une variable globale giMemoire. � Utilisation de variables locales seulement.

5) Compléter le programme ci-dessous qui utilise une variable globale giMem : #include <stdio.h> // variables globales int giMem; // déclaration des fonctions void addition( int n); void soustraction( int n); void raz( void ); void affiche( void ); // fonction principale int main( void ) { char com; int n; do { printf( "\n>" ); scanf( " %c" ,&com); switch (com) { case '-' : scanf( "%d" ,&n); soustraction(n); break ; case '+' : scanf( "%d" ,&n); addition(n); break ; case '=' : affiche(); break ; case 'z' : raz(); break ; case 'q' : break ; default : printf( "?\n" ); } } while ( com != 'q' ) ; } // code des fonctions void addition( int n) { // A compléter } void soustraction( int n) { // A compléter } void raz( void ) { giMemoire=0; } void affiche( void ) { // A compléter }

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 40/56

6) Compléter le programme ci-dessous qui n'utilise pas de variables globales #include <stdio.h> // déclaration des fonctions // A compléter // fonction principale int main( void ) { char com; int n, int iMemoire; do { printf( "\n>" ); scanf( " %c" ,&com); switch (com) { case '-' : scanf( "%d" ,&n); iMemoire=soustraction(iMemoire,n); break ; case '+' : scanf( "%d" ,&n); iMemoire=addition(iMemoire,n); break ; case '=' : afficher(iMemoire); break ; case 'z' : iMemoire=0; break ; case 'q' : break ; default : printf( "?\n" ); } } while ( com != 'q' ) ; } // code des fonctions int addition( int iMem, int n) { // a compléter } int soustraction( int iMem, int n) { // a compléter } void afficher( int iMem) { // a compléter }

7) Comparer les 2 solutions et conclure .

Travail à faire

Nombre parfait:

� Objectif : On souhaite écrire un programme de test de nombres parfaits. Un nombre est dit parfait s’il est égal à la somme de ses diviseurs, 1 compris.

� Exemple : 6 = 1+2+3 , est un nombre parfait (1 , 2 et 3 sont des diviseurs de 6) 28=14+7+4+2+1 est un nombre parfait (14, 7 , 4 , 2 et 1 sont des diviseurs de 28) 496 est un nombre parfait 8128 est un nombre parfait

Page 21: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 41/56

Pour savoir si un nombre est parfait ou non, il suffit de prendre toutes les valeurs inférieures à ce nombre et incrémenter les valeurs qui sont des diviseurs de ce nombre.

� Ecrire un programme qui teste si un nombre est parfait . Ecrire le code de 2 façons :

8) solution 1 : code monolithique (sans utilisation de fonctions,) tout le traitement est fait dans la fonction main().

9) solution 2 : code avec fonction; écrire le code de la fonction int isParfait(int n) qui renvoie 1 (vrai) si n est un nombre parfait ou 0 (faux)dans le cas contraire. La fonction main utilise la fonction isParfait pour testerr si le nombre entré est parfait ou non .

10) Amélioration :Tant que l'utilisateur n'a pas entré un nombre parfait, recommencer. Ecrire ce nouveau programme.

Travail sur les chaines de caractères

� On désire écrire le programme suivant :

Ce programme utilise les fonctions mettre_en_majuscule(), longueurChaine( taille de la chaine),nbVoy(nombre de voyelles de la chaines) ,nbLettre (nombre de lettres) ,nbChar().

11) Ecrire le code de ces fonctions. int main(void) { char sz[40]; puts("entrer un mot"); gets(sz); mettre_en_majuscule(sz); puts(sz); printf("taille du mot %d\n", longueurChaine(sz) ); printf("le nombre de consonne %d\n", nbCons(sz) ); printf("le nombre de voyelle %d\n", nbVoy(sz) ); printf("le nombre de lettre %d\n", nbLettre(sz) ); printf("le nombre de caractere e %d\n", nbChar(sz,'E') ); while (1); }

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 42/56

Test palindrome Une phrase est dite palindrome si en éliminant les blancs entre les mots elle représente la même lecture dans les deux sens : Exemple : "elu par cette crapule" → compresser : "eluparcettecrapule" → inverser : "eluparcettecrapule" il y a égalité entre les 2 chaines de caractères donc la phrase est un palindrome !

12) Exemple de la fonction inverser : Ecrire les 3 fonctions de compression, inversion et de test d'égalité de2 chaînes de caractères, puis appeler ces fonctions dans la fonction main pour obtenir le résultat suivant. La chaine de test sera initialisé à la déclaration ( prendre "elu par cette crapule"). Utiliser la fonction strcpy pour copier cette chaine (après compression) dans la chaine à inverser. tester ensuite les 2 chaines (une compressé et l'autre compressé + inversé) et écrire palindrome en cas d'égalité ou pas un palindrome dans le cas contraire.

Résultat

Page 22: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 43/56

TP7 Chaîne de compilation, fonctions et pointeurs

Thèmes

� Les fonctions. � Passages de paramètres par pointeurs. � Role du préprocesseur, introduction aux macros. � Introduction au langage assembleur. � Chaîne de compilation. � Compilation de plusieurs fichiers, notion de projet.

Préparation

1) Ecrire une fonction f ayant en paramètres un tableau iT de taille quelconque et un entier iElem indiquant la taille du tableau. f doit renvoyer par un return le nombre de valeurs comprises entre 0 et 10 dans les iElem premières cases du tableau iTt. Tester cette fonction.

2) Reprendre l'exercice 6 du TP6 sur la machine à calculer et modifier l'appel des fonctions soustraction et addition dans la fonction main. Ces fonctions ne renvoient rien et mettent à jour la valeur pointée par piMem.

// code des fonctions void addition( int *piMem, int n) { // a compléter } void soustraction( int *piMem, int n) { // a compléter }

Travail à faire

3) Ecrire le programme utilisant la fonction strcmp définie dans <string.h> permettant de tester 2 chaînes de caractères, celle entrée par l'utilisateur et "az". Tant que l'utilisateur n'a pas entré les caractères az celui-ci recommence. Dés que la séquence a été trouvée, le programme donne le nombre d'essais infructueux.

� Exemple : la fonction strcmp renvoie 0 si sz1 est égal à sz2 ou une valeur différente de 0 dans le cas contraire. Dans l'exemple ci-dessous, le programme affiche "different".

char sz1[20]="za",sz2[20]="az"; if (strcmp(sz2,sz1)==0) puts("identique"); else puts("different");

� Chercher dans l'aide(F1) pour plus de détail.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 44/56

� Algorithme suggéré : compteur =0 Faire lire chaîne de caractères si la chaîne de caractère lue est différente à " az" incrémenter compteur TantQue (chaîne de caractère lue est différente à " az") Afficher "gagne en <compteur> coup"

Rappels sur la chaîne de compilation : le préprocesseur

Role du préprocesseur : La compilation d'un programme se fait en 2 passes : La première passe appelée préprocesseur a pour but dans le cas des #include de copier le contenu du fichier de déclaration spécifié à la place de la directive #include et dans le cas des #define de remplacer les noms (définis par la directive #define) par leur valeur. Il est possible aussi de définir par le biais de la directive #define des macros qui sont des bouts de codes qui seront placer par le préprocesseur dans le programme à la place de la macro. Prenons un exemple : dans le fichier ci-dessous 2 constantes N1 et N2 et 2 macros MAX et MIN sont définies. Nous avons aussi placé 2 fonctions max et min pour une comparaison avec les macros. Une nouvelle instruction a aussi été rajoutée qui est une spécificité du language C . (test) ?valeur1:valeur2;

Dans le cas ou le test est vrai alors c'est la valeur1 qui est renvoyée sinon c'est la valeur2. Cette instruction permet de remplacer une instruction if et n'existe que dans le langage C ( et donc C++) et a été créé pour permettre d'avoir un code compact comme c'est le cas pour les opérations unaires += -= etc… Prenons un exemple : Le bout de code ci-dessous affiche 2 fois "ia=2". int i=9,ia; ia=(i<0)?0:2; // si i<0 ia prend la valeur 0 sinon 2 printf( "ia=%d\n" ,ia); if (i<0) // si i<0 ia prend la valeur 0 sinon 2 ia=0; else ia=2; printf( "ia=%d\n" ,ia);

Programme de test permettant de montrer le role du préprocesseur. #include <stdio.h> // mes définitions de constantes #define N1 3 #define N2 5 // mes macros #define MAX(x,y) (((x)>(y))?(x):(y)) #define MIN(x,y) (((x)>(y))?(y):(x)) // mes fonctions int max( int ia, int ib) { return ((ia>ib)?ia:ib); }

Page 23: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 45/56

int min( int ia, int ib) { if (ia>ib) return ib; else return ia; } // prog principal : test des fonctions min max et m acros MIN et MAX int main( void ) { printf( "MAX:%d\n" ,MAX(N1,N2)); printf( "MIN:%d\n" ,MIN(N1,N2)); printf( "max:%d\n" ,max(N1,N2)); printf( "min:%d\n" ,min(N1,N2)); system( "PAUSE"); return 0; }

4) Lancer le programme ci-dessus (tp7_exo4.c) et copier le résultat obtenu dans le compte-rendu.

Dans VC++ comme pour tous les compilateurs (gcc, borland C++,..) il est possible de visualiser le fichier créé par le préprocesseur. Sous VC++, ce fichier prend l'extension ".i". Pour visualiser ce fichier nous devons modifier une option du projet.

� Afficher les propriétés du projet

� Choisir la génération du fichier après passage du préprocesseur

� Puis taper sur F7 (Générer la solution ) pour lancer le préprocesseur. Visualiser le fichier. Ce fichier possède un grand nombre de lignes inutiles qui seront traitées par le compilateur. Allez en fin de fichier afin de visualiser le code main et le traitement fait par le préprocesseur.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 46/56

Programme après passage du préprocesseur : extrait du fichier tp7_exo4.i // déclaration de printf __declspec(dllimport) int __cdecl printf( c onst char * _Format, ...); int max(int ia,int ib) { return ((ia>ib)?ia:ib); } int min(int ia,int ib) { if(ia>ib) return ib; else return ia; } int main(void) { printf("MAX:%d\n",(((3)>(5))?(3):(5))); printf("MIN:%d\n",(((3)>(5))?(5):(3))); printf("max:%d\n",max(3,5)); printf("min:%d\n",min(3,5)); system("PAUSE"); return 0; }

On peut voir dans le programme ci-dessus que toutes les parties de code qui étaient en #... ont été enlevées.

5) Donner les différences entre les 2 fichiers tp7_exo4.c et tp7-exo4.i .

6) Ecrire le code de la fonction main utilisant les 3 directives préprocesseur ci-dessous et permettant de

� saisir un angle en radian puis l'afficher en degre (utilisation de RADTODEG).

� saisir un angle en degre et l'afficher en radian (utilisation de PI).

� saisir une valeur et donner sa valeur absolue (utilisation de ABS). En déduire ensuite le code généré après le passage du préprocesseur. #define RADTODEG(x) ((x) * 57.29578) #define ABS(x) ((x>0)?x:-x) #define PI 3.14159

Rappels sur la chaîne de compilation : le compilateur

VC++ comme tous les compilateurs permet de visualiser un certain nombre de fichiers intermédiaires générés par le compilateur. Nous allons visualiser le fichier assembleur (extension .asm) généré par le compilateur. Le but de cette manipulation est de comprendre la chaîne de compilation et le rôle de chaque outil.

Page 24: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 47/56

7) Créer un nouveau programme tp7_exo7.c et l'ajouter au projet tp7 (n'oubliez pas d'enlever l'ancien programme).Le code qui se veut très simple va permettre de comprendre le travail effectué par le compilateur.

tp7_exo7.c #include <stdio.h> #define N1 3 #define N2 5 int main( void ) { int ia,ib=N1,ic=N2; ia=ib+ic; ia=ib-ic; ia=ia<<1; if (ia==1) ib=5; else ib=8; while (1); return 0; }

Pour visualiser le fichier assembleur tp7_exo7.asm il suffit dans le menu Projet, Propriété (Alt + F7) de désactiver l'optimisation du compilateur (en effet l'optimisation peut amener à ne générer aucun code assembleur) puis dans fichier de sortie , sélectionner "Assembly avec code source" qui permet de générer un fichier ayant le code C en commentaire et le code assembleur associé. Le code assembleur généré est le langage compréhensible par le processeur PENTIUM. Avant l'apparition des langages évolués, les programmeurs écrivaient leurs programmes en assembleur. Certaines routines du BIOS et certains drivers sont toujours écrits en assembleur.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 48/56

extrait du fichier test.asm généré dans le répertoire RELEASE sous le répertoire du projet tp7. ; 7 : int ia,ib,ic; ; 8 : ia=ib+ic; mov eax, DWORD PTR _ib$[ebp] add eax, DWORD PTR _ic$[ebp] mov DWORD PTR _ia$[ebp], eax

Ces instructions assembleurs ont un code machine qui est en mémoire RAM. Pour visualiser le code machine , il suffit de regénérer la solution mais cette fois-ci avec l'option Assembly et code machine.

8) Recopier le code assembleur associé à la soustraction et au décalage à gauche. En déduire l'instruction assembleur associée à la soustraction et au décalage à gauche. Quelle est l'instruction assembleur permettant de faire un test (if) ?

Le code ci-dessous a été généré avec l'option Assembly, code machine et source (/FAcs) dans Fichiers de sortie (compilateur C/C++) dans la fenêtre propritété du projet. Après génération du projet (F7) le fichier tp7_exo7.cod est généré dans le répertoire RELEASE . 0002c 8b 45 ec mov eax, DWORD PTR _ib$[ebp] 0002f 03 45 e0 add eax, DWORD PTR _ic$[ebp] 00032 89 45 f8 mov DWORD PTR _ia$[ebp], eax Une autre solution pour voir le code assembleur est d'utiliser le débogueur.

� Pour cela, mettre un point d'arrêt (clic à gauche du code à stopper).

� Puis lancer le programme qui s'arrête sur le point d'arrêt.

� Ensuite, il suffit dans le menu Debug, Fenêtre, afficher le code machine.

adresse en RAM du programme

code machine en RAM

code assembleur associé au code machine (plus lisible)

Page 25: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 49/56

Le code assembleur associé à chaque instruction en C apparaît.

Schéma simplifié de la structure PENTIUM + RAM

ALU

eax

ia

ib

ic

32

bits

RAM

Zone de

données

0x0000

eip

0x002C

Début du prog

8b 45 ec

03 45 e0

89 45 f8

RAM

Zone de

programme0x002F

0x0032

32

bits

32

bits

32

bits

Registre

d’instruction

32

bits

Bus

d’adresse

Compteur

d’instructions

Unité

arithmétique et

logique

ebp

+

Bus

d’adresseBus

De données

Bus

De données

Extrait du

schéma

fonctionnel

du CPU

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 50/56

9) Expliquer pour chacune des 3 instructions assembleurs générées à partir de l'instruction ia=ib+ic; le role du registre d'instruction, de l'ALU, du compteur eip, du registre eax et du registre ebp.

10) Chaque instruction possède un code machine. Donner le code machine de add et sub. Le code machine de ces instructions est sur 16 bits. Or le code machine de ces instructions est sur 24 bits. Le dernier octet donne l'adresse des variables ia, ib et ic qu'il faut rajouter au registre ebp. Il est possible de visualiser la zone mémoire ou se trouve ia, ib et ic.

Le compilateur n'est pas le dernier élément permettant de générer un exécutable. Le Linker qui est appelé à la suite du compilateur permet de regrouper le code issu de la compilation du ou des fichiers du projet et aussi le code de fonctions utilisées et issues de librairies (par exemple printf ou scanf) déjà compilées. Afin de montrer le rôle du linker , faire l'exercice ci-dessous :

Découpe des blocs de fonctions en fichiers

11) Ecrire le code des fonctions marquées A COMPLETER. #include <stdio.h> #include <time.h> // remplir un tab de nEle avec la valeur n. void remplir_tab( int nTab[], int nElem, int n); // saisie du tab par l'utilisateur void saisir_tab( int nTab[], int nElem); // recherche du min du tab de nElem int min_tab( int nTab[], int nElem); // recherche du max du tab de nElem int max_tab( int nTab[], int nElem); // calcul de la moyenne du tab de nElem double moyenne_tab( int nTab[], int nElem); // créer un tab de nEle commençant à nMin et finis sant à nMax void creer_tab_aleatoire( int nTab[], int nEle, int nMin, int nMax); #define N 5 int main( void ) { int it1[N]; int it2[N]; int it3[N]; saisir_tab(it3,N); puts( "t3" ); affiche_tab(it3,N); remplir_tab(it2,N,2); puts( "t2" ); affiche_tab(it2,N); creer_tab_aleatoire(it1,N,1,19); puts( "t1" ); affiche_tab(it1,N); printf( "min=%d\n" ,min_tab(it1,N)); printf( "max=%d\n" ,max_tab(it1,N)); printf( "moy=%g\n" ,moyenne_tab(it1,N)); system("PAUSE"); } // code des fonctions void remplir_tab( int nTab[], int nElem, int n) { for (i=0;i<nElem;i++) {

Page 26: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 51/56

nTab[i]=n; } } void saisir_tab( int nTab[], int nElem) { int i; for (i=0;i<nElem;i++) { printf( "t[%d]=" ,i); scanf( "%d" ,nTab[i]); } } int min_tab( int nTab[], int nElem) { // a compléter } int max_tab( int nTab[], int nElem) { // a compléter } double moyenne_tab( int nTab[], int nElem) { // a compléter } // créer un tableau de nEle éléments commençant à n Min et finissant à nMax void creer_tab_aleatoire( int nTab[], int nEle, int nMin, int nMax) { int i; srand(time(0)); for (i=0;i<nEle; i++) { nTab[i]= nMin+ ( int ) rand()%(nMax-nMin+1) ; } } void affiche_tab( int nTab[], int nEle) { // a compléter }

Découpe en fichiers : exemple

� Toutes les déclarations de fonctions doivent être mises dans un fichier xxx.h � Le code des fonctions est placé dans le fichier xxx.c � Le compilateur doit compiler le fichier main.c et le fichier de bibliothèque xxx.c. Les 2 fichiers compilés se

nomment main.obj et xxx.obj. � L'éditeur de lien va générer le fichier exécutable en assemblant le code des fichiers objets xxx.obj et

main.obj générés par le compilateur.

� Dans le projet courant créer le fichier tableau.h ou se trouve toutes les déclarations (ou prototypes) des fonctions.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 52/56

tableau.h // remplir un tab de nEle avec la valeur n. void remplir_tab( int nTab[], int nElem, int n); // saisie du tab par l'utilisateur void saisir_tab( int nTab[], int nElem); // recherche du min du tab de nElem int min_tab( int nTab[], int nElem);

Page 27: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 53/56

// recherche du max du tab de nElem int max_tab( int nTab[], int nElem); // calcul de la moyenne du tab de nElem double moyenne_tab( int nTab[], int nElem); // créer un tab de nEle commençant à nMin et finis sant à nMax void creer_tab_aleatoire( int nTab[], int nEle, int nMin, int nMax); // afficher le tab de nEle void affiche_tab( int nTab[], int nEle);

� Ensuite créer un nouveau fichier tableau.c ; ce fichier va accueillir le code des fonctions sur les tableaux.

� Puis ajouter tableau.c dans le projet existant.

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 54/56

Vous devriez avoir dans l'explorateur de projet , Fichiers sources , les 2 fichiers tableau.c et test.c. Ces 2 fichiers vont être compilés .

Fichier test.c #include <stdlib.h> #include "tableau.h" #define N 5 int main( void ) { int it1[N]; int it2[N]; int it3[N]; saisir_tab(it3,N); puts( "t3" ); affiche_tab(it3,N); remplir_tab(it2,N,2); puts( "t2" ); affiche_tab(it2,N); creer_tab_aleatoire(it1,N,1,19); puts( "t1" ); affiche_tab(it1,N); printf( "min=%d\n" ,min_tab(it1,N));

Page 28: TP Informatique

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 55/56

printf( "max=%d\n" ,max_tab(it1,N)); printf( "moy=%g\n" ,moyenne_tab(it1,N)); system("PAUSE"); }

Fichier tableau.c // code des fonctions void remplir_tab( int nTab[], int nElem, int n) { for (i=0;i<nElem;i++) { nTab[i]=n; } } void saisir_tab( int nTab[], int nElem) { int i; for (i=0;i<nElem;i++) { printf( "t[%d]=" ,i); scanf( "%d" ,nTab[i]); } } int min_tab( int nTab[], int nElem) { // a compléter } int max_tab( int nTab[], int nElem) { // a compléter } double moyenne_tab( int nTab[], int nElem) { // a compléter } // créer un tableau de nEle éléments commençant à n Min et finissant à nMax void creer_tab_aleatoire( int nTab[], int nEle, int nMin, int nMax) { int i; srand(time(0)); for (i=0;i<nEle; i++) { nTab[i]= nMin+ ( int ) rand()%(nMax-nMin+1) ; } } void affiche_tab( int nTab[], int nEle) { // a compléter }

12) Compléter le code des fonctions de tableau.c et tester .

13) Créer un nouveau projet. Dans ce projet créer le fichier mes_fonctions.c dans lequel se trouve la fonction carre et cube qui prennent un entier en argument et renvoie le carré ou le cube de cet entier. Créer ensuite le fichier mes_fonctions.h ou se trouve les déclarations de ces 2

UNSA/IUT de Nice - département GEII I1 - TP 1ère Année

08/08/2007 JLS page 56/56

fonctions. Créer ensuite la fonction main.c dans laquelle sont appelées et testées les 2 fonctions.

14) Compléter le schéma ci-dessous :

15) Modifier le programme mes_fonctions.c et modifier le nom de la fonction carre en carre_bis. Générer la solution (F7) et vérifier que l'erreur vient du linker. Faire une faute dans la fonction carre_bis et vérifier que l'erreur est générée par le compilateur.

Et s'il reste du temps ?

16) Créer un fonction permettant à partir d'un tableau de nElem élément de renvoyer le min et l'indice du minimum. On suppose que le tableau ne possède pas de valeurs en double.

Cette fonction sera ajoutée au fichier tableau.c

mes_fonctions.c main.c

mes_fonctions.obj main.obj

tp7_exo9.exe

librairie (printf)

? ?

?