You are on page 1of 28

UNSA/IUT de Nice - département GEII

I1 - TP 1ère Année

UNSA/IUT de Nice - département GEII

I1 - TP 1ère Année

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 TP1 TP2 TP3 TP4 TP5 TP6 TP7 Premiers programmes Résolution d'équation du second degré Algorithmique 1 Algorithmique 2 Tableaux et chaînes de caractères Les fonctions Chaîne de compilation, fonctions et pointeurs 1 2 18 25 29 33 37 43

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. 08/08/2007 JLS page 1/56 08/08/2007 JLS page 2/56

UNSA/IUT de Nice - département GEII

I1 - TP 1ère Année

UNSA/IUT de Nice - département GEII

I1 - TP 1ère Année

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

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,

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

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

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.

On obtient alors un fichier vide. Recopier le fichier modèle vu précédemment et modifier l'en-tête.

08/08/2007

JLS

page 3/56

08/08/2007

JLS

page 4/56

nRes=n1-2..n1.. printf("%d^2=%d\n". tp1_exo1..nRes).. -----. puis clic sur oui.département GEII I1 . int nRes=6.nRes).n1.. printf("%d*2=%d\n".0 erreur(s). printf("%d%2=%d\n". nRes=n1&0x07. nRes=n1%2. puts ("fin du programme"). printf("%d&2=%d\n". Configuration : Release Win32 -----Compilation en cours. Génération de code en cours Fin de la génération du code Incorporation du manifeste en cours.n1. printf(" j'ai deux valeurs a afficher :%d et %d puts ("operations aritmetiques").TP 1ère Année UNSA/IUT de Nice . cocher la case "Ne plus afficher cette boite de dialogue". Clic sur la flèche verte Une fenêtre s'affiche .n1.nRes).nRes).c Édition des liens en cours.UNSA/IUT de Nice .Début de la génération : Projet : tp1.nRes).nRes).n1. puts ("operations logiques"). nRes=n1*3.n1. \n".nRes). programme à placer Lancer le programme. OPERATION 08/08/2007 JLS page 5/56 08/08/2007 JLS RESULTAT page 6/56 ..département GEII I1 .htm" tp1 .nRes).n1.n1). printf("%d|2=%d\n". printf("%d-2=%d\n". nRes=n1/2. nRes=n1^0x07. Le journal de génération a été enregistré à l'emplacement "file://g:\iut_courant\i1\programmes_2007_2008\tp1\Release\BuildLog. printf(" j'ai une valeur a afficher :%d\n". 0 a échoué. 0 mis à jour. printf("%d/2=%d\n".TP 1ère Année Placer à la place du commentaire les lignes suivantes : int n1=5. 0 a été ignoré ========== 1) Analyser chaque ligne affichée et expliquer le résultat obtenu (Compléter le tableau ci-dessous). 0 avertissement(s) ========== Génération : 1 a réussi. nRes=n1|0x07..n1.

puis lancement de l'exécutable (avec le chargement des dll permettant l'exécution du programme). Cinquième erreur : oubli de la fonction "system".n1.département GEII I1 . 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. VC++ fait 2 opérations : appel au compilateur qui génère le fichier exécutable. Conclure sur l'importance des Warnings. 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. Vous obtenez la ligne suivante : .' avant l'identificateur 'printf' Ainsi qu'un marqueur vert sur la ligne ayant un problème : 08/08/2007 JLS page 7/56 08/08/2007 JLS page 8/56 .n1".c(31) : warning C4313: 'printf' : conflit 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. l'erreur se situe ici ! Deuxième erreur : non déclaration d'une variable.\tp1_exo1. 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. Quel message donne le compilateur fasse à ce type d'erreur ? Remplacer la ligne int n1=5.c. Pour cela nous allons faire un certain nombre d'erreurs classiques : Première erreur : oubli du point virgule. il est incapable de générer le fichier exécutable et c'est l'ancien exécutable qui est lancé. Ce message n'est pas un message d'erreur mais un Warning (avertissement).c(25) : error C2146: erreur de syntaxe : absence de '. nRes=n1%2. Quatrième erreur : appel à une fonction inconnue . par systeme("PAUSE").nRes).département GEII I1 . Le compilateur génère l'exécutable. nRes=n1|0x07.UNSA/IUT de Nice .Affichage. Générer la solution Vous obtenez la ligne suivante : . Générer la solution (F7) : Vous obtenez la ligne suivante : . D'autres erreurs à la suite de cette erreur sont vues par le compilateur.\tp1_exo1. nRes=n1^0x07. Il est possible qu'un certain nombre d'erreurs disparaissent alors !!! Dans les 2 cas . Ces erreurs sont dues à la première erreur et ne doivent donc pas être corrigées. Si le compilateur rencontre une erreur dans le fichier tp1_exo1. Un avertissement permet de donner une information au programmeur mais sans bloquer la génération du code. Deuxième erreur : non déclaration d'une variable. 2) Lancer le programme et donner le résultat affiché par cette ligne de code.\tp1_exo1.nRes). 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.c(18) : error C2065: 'n1' : identificateur non déclaré Première erreur : l'oubli du point virgule. Remplacer system("PAUSE"). par n1=5. 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. Troisième erreur : problème de l'apostrophe dans le "printf". nRes=n1&0x07. Toutes les variables doivent être déclarées avant d'être utilisées. Par contre l'affichage du résultat est incohérent. les informations issues du compilateur sont masquées. Sortie). nRes=n1-2. Vous ne voyez donc que les informations issues du lancement de l'exécutable . l'affichage des informations issues de ces 2 étapes se fait dans la fenêtre "sortie" ( ALT+2 ou dans le menu .TP 1ère Année nRes=n1*3 nRes=n1/2. 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. Quatrième erreur : appel à une fonction inconnue.TP 1ère Année UNSA/IUT de Nice . troisième erreur : problème de l'apostrophe dans le printf Remplacer printf("%d-2=%d\n". par printf("%d-2=%d\n. Trouver les erreurs de compilation Nous allons ici voir comment le compilateur peut aider à trouver les erreurs faites lors de la saisie du code.

Optimisation.c(42) : warning C4013: 'systeme' non défini(e) .Dans cet avertissement le compilateur informe que la fonction "systeme" n'est pas définie (dans les fichiers de déclaration #include""). Mettre un point d'arrêt (double-clic à gauche de la ligne ou l'on veut arrêter le code). extern retournant int pris par défaut Édition des liens en cours.obj : error LNK2001: symbole externe non résolu _systeme Le compilateur génère un warning à la ligne 42.TP 1ère Année Générer la solution : Vous obtenez les lignes suivantes : .TP 1ère Année UNSA/IUT de Nice . Et modifier dans C/C++ . tp1_exo1. Dans la zone Explorateur de solution. le niveau d'optimisation du code : Désactivé. 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.. Que se passe-t-il ? Expliquer et en déduire le rôle de la fonction system.c(42) : warning C4013: 'systeme' non défini(e) . tp1_exo1. il peut être intéressant de stopper le programme juste avant l'arrivée de l'erreur et de visualiser les variables..Un point rouge apparaît.c .département GEII I1 . C'est l'éditeur de lien qui stoppe la génération du code. Le bug ou bogue informatique est une erreur qui apparaît dans un programme.c avec le code des fonctions appelées (printf. 3) Générez la solution. C'est le débuggeur qui permet de faire cette opération. Oubli de la fonction system("PAUSE"). 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. il est important que le code ne soit pas optimisé. extern retournant int pris par défaut Compilation en cours.UNSA/IUT de Nice . mais les erreurs de conceptions ne peuvent être détectées que lors de l'exécution du programme. 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. Existe-t-il une erreur de compilation ? Lancer le programme. puisqu'il ne trouve pas dans la bibliothèque des fonctions disponibles le code de la fonction systeme. Pour visualiser le Débug en mode pas à pas comme nous voulons le faire. l'éditeur de lien vient assembler le code généré par tp1_exo1.. 08/08/2007 JLS page 9/56 08/08/2007 JLS page 10/56 . Après la compilation. Propriétés du Projet) 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. cliquer sur Propriétés (ou projet. systeme).\tp1_exo1.\tp1_exo1.département GEII I1 .. Au moment ou une erreur apparaît. On rappelle qu'une valeur précédée de 0x est en hexadécimal. puts. Les erreurs simples sont détectées par le compilateur.

Tous les fichiers que vous allez créé ne devront pas être effacés ! Puis clic droit sur fichier source. printf. En effet.département GEII I1 . 0 OU 1 et 0 OU EXC 1.TP 1ère Année UNSA/IUT de Nice .c 08/08/2007 JLS page 11/56 08/08/2007 JLS page 12/56 . choisir Enlever. A la question Supprimer ou Enlever.c écrit précédemment.TP 1ère Année Après 4 appuis sur la touche F10. nRes a été mise à jour (valeur en rouge) 4) En utilisant le débogueur donner le résultat des opérations 255 ET 0x80. Ne pas pas placer de fonction printf après chaque calcul.c Sous le même projet retirer le fichier tp1_exo1.c et ajouter ces opérations au début du programme (le résultat de l'opération est stocké dans nRes). il est important de garder le source tp1_exo1.Faire une copie d'écran dans le compte rendu.Pour cela modifier le programme tp1_exo1.UNSA/IUT de Nice . putchar : tp1_exo2. utilisation des fonction d'affichages puts. Faire une copie d'écran. 5) Sans utiliser le débogueur.département GEII I1 . Nouvel élément et dans Nom: tp1_exo2.c On peut voir que l'affichage suit bien l'exécution en mode pas à pas. afficher les résultats de ces opérations en ajoutant à la fin de chaque calcul l'affichage de la valeur nRes (printf). Ajouter.

puts("******************************************").département GEII I1 . //déclaration et initialisation entier double d=2. (" hello\n"). //commentaire à faire puts(" \ntest \\n "). d). int n = 32. d).TP 1ère Année Copier le modèle de la page 2 (Règles de programmation) et modifier l'en-tête.\n". 6) Faire la copie d'écran du résultat affiché dans le compte rendu. //commentaire à faire ("hello"). n). d). Rajouter les lignes suivantes dans le programme. //commentaire à faire puts("_________________________________________").UNSA/IUT de Nice .//commentaire à faire ("%s \n". puts(" test "). d). putchar".3f\n".TP 1ère Année UNSA/IUT de Nice . //commentaire à faire ("n vaut 0x%x. //commentaire à faire puts(" \ttest \\t "). puis tester.//commentaire à faire ("%12s \n". n). puts. Chaque nouveau programme devra avoir cet en-tête ! Modifier la description du programme de l'en-tête " tests des fonctions printf."Coucou"). //commentaire à faire 08/08/2007 JLS page 13/56 08/08/2007 JLS page 14/56 . //commentaire à faire ("d vaut %10.34. //commentaire à faire ("n vaut %10d. //commentaire à faire puts(" \" test \" ").\n".//commentaire à faire ("d vaut %f\n". Compléter les commentaires pour chaque ligne."Coucou"). //commentaire à faire ("d vaut %g\n". 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. n). //déclaration et initialisation réel printf printf printf printf printf printf printf printf printf printf printf ("n vaut %d. 7) Rajouter les lignes suivantes et écrire les commentaires à chaque ligne. //commentaire à faire ("d vaut %e\n".\n".département GEII I1 .

putchar(0x5F). On pourra tester avec l'instruction putchar(7).département GEII I1 .TP 1ère Année 8) Rajouter les lignes suivantes à la suite.écrire à la suite un programme qui affiche les lettres de l'alphabet : ABCDEFGHIJKLMNOPQRSTUVWXYZ Le caractère 7 de la table ASCII correspond au bip que vous entendez. i<10. int i. Donner le caractère ayant le code 0x5F et 0xB3..UNSA/IUT de Nice .i). 0x41 0x42 . puts(""). 11) Expliquer le résultat obtenu et compléter le tableau suivant. puts(""). 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. Dans le même projet. tester le code suivant dans le fichier tp1_exo4. 0x7A 12) Modifier le code de la fonction ASCII avec le code ci-dessous . putchar('\n')...i) ? Donner le résultat de la ligne suivante int n=48. Ce code a ensuite été utilisé pour coder les caractères dans les ordinateurs.i.i. 10) b AAA 234 43.i++){ printf("%d | 0x%X = %c\n". Donner le résultat affiché par chaque ligne.TP 1ère Année UNSA/IUT de Nice . 9) Mettre la copie d'écran du résultat obtenu sur le compte rendu.i++){ printf("%d | 0x%X =". putchar(0xB3).n..i).département GEII I1 .. i++) putchar('A').i<=127.// pour entendre bip.puts(""). Valeur en décimal Valeur en hexadécimal lettre affichée 0x30 0x31 . avec en-tête et fonction main. putchar('x'). 0x59 0x5A . putchar('|').5 bbbbbbbbbbbbbbb 2 ET 3 = 2 3 <<1 = 6 Ecrire un programme qui affiche : (utilisation de putchar avec affichage d'un variable caractère notée c) (utilisation de puts) (utilisation de printf avec affichage d'une variable de type int notée n) (utilisation de printf avec affichage d'une variable de type double notée d) (utilisation d'une boucle for. Conclure int i. Le but du programme que l'on va lancer est de visualiser cette table ASCII. putchar(i). afficher 15 b) (calcul + affichage du résultat du calcul. . Mon deuxième programme : tp1_exo5.. } Mon premier programme : tp1_exo3.i. printf("%c = %d". puts("").. for(i=0. 0x61 0x62 .).c et le remplacer par un nouveau fichier tp1_exo3.c . int i. 08/08/2007 JLS page 15/56 08/08/2007 JLS page 16/56 . 0x39 . variable entière nRes) 13) 14) Existe-t-il une différence entre putchar(i) et printf("%c".c En gardant les mêmes règles que précédemment : enlever le fichier tp1_exo2... putchar('-').écrire un programme qui affiche : Notion de table ASCII : tp1_exo4.i<=127.c 15) 123456789 En utilisant la boucle for .n).c. variable entière nRes) (calcul + affichage du résultat du calcul. for(i=0.. tabulation. for (i=0. } 16) En utilisant la boucle for .. // a metre en début de code putchar('_').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)..

pow et sqrt de la bibliothèque <math. double dCompte=123. else puts("pas un chiffre"). } 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 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. Utilisation des fonctions mathématiques sin.25 BASE HEXADECIMALES 0x64 0xFF 0xFFFFFFFF 0xFFFFFFFF 0x4249 0x0000 REPRESENTATIONS BINAIRES 0110 0100 1111 1111 8 fois 1111 8 fois 1111 TP2 Résolution d'équation du second degré Thèmes Utilisation des structures de contrôles if et for.UNSA/IUT de Nice .dCompte). int nAge=20. while(1). c=getchar(). 0100 0010 0100 1001 0000 0000 0000 0000 Préparation Pour un nombre réel : 2 types possibles float et double.département GEII I1 . c=getchar().sz. while(1). Utilisation de l'aide de VC++. 08/08/2007 JLS page 17/56 08/08/2007 JLS page 18/56 .TP 1ère Année Ressources :Codage des données TYPES char unsigned char int unsigned int float BASE DECIMALES 100 255 -1 2^32-1 50. return 0.2f|\n".département GEII I1 . else puts("pas un chiffre").nAge. } 2) Expliquer ce que fait le programme ci-dessous.. printf("\t|%10s|%5d|%10. printf("\t|----------|-----|----------|\n").h> int main (void) { char c. + m232-23 Exposant codé sur 8 bits (-127=00000000 et 128=11111111) Exposant = e727 + e626+ . if(c>='0' && c<='9') puts("un chiffre"). 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+ . + e020 -127 1) Expliquer ce que fait le programme ci-dessous et plus particulièrement l'utilisation faite de la fonction printf. if(c>='0' && c<='9') puts("un chiffre"). 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. char sz[]="toto".h>. printf("\t|%10s|%5s|%10s|\n".. #include <stdio."age". return 0. tan.89.TP 1ère Année UNSA/IUT de Nice ."nom"."valeur"). Différences entre les types float et double. Introduction aux pragmas. cos. printf("\t|----------|-----|----------|\n"). int main (void) { int i.

