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