tp1
Transcription
tp1
Langage Impératif 1 TP 1 du 11 octobre 2010 Série d’exercices Rappels rapides : - Un programme C s’écrit toujours dans un fichier d’extension .c (en minuscule !! sinon ce serait compilé comme du C++). Ce fichier est aussi appelé fichier source. - Ce fichier source contient une fonction main(). Cette fonction doit toujours être déclarée de type int et retourner un int via l’instruction return. - La compilation du fichier source s’effectue par la commande gcc mais avec différentes options. Nous présentons quelques unes ci-dessous : o Cas 1 : gcc nomSource.c Un fichier a.out est généré par défaut qui correspond à la forme exécutable du programme nomSource.c. o Cas 2 : gcc –o nomExecutable –c nomSource.c L’exécutable généré porte le nom qui suit l’option –o, ici nomExecutable. Il est préférable de ne pas mettre d’extension à l’exécutable. L’option -c permet d’indiquer le fichier .c à compiler. o Cas 3 : gcc –o nomExecutable –W -Wall nomSource.c Les options –W et -Wall permettent l’affichage d’un maximum de messages d’erreurs à la compilation. Il arrive parfois que le programme compile, bien qu’il contienne des erreurs. Il est donc nécessaire de corriger ces erreurs et de n’exécuter le programme que lorsque ce dernier est exempt d’erreurs. Dans nos séances de TP nous compilerons nos programmes avec cette dernière commande. - L’exécution du programme s’effectue de la manière suivante : ./nomExecutable 1 Premier programme C « Hello World » 1. Ecrire le programme toto.c du cours. a) Compilez-le avec la commande : gcc toto.c. regardez les fichiers générés (commande ls du Shell). Que voyez-vous ? b) Maintenant, c) Supprimer le « ; » après le printf(). Sauvegardez, puis compilez. Que se passe-t-il ? Le fichier binaire a-t-il été généré ? remettez les « ; » après le printf(), sauvegardez. La fonction main d) Ecrire une seconde fonction main() à la suite de la première de façon à ce qu’elle contienne un printf(« Goodbye world ! »). Compilez et exécutez. Qu’observez-vous ? 2. Que fait le programme ci-dessous ? a) Ecrivez, sauvegardez puis compilez ce programme. b) Exécutez le programme de manière à afficher la liste suivante : 3 b 10000 e Les commentaires Dans un des programmes précédemment écrit, ajoutez un commentaire sur plusieurs lignes contenant votre nom, prénom et date. 4. Ajoutez dans ce commentaire les caractères « */ », compilez. Qu’observezvous ? 3. 2 5. Essayez maintenant le commentaire suivant : Int /* type entier */ n /* une variable */,/*----*/p/* une autre variable */ ; Comment réagit le compilateur lors de la compilation ? 6. Comment le compilateur va-t-il traiter cette instruction ? printf(« Hello /* mon commentaire ici */ World ! ») ; Etapes de la compilation : Gcc effectue quatre étapes pour produire l'exécutable : gcc toto.c preprocessing toto.c compiling toto.i assembling toto.s linking toto.o a.out o passage au préprocesseur (preprocessing) : analyse le programme C et lui fait subir certaines transformations : - Suppression des commentaires Inclusion des fichiers .h dans le code source. Traitement des directives de compilation (#define, #elif, #else, #endif, #error, #if, #ifdef, #ifndef, #include, #line, #pragma, “undef). Traitement des erreurs de syntaxe. Il est possible de forcer le compilateur pour qu’il n’effectue que cette étape. Il génère alors un fichier intermédiaire d’extension .i. Voici l’option de compilation : $ gcc –E foo.c > foo.i o compilation en langage assembleur (compiling) : le code C est transformé en langage assembleur. Pour voir le code assembleur de votre programme vous pouvez utiliser l’option –S de gcc. o conversion du langage assembleur en code machine binaire (assembling) : le code assembleur qui est lisible par un humain, est transformé en binaire pour être exécuté par la machine (le processeur). Générer ce format de fichier, est utile lorsqu’on compile des programmes modulaires. Seuls les binaires des sources ayant été modifiés sont de nouveau générés à la compilation. Vous pouvez utiliser l’option –c avec gcc pour générer ce format. Pour le rendre visible utilisez la commande od –x toto.o (od pour Octal Dump et -x pour hexadecimal). 3 o édition des liens (linking) : à l’étape précédente, seuls les prototypes de fonctions sont chargés. Des liens entre ces prototypes et leurs sources (les .c correspondant aux librairies .h) doivent être faits. Une fois les liens établis, le binaire devient exécutable. Ces fichiers intermédiaires ne sont pas générés à la compilation, seul le fichier a.out nommé exécutable est généré. Mais vous aurez à utilisez les fichiers objets .o pour la compilation modulaire avec les makefile en Langage impératif 2. //!\\ Attention un exécutable ne peut fonctionner sur un autre système que celui où il é été généré. Par exemple un programme compilé sous Linux ne peut fonctionner sous Sun ou Windows. Vous devez recompiler votre programme sous le nouveau système pour qu’il puisse y être exécuté. 7. Reprenons le programme toto.c. a) Compiler le programme de façon à générer les fichiers intermédiaires .i, .s, .o. b) Copiez le programme en un nouveau fichier nommé exo7.c. c) Commentez la directive d’inclusion dans exo7.c et générez le fichier exo7.i. d) Comparez les deux fichiers toto.i et exo7.i. La modularité 8. Créez les fichiers suivants : main.c hello.c hello.h a) Compilez avec la commande gcc suivante : i. $ gcc –W –Wall hello.c main.c –o main b) Exécutez le programme. Les variables 9. Dans un programme, on déclare une variable x de type int et on lui affecte la valeur 5. a) Qu'affiche la suite d'instructions suivante ? printf ("Je sais que ") ; printf ("%d" , x ) ; printf (" est la valeur de x") ; printf ("\n") ; b) Réécrivez ces quatre printf en un seul. c) Modifiez la fonction main() de façon à passer la valeur affectée à x soit passée en paramètre d’entrée au programme. 4 10. Ecrivez le programme suivant : int a, b ; printf("%d , %d\n", a, b) ; a) Compilez. Qu’observez-vous ? b) Déclarer la variable c de type char. Et introduisez-la dans le printf (). Sauvegardez, compilez, exécutez. Qu’observez-vous ? c) Que fait le compilateur à votre avis ? Ecrivez un programme qui calcule la moyenne de deux notes (utilisez le type float). 12. Lorsque, par exemple, une variable est déclarée de type float et que la force à être de type int, cela s’appelle un cast. Le printf() effectue des cast implicites. Reprenez le programme de l’exercice 11 et retourner la moyenne des deux notes sous forme d’entier. 11. 5