pow(2.h> <stdlib. puts("*********************************************************").pow(2. } int main(void) { puts("*********************************************************").sizeof(double). Comme tous les fichiers de déclarations de fonctions celui-ci est placé dans le répertoire par défaut des "include".SHRT_MAX).INT_MIN. printf("short \t|%10d|%15d|%15d|\n".fS). puts("___________________________________________________").LONG_MAX).pow(2. 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). puts("___________________________________________________"). #define M_PI 3. Puis rechercher math routines puis math constant.sizeof(long). paramètres de l'application: projet vide). INT_MIN.c).Donner les valeurs de CHAR_MIN. system("PAUSE"). i<100000. float et double."max").département GEII I1 .sizeof(char). Travail à faire Comme pour chaque nouveau TP.CHAR_MAX). valeur min et max pour chaque type "). Le fichier math.1023))."taille".TP 1ère Année UNSA/IUT de Nice . fS = 1000.h> #include <stdlib. for (i=0. float fS . printf("char \t|%10d|%15d|%15d|\n". Quelle est la valeur finale de fS ? #include <stdio. Pour chaque nouveau programme. Une autre source d'information pour le programmeur est évidemment l'utilisation de l'aide (touche F1). 08/08/2007 JLS page 19/56 08/08/2007 JLS page 20/56 . ajouter le fichier créé au projet (Fichier source. cosh. nom:tp2. Nous allons utiliser l'aide de VC++ express. Cette ligne signifie que la fonction sin prend en argument un "double" et renvoie un "double".LONG_MIN.CHAR_MIN.sizeof(int). printf("float \t|%10d|%15e|%15e|\n". Application Console Win32.sizeof(short). L'aide de VC++ est très bien documentée et doit être utilisée le plus possible. ajouter. i++) fS=fS+0.0 .1. printf("type \t|%10s|%15s|%15s|\n". 5) Ecrire un programme tp2_exo5. return 0. Taper F1 pour ouvrir la fenêtre d'aide.TP 1ère Année 4) Commenter chaque ligne du programme ci-dessous . puis fenêtre suivante .pow(2. } 7) Rajouter à la suite de la boucle for le même calcul mais cette fois-ci en utilisant la variable dS de type double.sizeof(float). Rechercher la fonction sin.h> <math.0.UNSA/IUT de Nice . printf("int \t|%10d|%15d|%15d|\n". return 0. CHAR_MAX. puts(""). clic droit. nouvel élément et enlever le programme précédent.h> Différences entre les types float et double 6) Ecrire le programme suivant (tp2_exo6. une valeur de fin et qui affiche toutes les valeurs comprises entre début et fin sauf celle égale à debut+2 _CRTIMP double __cdecl sin (double).h> <limits.tan. Projet.SHRT_MIN.11000.-1023). Nouveau. créer un projet TP2 (Fichier .h est un fichier de déclaration des fonctions mathématiques utilisables en C.département GEII I1 ."min".+128)).h dans le répertoire include. #include #include #include #include <stdio.INT_MAX). puts(" \ttaille en octet. 8) Les fonctions cos. printf("long \t|%10d|%15d|%15d|\n". system("PAUSE"). Expliquer ! Calculs trigonométriques Questions préliminaires : ouvrir math. printf( "valeur theorique %f et valeur apres calcul %f\n".c qui demande une valeur de début. printf("double \t|%10d|%15e|%15e|\n".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. INT_MAX ainsi que la taille d'un int.h> int main(void) { int i . log10. Tester.-126). exp.

Le compilateur C issu du GNU (Linux) gcc possède lui une bibliothèque mathématique math.département GEII I1 .h dans laquelle M_PI est défini.UNSA/IUT de Nice . Une autre solution consiste à utiliser les pragma ou directives.le sinus et la tangente de 45 °. Le code ci-dessous permet donc une compilation du programme avec VC++ ou bien avec gcc. #include <math. Ces pragma commencent par # . 10) Ecrire un programme qui affiche le cosinus. le programmeur doit taper les 2 lignes suivantes en début de programme : #define _USE_MATH_DEFINES #include <math. Pour pouvoir utiliser ces constantes. On pourra s'aider de l'exemple et le modifier.14159265358979323846 08/08/2007 JLS page 21/56 08/08/2007 JLS page 22/56 . Dans l'exemple ci-dessous après l'insertion de la bibliothèque math.TP 1ère Année UNSA/IUT de Nice .département GEII I1 .TP 1ère Année L'aide explique qu'il existe des constantes mathématiques utiles pour le programmeur.h> L'aide en plus des explications sur les fonctions mathématiques vous fournit un exemple (clic sur example).h> #ifndef M_PI #define M_PI #endif 3.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.

sin et tan.h> #include <stdio.cos(M_PI/180*10)). 13) Modifier le code pour que lorsqu'une valeur est supérieure à une constante MAX (par exemple 100000) le programme affiche INFINI. printf("exp(%g)=%g\n".log10(10)).département GEII I1 .c sont entrés au clavier. // résultat dy=2. b et c.0.département GEII I1 .TP 1ère Année UNSA/IUT de Nice .10.M_E). 15) Modifier le programme pour que celui-ci fonctionne sans aucune restriction sur a. Si le coefficient a est non nul. printf("M_E=%g\n". Faire l’organigramme de ce programme puis l'écrire et le tester. calculer les valeurs des sin. } Résolution d'équation du second degré On désire écrire un programme de résolution d'équation du second degré.h> int main() { double dy. printf("log10(%g)=%g\n".4ac NON OUI d<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.h> double dy= sqrt(4. le tout en degré.b.√d / 2a x2 = -b + √d / 2a une racine réelle x1 = -b / 2a deg = inf OUI deg<sup 14) Ecrire le programme dont le cahier des charges est donné ci-dessus . 08/08/2007 JLS page 23/56 08/08/2007 JLS page 24/56 . cos tg et les afficher . ainsi que le pas. on utilise la fonction sqrt() définie dans la bibliothèque <math..0. 12) Ecrire le programme dont le cahier des charges a été donné ci-dessus. return 0. sup.TP 1ère Année 11) Tester le programme ci-dessous : #define _USE_MATH_DEFINES #include <math. l’organigramme du programme est le suivant : d = b2 . step lire les valeurs de inf. deg = deg + step Résultat du programme : On prendra soin d'utiliser les types qui conviennent pour le calcul des cos.UNSA/IUT de Nice .dy). dy=exp(1). sup et step (en degré) Pour i=inf jusqu'à sup (par pas de step) k ← transformer i en radian calculer puis afficher sin(k). printf("cos(10)=%g\n".. Ce programme résout l’équation ax2+bx+c=0 où les coefficients a. system("PAUSE").cos(k) et tg(k) FinPour NON NON d==0 OUI pas de racines réelles deux racines réelles x1 = -b .0.0).1. L’organigramme du programme est le suivant: Algorithme entrée de inf. Le résultat est ensuite affiché. Pour le calcul de la racine carrée.

Expliquer chacun des résultats affichés à l'écran. system("PAUSE"). double y ).nB=6. expliquer les lignes suivantes tirées de l'aide : The pow function computes x raised to the power of y. résultat de l'aide : 2) Evaluer nRes pour n =2 et n=10. 08/08/2007 JLS page 25/56 08/08/2007 JLS page 26/56 . if((nA>0)&&(nA<6)) puts("7:nA compris entre 1 et 5"). return 0. int main() { int nA = 2.nRes). nRes=(nA == (nB+2)).UNSA/IUT de Nice . nRes=(5==5)&&(6==2).TP 1ère Année UNSA/IUT de Nice . 4) Ecrire un programme qui affiche tous les entiers de 8 jusqu’à 23 (bornes incluses) en utilisant une structure en for puis en while. if (n) puts("n"). 5) En utilisant l'aide de VC++ rechercher la fonction pow. printf("2:%d\n". } double pow( double x. nA=0. (n==1)||(n>=2)||(n<9).nRes). nA %= 2.nB). n=3. n=3. if (n<4) puts("n<4"). (n==0)||((n>=2)&&(n<9)). if (n=5) puts("n=5").nA). L'aide étant en anglais. printf("3:%d\n". printf("1:%d\n".nRes . (n=1)||((n>=2)&&(n<9)). nRes= nRes= nRes= nRes= (n==1)||(n>=2).département GEII I1 . Utilisation des fonctions ceil et floor et pow. nB= 0.nRes). on suppose que nRes et n sont des entiers. nRes=(5>1)||(6>8). if((nA>0)||(nA<6)) puts("8:nA compris entre 1 et 5"). 3) Donner le résultat affiché par l'extrait suivant (n est un entier) et expliquer. printf("4:%d\n". nA=5.département GEII I1 . printf("6:%d\n". nB += 4.TP 1ère Année Travail à faire : TP3 Algorithmique 1 Thèmes Algorithmique de base : utilisation de toutes les structures de contrôle. Préparation 1) Donner le résultat de l'extrait ci-dessous. if(nA != nB) puts("5:nA different de nB").

L'utilisateur devra saisir une lettre suivie du retour chariot à chaque nouveau passage dans la boucle. Le programme affiche la valeur de l'entier puis affiche le menu suivant : 1.TP 1ère Année UNSA/IUT de Nice .. Afficher le code ASCII des chiffres 2. Le programme demande une valeur entière. Afficher le code ASCII des lettres majuscules 4. La valeur n est saisie une seule fois en début de programme. 14 ). calcule le carré de cette valeur. le programme se termine. Afficher le code ASCII des lettres minuscules 3. Afficher la somme de 1 à n 2. 10. Si l'utilisateur tape une valeur entre 1 et 3. le programme se termine. 10) Ecrire un programme qui demande à l’utilisateur de taper 10 entiers et qui affiche le plus petit de ces entiers. 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.département GEII I1 . 15) Ecrire un programme qui permet de faire des opérations sur un entier (valeur initiale à 0). 16) Ecrire un programme qui permet d'afficher le code ASCII de certaines lettres de la table. Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées (questions 15. 08/08/2007 JLS page 27/56 08/08/2007 JLS page 28/56 . Le programme après avoir lu la valeur entière n. 17 ). Si l'utilisateur tape une valeur entre 1 et 3. Demander à l'enseignant quelle question vous devez traiter. le programme se termine.UNSA/IUT de Nice .u(n)+4 Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées (questions 12. Afficher si n est pair ou impair 4. Lorsqu'on tape 4. diviser par 2 4. 14) Ecrire un programme qui calcule le carré de la valeur entière saisie par l'utilisateur et l'affiche. Demander à l'enseignant quelle question vous devez traiter. Utiliser getchar pour lire le caractère. 9) Ecrire un programme qui demande à l’utilisateur de taper 10 entiers et qui affiche leur somme. 13. 17) Ecrire un programme qui permet d'afficher un certain nombre de calcul sur un entier préalablement saisi par l'utilisateur. 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. Ensuite le programme affiche la somme des carrés calculés. Attention au retour chariot qui est vue comme un caractère! Le programme demande alors de taper un entier entre 1 et 4. Le programme affiche le menu suivant : 1. 8) Ecrire un programme qui demande à l'utilisateur d'entrer un chiffre à virgule et qui arrondit à l'entier le plus proche. 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. Quitter Le programme demande alors de taper un entier entre 1 et 4. Lorsqu'on tape 4. Lorsqu'on tape 4. L'aide de la fonction floor fournit un exemple. le programme effectue le calcul demandé puis réaffiche le menu et ainsi de suite jusqu'à ce qu'on tape 4.5. on affiche la nouvelle valeur de l'entier puis on réaffiche le menu et ainsi de suite jusqu'à ce qu'on tape 4. l'affiche et recommence tant que cette valeur est supérieure à 0. Quitter Le programme demande alors de taper un entier entre 1 et 4.département GEII I1 .h>.TP 1ère Année 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. Ajouter 1 2. Le programme affiche alors la somme de tous les nombres saisis excepté le dernier (qui était en dehors des limites). 11 ). Demander à l'enseignant quelle question vous devez traiter. Recopier et commenter cet exemple dans le compte-rendu. on effectue l'opération. affiche le menu suivant : 1. Multiplier par 2 3. Afficher la somme des carré :1 + 2*2 + 3*3 + . 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. Quitter 7) Grâce à l'aide de VC++ (touche F1) rechercher le but des fonctions ceil et floor. Le programme affiche alors le nombre de 'b' entrés par l'utilisateur. 13) Ecrire un programme qui demande à l'utilisateur une lettre et ce tant que la lettre saisie n'est pas une voyelle. + n*n 3. 16. Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées (questions 9.

4) Que fait le programme suivant si on rentre 12 #include <stdio. c1=getchar(). Exemple : 153 = 1 + 125 + 27. printf("saisie de 2 caracteres>"). printf("%c%c\n". system("PAUSE"). 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). 2) Que fait le programme suivant si on rentre 12 #include <stdio.c1. } puis 23 ? Expliquer. les fonctions scanf() ou getchar() sont bloquantes.c1.c2). Préparation 1) Ecrire un programme permettant d'afficher les 10 premiers nombres pairs.département GEII I1 .c2.&c1. printf("saisie de 2 caracteres>"). et qu'ils ont tous 3 chiffres (ils sont compris entre 100 et 500). unité) Pour décomposer un nombre en centaine.UNSA/IUT de Nice .h> int main(int argc. c2=getchar().&c1.TP 1ère Année UNSA/IUT de Nice . char *argv[]) { char c1. unité.c1. Remarque : comme il a été vu dans le TD2. c2=getchar(). SOLUTION 1 : On sait qu'il n'existe que 4 nombres de Armstrong. j chiffres des dizaines et k chiffres des unités).h> #include <stdlib.h> int main(int argc.c1. Donc si l'on veut lire 2 caractères il faudra en fait lire les 2 caractères + le retour chariot. Ainsi si l'utilisateur entre '1' . est un nombre de Armstrong.TP 1ère Année TP4 Algorithmique 2 Thème Programmation avec toutes les structures de contrôles. scanf("%c%c". 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. printf("saisie de 2 caracteres>"). '2' suivi de non pas 2 comme on pourrait le supposer). 53/10=5 et 53%10=3. dizaine et unité) constituant le nombre. 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. char *argv[]) { char c1. le programme reste bloqué sur la fonction de lecture. printf("%c%c\n".: tant que l'utilisateur n'a pas tapé sur le retour chariot. 5) Donner une solution à ce problème en utilisant getchar(). 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.h> #include <stdlib. system("PAUSE"). scanf("%c%c". dizaine. il suffit de se rappeler que 153/100 =1 et que 153 %100=53. printf("%c%c\n". Il ne reste plus qu'à calculer la somme des cubes de ces 3 chiffres et de tester le résultat au nombre. (3 boucles for imbriqués).&c2). 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. dizaine. return 0. SOLUTION 2 Sachant qu'un nombre est écrit ijk (i chiffre des centaines. 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. 6) Ecrire un programme qui demande à l'utilisateur d'entrer 2 caractères. Dans ce buffer se trouvent les caractères entrés mais aussi le code ASCII du retour . printf("%c%c\n". } puis 23 ? Expliquer. se trouvent dans le buffer de saisi 3 caractères (et chariot.c2). Nombres de Armstrong: 08/08/2007 JLS page 29/56 08/08/2007 JLS page 30/56 . Donc grace à des divisions entières et à des restes de divisions (modulo) il est possible de trouver les 3 chiffres (centaine.département GEII I1 . printf("saisie de 2 caracteres>").&c2). c1=getchar(). Si a est impair a&1 renvoi 1 et si a est pair a&1 renvoi 0 (Cf TD3). while et do while.c2). Utilisation des fonctions srand et rand.c2).c2. 3) Donner une solution à ce problème). return 0. Utiliser un boucle for.

08/08/2007 JLS page 31/56 08/08/2007 JLS page 32/56 . 11) Ecrire un programme qui saisit un nombre et affiche tous les nombres premiers inférieurs ou égaux à ce nombre. #define MAX 10 #define MIN 1 int main(void) { int i.département GEII I1 . srand(time(0)). Il faut alors sortir de la boucle (break. } puts("").h> <time.int rand(void) : retourne un nombre entier pseudo-aléatoire compris entre 0 et 32767 . nVal).). dans laquelle on calcule n%i avec i variant de 2 à n-1. i est égal à n cela veut dire que n n'est pas divisible et donc est un nombre premier. le nombre n'est pas premier( il est au moins divisible par i). Dés que ce modulo est égal à 0.TP 1ère Année 153 370 371 407 7) Ecrire le programme qui affiche les nombres d'Armstrong selon la méthode de la solution 1. // nVal compris entre 1 et N printf("%d ".département GEII I1 . Remarque :Un nombre pair ne peut pas être premier.h> <math.void srand(unsigned int amorce) : donne une valeur initiale à rand(). system("PAUSE").TP 1ère Année UNSA/IUT de Nice . 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 nVal. Puis afficher sous forme d'histogramme.h> 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). return 0. Si en sorti de la boucle for. exemple d'une fonction qui remplit aléatoirement un tableau de 10 entiers compris entre MIN et MAX #include #include #include #include <stdio.i++) { nVal=rand()%MAX +MIN. On pourra utiliser ce principe pour réduire les tests de nombre premier.h> <stdlib. } 9) Faire 20 tirages aléatoires de nombres compris entre 0 et 3 et compter le nombre d'occurrence de chaque chiffre. /* utilisation de l'horloge pour initialiser la suite */ for (i=0. Le principe est une boucle for. afficher le max et le min et la moyenne de la séquence.UNSA/IUT de Nice .i<10. 8) Ecrire le programme qui affiche les nombres d'Armstrong selon la méthode de la solution 2.

. Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées. N=>3 --* --** * --*** ** * FIN DU PROGRAMME 6) Ecrire un programme qui demande à l'utilisateur de saisir un entier N . si le nombre est impair et compris entre 1 et 10 le programme affiche un carré de N’#' . chaque triangle étant séparé par une ligne de N caractères '-'. 3) Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau ainsi qu'un entier V. Utilisation des tableaux et chaînes de caractères.département GEII I1 . 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 Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées. 08/08/2007 JLS page 33/56 08/08/2007 JLS page 34/56 . Demander à l'enseignant quelle question vous devez traiter. 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 compter le nombre de voyelles. N=>3 ### ### ### N=>2 ** ** N=>0 FIN DU PROGRAMME Travail à faire Questions différenciées : Ne traiter ici qu'une question sur les 3 proposées.6.8. 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.10 au moment de la déclaration du tableau et qui calcule la somme de ce tableau. 7) Ecrire un programme qui demande à l'utilisateur de saisir 10 notes comprises entre 0 et 20 qui seront stockés dans un tableau. de consonnes et de chiffres entrées.TP 1ère Année UNSA/IUT de Nice .UNSA/IUT de Nice . 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". Le programme s'arrête si l'utilisateur entre une valeur inférieure à 1 ou supérieure à 10. entre 11 et 15 et entre 16 et 20. Le programme doit alors traiter le tableau et compter et afficher le nombre de notes comprises entre 0 et 5. la moyenne et le nombre minimum de ce tableau. Si le nombre est pair et compris entre 1 et 10 le programme affiche un carré de N’*'.comprises entre 6 et 10. 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. 4) Ecrire un programme qui demande à l'utilisateur de saisir un entier N et qui affiche un triangle inversé de N lignes. Demander à l'enseignant quelle question vous devez traiter. Demander à l'enseignant quelle question vous devez traiter. Ci-dessous est affiché une copie d'écran du programme avec en GRAS la saisie de l'utilisateur.département GEII I1 . Cidessous est affiché une copie d'écran du programme avec en GRAS la saisie de l'utilisateur. 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. Le programme doit alors traiter le tableau et afficher la somme de ces nombres. 9) Ecrire un programme qui demande à l'utilisateur de saisir 10 caractères qui seront stockés dans un 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).5.4.TP 1ère Année TP5 Tableaux et chaînes de caractères Thème Programmation avec toutes les structures de contrôles.

On fait autant de parcours que nécessaire jusqu'à ce que le nombre d'échanges soit nul : le tableau sera alors trié.département GEII I1 . Exemple de traitement : 24 5 5 5 5 24 9 9 100 9 100 9 100 24 24 100 recherche min de 0 à n-1 (ici la valeur 5.(ici la valeur 9. Le programme doit trier le tableau par ordre croissant et doit afficher le tableau.TP 1ère Année UNSA/IUT de Nice . 13) Ecrire un programme qui demande à l’utilisateur de taper 4 entiers qui seront stockés dans un tableau. Exemple de traitement : 24 5 5 24 100 9 100 9 teste case 0 et 1 : 24>5 : permutation teste case 1 et 2 : 24<100 :pas de permutation JLS page 35/56 08/08/2007 JLS page 36/56 08/08/2007 ... (ici la valeur 24. on recommence le processus en comparant t[1] et t[2]. Le programme donne la première lettre et la dernière lettre de la phrase. permutation de la case 1 et 0 recherche min de 1 à n-1. Demander à l'enseignant lequel vous devez traiter.. Méthodes de tri de tableaux : Ne traiter qu'un problème sur 2. On cherche l'indice du plus petit élément parmi les indices de 2 à 4 et on échange cet élément avec t[2].TP 1ère Année 10) Ecrire un programme qui demande à l'utilisateur d'entrer un phrase (utiliser gets) . case 3) permutation de la case 3 et 2 fin du programme : indice courant = n-1 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 5 24 9 9 24 100 teste case 1 et 2 : permutation 100 teste case 2 et 3 :pas de permutation On recommence 5 9 24 100 teste case 0 et 1: pas de permutation 5 5 9 9 24 24 100 teste case 1 et 2: pas de permutation 100 teste case 2 et 3: pas de permutation Il n'a pas eu de permutation donc le tableau est trié.UNSA/IUT de Nice .département GEII I1 . 11) Ecrire un programme qui demande à l'utilisateur d'entrer une phrase et qui compte le nombre d'espace dans la phrase. et ainsi de suite jusqu'à t[3] et t[4]. On cherche l'indice du plus petit élément parmi les indices de 3 à 4 et on échange cet élément avec t[3]. case 3) permutation de la case 3 et 1 recherche min de 2 à n-1. On compte lors de ce parcours le nombre d'échanges effectués. 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. case 1). On cherche l'indice du plus petit élément parmi les indices de 1 à 4 et on échange cet élément avec t[1]. 14) Ecrire un programme qui demande à l’utilisateur de taper 10 entiers qui seront stockés dans un tableau. 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é. 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]. Le programme doit trier le tableau par ordre croissant et doit afficher le tableau.

break.département GEII I1 . Pour cela écrire le code main permettant d'afficher le min. else return ia. default : printf("?\n"). case '=': printf("%d".&n). Variables locales et variables globales. 2) Étudier le programme suivant : #include <stdio.TP 1ère Année TP6 Les fonctions Thèmes Les fonctions.&n). 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.iMemoire).h> // code des fonctions int mini(int ia. switch (com) { case '-': scanf("%d". le max et la moyenne de 2 nombres saisis.int ib) { // a compléter } // fonction principale int main(void) { int ia. int iMemoire. //a compléter } } printf("\n>"). break.&com). Les chaînes de caractères Préparation 1) Compléter le programme ci-dessous. } double moyenne(int ia.h> int main(void) { char com.int ib) { if(ib>ia) return ib. } } while ( com != 'q' ) .TP 1ère Année UNSA/IUT de Nice .&com).n. case 'z': iMemoire=0.int ib) { if(ia>ib) return ib. iMemoire=iMemoire+n. case 'q': break. break. iMemoire=iMemoire-n.UNSA/IUT de Nice . 4) Que se passe-t-il si on remplace l'instruction scanf(" %c". else return ia. case '+': scanf("%d". do { 08/08/2007 JLS page 37/56 08/08/2007 JLS page 38/56 .département GEII I1 . par l'instruction com=getchar() ? Expliquer.ib. iMemoire=0. } int maxi(int ia. break. On utilisera les 3 fonctions dont le code est donné ci-dessous : #include <stdio. scanf(" %c".

} void affiche(void) { // A compléter } 7) Comparer les 2 solutions et conclure . } } while ( com != 'q' ) . case '=': afficher(iMemoire).&n). 2 et 3 sont des diviseurs de 6) 28=14+7+4+2+1 est un nombre parfait (14. case 'q': break. scanf(" %c".TP 1ère Année On désire découper le programme précédent en fonctions. break. 6) Compléter le programme ci-dessous qui n'utilise pas de variables globales #include <stdio. case 'q': break. break.h> // variables globales int giMem. 7 .int n) { // a compléter } int soustraction(int iMem. Pour cela 2 solutions : Utilisation d'une variable globale giMemoire. default : printf("?\n"). 4 . break. Exemple : 6 = 1+2+3 . void raz(void).n). // déclaration des fonctions void addition(int n). } // code des fonctions int addition(int iMem. int n. iMemoire=soustraction(iMemoire.&n). 2 et 1 sont des diviseurs de 28) 496 est un nombre parfait 8128 est un nombre parfait JLS page 39/56 08/08/2007 JLS page 40/56 08/08/2007 . case 'z': iMemoire=0. case '=': affiche(). int iMemoire. default : printf("?\n"). break. void soustraction(int n). break. void affiche(void).&n). iMemoire=addition(iMemoire.int n) { // a compléter } void afficher(int iMem) { // a compléter } do { printf("\n>"). // fonction principale int main(void) { char com. Utilisation de variables locales seulement. soustraction(n).département GEII I1 . break. scanf(" %c". addition(n). case '+': scanf("%d". Un nombre est dit parfait s’il est égal à la somme de ses diviseurs. break.n). 5) Compléter le programme ci-dessous qui utilise une variable globale giMem : #include <stdio.h> // déclaration des fonctions // A compléter // fonction principale int main(void) { char com.&com).&com). Travail à faire Nombre parfait: Objectif : On souhaite écrire un programme de test de nombres parfaits. case 'z': raz(). break.&n). } // code des fonctions void addition(int n) { // A compléter } void soustraction(int n) { // A compléter } void raz(void) { giMemoire=0. switch (com) { case '-': scanf("%d".TP 1ère Année UNSA/IUT de Nice . 1 compris. do { printf("\n>"). case '+': scanf("%d".UNSA/IUT de Nice . int n.département GEII I1 . est un nombre parfait (1 . } } while ( com != 'q' ) . switch (com) { case '-': scanf("%d".

printf("le nombre de voyelle %d\n". printf("le nombre de consonne %d\n". Ecrire le code de 2 façons : 8) solution 1 : code monolithique (sans utilisation de fonctions.nbLettre(sz)).nbChar(). recommencer. puis appeler ces fonctions dans la fonction main pour obtenir le résultat suivant.nbCons(sz)). printf("taille du mot %d\n".'E')).département GEII I1 .nbChar(sz. longueurChaine( taille de la chaine). Ecrire un programme qui teste si un nombre est parfait .nbVoy(nombre de voyelles de la chaines) . 10) Amélioration :Tant que l'utilisateur n'a pas entré un nombre parfait. inversion et de test d'égalité de2 chaînes de caractères. 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.département GEII I1 .TP 1ère Année Pour savoir si un nombre est parfait ou non. mettre_en_majuscule(sz). Utiliser la fonction strcpy pour copier cette chaine (après compression) dans la chaine à inverser.nbLettre (nombre de lettres) . int main(void) { char sz[40].UNSA/IUT de Nice . printf("le nombre de lettre %d\n". il suffit de prendre toutes les valeurs inférieures à ce nombre et incrémenter les valeurs qui sont des diviseurs de ce nombre. é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. Résultat Travail sur les chaines de caractères On désire écrire le programme suivant : Ce programme utilise les fonctions mettre_en_majuscule(). 11) Ecrire le code de ces fonctions. gets(sz). printf("le nombre de caractere e %d\n". while(1). puts("entrer un mot"). puts(sz). La fonction main utilise la fonction isParfait pour testerr si le nombre entré est parfait ou non . } 08/08/2007 JLS page 41/56 08/08/2007 JLS page 42/56 .TP 1ère Année UNSA/IUT de Nice . La chaine de test sera initialisé à la déclaration ( prendre "elu par cette crapule"). 9) solution 2 : code avec fonction.nbVoy(sz)).longueurChaine(sz)).) tout le traitement est fait dans la fonction main(). Ecrire ce nouveau programme. 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.

f doit renvoyer par un return le nombre de valeurs comprises entre 0 et 10 dans les iElem premières cases du tableau iTt.y) (((x)>(y))?(x):(y)) #define MIN(x. // code des fonctions void addition(int *piMem.h> permettant de tester 2 chaînes de caractères. Nous avons aussi placé 2 fonctions max et min pour une comparaison avec les macros.UNSA/IUT de Nice . introduction aux macros.int n) { // a compléter } Dans le cas ou le test est vrai alors c'est la valeur1 qui est renvoyée sinon c'est la valeur2.département GEII I1 . int i=9. Introduction au langage assembleur. Ces fonctions ne renvoient rien et mettent à jour la valeur pointée par piMem.département GEII I1 . 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. 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".sz2[20]="az". 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. Une nouvelle instruction a aussi été rajoutée qui est une spécificité du language C .h> // mes définitions de constantes #define N1 3 #define N2 5 // mes macros #define MAX(x. printf("ia=%d\n". ia=(i<0)?0:2.int ib) { return ((ia>ib)?ia:ib). Exemple : la fonction strcmp renvoie 0 si sz1 est égal à sz2 ou une valeur différente de 0 dans le cas contraire. } 08/08/2007 JLS page 43/56 08/08/2007 JLS page 44/56 . Passages de paramètres par pointeurs. else ia=2. char sz1[20]="za". le programme affiche "different". // si i<0 ia prend la valeur 0 sinon 2 printf("ia=%d\n". celle entrée par l'utilisateur et "az". (test) ?valeur1:valeur2.TP 1ère Année Algorithme suggéré : TP7 Chaîne de compilation. le programme donne le nombre d'essais infructueux.sz1)==0) puts("identique"). if(strcmp(sz2.TP 1ère Année UNSA/IUT de Nice . Dans l'exemple ci-dessous. Chercher dans l'aide(F1) pour plus de détail. Role du préprocesseur.ia.int n) { // a compléter } void soustraction(int *piMem. 2) Reprendre l'exercice 6 du TP6 sur la machine à calculer et modifier l'appel des fonctions soustraction et addition dans la fonction main. Programme de test permettant de montrer le role du préprocesseur. Prenons un exemple : dans le fichier ci-dessous 2 constantes N1 et N2 et 2 macros MAX et MIN sont définies. Tant que l'utilisateur n'a pas entré les caractères az celui-ci recommence. #include <stdio. notion de projet. Tester cette fonction. Dés que la séquence a été trouvée. Travail à faire 3) Ecrire le programme utilisant la fonction strcmp définie dans <string. Compilation de plusieurs fichiers. 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.y) (((x)>(y))?(y):(x)) // mes fonctions int max(int ia. if(i<0) // si i<0 ia prend la valeur 0 sinon 2 ia=0. fonctions et pointeurs Thèmes Les fonctions.ia). Chaîne de compilation.ia). else puts("different").

min(N1.(((3)>(5))?(5):(3))).TP 1ère Année UNSA/IUT de Nice .i // déclaration de printf __declspec(dllimport) int __cdecl printf( const char * _Format. } Programme après passage du préprocesseur : extrait du fichier tp7_exo4.N2)). saisir un angle en degre et l'afficher en radian (utilisation de PI).MAX(N1. #define RADTODEG(x) ((x) * 57.N2)). Pour visualiser ce fichier nous devons modifier une option du projet. 08/08/2007 JLS page 45/56 08/08/2007 JLS page 46/56 .(((3)>(5))?(3):(5))). Visualiser le fichier. else return ia. VC++ comme tous les compilateurs permet de visualiser un certain nombre de fichiers intermédiaires générés par le compilateur. Dans VC++ comme pour tous les compilateurs (gcc. printf("max:%d\n". } // prog principal : test des fonctions min max et macros MIN et MAX int main(void) { printf("MAX:%d\n".département GEII I1 .c et tp7-exo4. } int main(void) { printf("MAX:%d\n".int ib) { if(ia>ib) return ib.)..max(N1..i . printf("min:%d\n". } int min(int ia. printf("min:%d\n". printf("MIN:%d\n". ont été enlevées.i". 5) Donner les différences entre les 2 fichiers tp7_exo4. system("PAUSE"). system("PAUSE").. return 0.N2)).int ib) { if(ia>ib) return ib.5)). Nous allons visualiser le fichier assembleur (extension . Afficher les propriétés du projet On peut voir dans le programme ci-dessus que toutes les parties de code qui étaient en #.5)).département GEII I1 . else return ia. borland C++.) il est possible de visualiser le fichier créé par le préprocesseur.. int max(int ia. Ce fichier possède un grand nombre de lignes inutiles qui seront traitées par le compilateur. Le but de cette manipulation est de comprendre la chaîne de compilation et le rôle de chaque outil.min(3.UNSA/IUT de Nice . printf("MIN:%d\n".TP 1ère Année int min(int ia. saisir une valeur et donner sa valeur absolue (utilisation de ABS)..14159 Rappels sur la chaîne de compilation : le compilateur Puis taper sur F7 (Générer la solution ) pour lancer le préprocesseur.N2)).int ib) { return ((ia>ib)?ia:ib). En déduire ensuite le code généré après le passage du préprocesseur.. return 0.29578) #define ABS(x) ((x>0)?x:-x) #define PI 3.max(3.c) et copier le résultat obtenu dans le compte-rendu. Sous VC++. Choisir la génération du fichier après passage du préprocesseur 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). printf("max:%d\n". ce fichier prend l'extension ". Allez en fin de fichier afin de visualiser le code main et le traitement fait par le préprocesseur. .asm) généré par le compilateur.MIN(N1. } 4) Lancer le programme ci-dessus (tp7_exo4.

asm généré dans le répertoire RELEASE sous le répertoire du projet tp7. eax.c #include <stdio. ia=ib+ic.ic. . } extrait du fichier test. ia=ia<<1.Le code qui se veut très simple va permettre de comprendre le travail effectué par le compilateur. Quelle est l'instruction assembleur permettant de faire un test (if) ? Le code ci-dessous a été généré avec l'option Assembly.département GEII I1 . Pour visualiser le code machine . DWORD PTR _ib$[ebp] eax. ia=ib+ic. Le code assembleur généré est le langage compréhensible par le processeur PENTIUM. DWORD PTR _ic$[ebp] DWORD PTR _ia$[ebp].ib. 7 . il suffit de regénérer la solution mais cette fois-ci avec l'option Assembly et code machine.TP 1ère Année 7) Créer un nouveau programme tp7_exo7.h> #define N1 3 #define N2 5 int main(void) { int ia. 0002c 0002f 00032 8b 45 ec 03 45 e0 89 45 f8 mov add mov eax. tp7_exo7. afficher le code machine. while(1).ib=N1. mettre un point d'arrêt (clic à gauche du code à stopper). Pour cela. Ensuite. il suffit dans le menu Debug.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 . Puis lancer le programme qui s'arrête sur le point d'arrêt. Après génération du projet (F7) le fichier tp7_exo7. DWORD PTR _ic$[ebp] DWORD PTR _ia$[ebp]. Fenêtre. En déduire l'instruction assembleur associée à la soustraction et au décalage à gauche.c et l'ajouter au projet tp7 (n'oubliez pas d'enlever l'ancien programme). les programmeurs écrivaient leurs programmes en assembleur. else ib=8. 08/08/2007 JLS page 47/56 08/08/2007 JLS page 48/56 . eax Pour visualiser le fichier assembleur tp7_exo7. Certaines routines du BIOS et certains drivers sont toujours écrits en assembleur.cod est généré dans le répertoire RELEASE .département GEII I1 . Avant l'apparition des langages évolués. 8 : : mov add mov int ia. code machine et source (/FAcs) dans Fichiers de sortie (compilateur C/C++) dans la fenêtre propritété du projet. ia=ib-ic.TP 1ère Année UNSA/IUT de Nice . if(ia==1) ib=5. 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é. 8) Recopier le code assembleur associé à la soustraction et au décalage à gauche. DWORD PTR _ib$[ebp] eax.ic=N2. adresse en RAM du programme code machine en RAM code assembleur associé au code machine (plus lisible) Une autre solution pour voir le code assembleur est d'utiliser le débogueur. return 0. eax Ces instructions assembleurs ont un code machine qui est en mémoire RAM.UNSA/IUT de Nice .

// recherche du min du tab de nElem int min_tab(int nTab[]. #define N 5 int main(void) { int it1[N]. int nMax). puts("t3").N). int n). Le dernier octet donne l'adresse des variables ia. int nElem).N. Le code machine de ces instructions est sur 16 bits. // calcul de la moyenne du tab de nElem double moyenne_tab(int nTab[]. 9) Expliquer pour chacune des 3 instructions assembleurs générées à partir de l'instruction ia=ib+ic. du compteur eip. Donner le code machine de add et sub.max_tab(it1. system("PAUSE"). RAM ia ib ic #include <stdio. Il est possible de visualiser la zone mémoire ou se trouve ia.N)). int nMin. saisir_tab(it3. int nElem). int nElem. // recherche du max du tab de nElem int max_tab(int nTab[].TP 1ère Année UNSA/IUT de Nice . printf("min=%d\n". } // code des fonctions void remplir_tab(int nTab[]. affiche_tab(it3.i++) { eip Compteur d’instructions eax 32 bits 32 bits Unité arithmétique et logique ALU 32 bits Extrait du schéma fonctionnel du CPU 08/08/2007 JLS page 49/56 08/08/2007 JLS page 50/56 .département GEII I1 . affiche_tab(it2. creer_tab_aleatoire(it1. 10) Chaque instruction possède un code machine.19).N). Le compilateur n'est pas le dernier élément permettant de générer un exécutable.i<nElem. Or le code machine de ces instructions est sur 24 bits. int nEle. int nElem. ib et ic qu'il faut rajouter au registre ebp.min_tab(it1. printf("max=%d\n". faire l'exercice ci-dessous : Schéma simplifié de la structure PENTIUM + RAM RAM 0x0000 Début du prog … Découpe des blocs de fonctions en fichiers 11) Ecrire le code des fonctions marquées A COMPLETER.N)). le role du registre d'instruction.moyenne_tab(it1. // saisie du tab par l'utilisateur void saisir_tab(int nTab[].2). affiche_tab(it1. 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.département GEII I1 . Afin de montrer le rôle du linker . puts("t2"). remplir_tab(it2. int n) { for(i=0. puts("t1"). int nElem). printf("moy=%g\n".N)).N. int nElem). // créer un tab de nEle commençant à nMin et finissant à nMax void creer_tab_aleatoire(int nTab[]. int it2[N]. void remplir_tab(int nTab[].UNSA/IUT de Nice .N).TP 1ère Année Le code assembleur associé à chaque instruction en C apparaît.h> #include <time.h> Zone de données 0x002C 0x002F 0x0032 Bus d’adresse 8b 45 ec 03 45 e0 89 45 f8 Zone de programme Bus De données 32 bits Registre d’instruction Bus d’adresse Bus De données + ebp 32 bits // remplir un tab de nEle avec la valeur n.N). de l'ALU. int it3[N]. ib et ic.1. du registre eax et du registre ebp.

int n).c et le fichier de bibliothèque xxx. i++) { nTab[i]= nMin+ (int) rand()%(nMax-nMin+1) . int nEle) { // a compléter } Découpe en fichiers : exemple Toutes les déclarations de fonctions doivent être mises dans un fichier xxx.h ou se trouve toutes les déclarations (ou prototypes) des fonctions. int nMin. // saisie du tab par l'utilisateur void saisir_tab(int nTab[].TP 1ère Année UNSA/IUT de Nice . L'éditeur de lien va générer le fichier exécutable en assemblant le code des fichiers objets xxx. for(i=0. scanf("%d".i<nElem.i++) { printf("t[%d]=".h Le code des fonctions est placé dans le fichier xxx.TP 1ère Année nTab[i]=n. int nElem. 08/08/2007 JLS page 51/56 08/08/2007 JLS page 52/56 . srand(time(0)).obj et main. int nElem) { // a compléter } double moyenne_tab(int nTab[]. Les 2 fichiers compilés se nomment main. int nMax) { int i. Dans le projet courant créer le fichier tableau.département GEII I1 . int nElem) { int i.obj et xxx.UNSA/IUT de Nice . int nElem) { // a compléter } // créer un tableau de nEle éléments commençant à nMin et finissant à nMax void creer_tab_aleatoire(int nTab[]. } } void affiche_tab(int nTab[]. // recherche du min du tab de nElem int min_tab(int nTab[]. for(i=0.i<nEle. } } void saisir_tab(int nTab[].département GEII I1 .nTab[i]). tableau.obj.c.i). int nEle.h // remplir un tab de nEle avec la valeur n.obj générés par le compilateur. int nElem). void remplir_tab(int nTab[]. } } int min_tab(int nTab[].c Le compilateur doit compiler le fichier main. int nElem) { // a compléter } int max_tab(int nTab[]. int nElem).

int nEle). Vous devriez avoir dans l'explorateur de projet . ce fichier va accueillir le code des fonctions sur les tableaux. int nElem).département GEII I1 .2).c et test. Fichiers sources .c #include <stdlib. Fichier test. saisir_tab(it3. int nEle.h> #include "tableau. puts("t1"). int it3[N]. int nMin.h" Puis ajouter tableau. puts("t3"). affiche_tab(it3.N). int it2[N].UNSA/IUT de Nice .TP 1ère Année UNSA/IUT de Nice .N).N). // calcul de la moyenne du tab de nElem double moyenne_tab(int nTab[].N.N. #define N 5 int main(void) { int it1[N]. Ensuite créer un nouveau fichier tableau. affiche_tab(it1.N). // créer un tab de nEle commençant à nMin et finissant à nMax void creer_tab_aleatoire(int nTab[]. creer_tab_aleatoire(it1. int nMax).1.min_tab(it1. 08/08/2007 JLS page 53/56 08/08/2007 JLS page 54/56 .c dans le projet existant. affiche_tab(it2.TP 1ère Année // recherche du max du tab de nElem int max_tab(int nTab[]. puts("t2"). printf("min=%d\n". // afficher le tab de nEle void affiche_tab(int nTab[].N)).département GEII I1 . les 2 fichiers tableau. remplir_tab(it2.19). Ces 2 fichiers vont être compilés .c . int nElem).c.

c et modifier le nom de la fonction carre en carre_bis.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. scanf("%d".UNSA/IUT de Nice .c dans laquelle sont appelées et testées les 2 fonctions. srand(time(0)).c et tester .i<nEle. Créer ensuite la fonction main. } } void affiche_tab(int nTab[]. Créer ensuite le fichier mes_fonctions.département GEII I1 .i<nElem. for(i=0. int nElem) { // a compléter } // créer un tableau de nEle éléments commençant à nMin et finissant à nMax void creer_tab_aleatoire(int nTab[].c // code des fonctions void remplir_tab(int nTab[]. printf("moy=%g\n". 13) Créer un nouveau projet.N)). } } void saisir_tab(int nTab[].max_tab(it1.obj librairie (printf) ? mes_fonctions.i++) { nTab[i]=n.exe 15) Modifier le programme mes_fonctions. } fonctions.i++) { printf("t[%d]=". int nMin. int nElem) { // a compléter } int max_tab(int nTab[].c ? main.c 12) Compléter le code des fonctions de tableau.nTab[i]). On suppose que le tableau ne possède pas de valeurs en double.N)). Faire une faute dans la fonction carre_bis et vérifier que l'erreur est générée par le compilateur.moyenne_tab(it1. Générer la solution (F7) et vérifier que l'erreur vient du linker.i<nElem.obj ? tp7_exo9. int nElem) { // a compléter } double moyenne_tab(int nTab[]. int nMax) { int i. i++) { nTab[i]= nMin+ (int) rand()%(nMax-nMin+1) . int nEle. for(i=0. 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. Cette fonction sera ajoutée au fichier tableau. int nElem) { int i. Dans ce projet créer le fichier mes_fonctions. 14) Compléter le schéma ci-dessous : Fichier tableau.département GEII I1 .i). int n) { for(i=0.h ou se trouve les déclarations de ces 2 08/08/2007 JLS page 55/56 08/08/2007 JLS page 56/56 . int nEle) { // a compléter } mes_fonctions.c main. } } int min_tab(int nTab[].TP 1ère Année printf("max=%d\n". int nElem. system("PAUSE").TP 1ère Année UNSA/IUT de Nice .