Ce document a été produit par HEVEA.
Votre browser peut avoir a être configuré pour afficher correctement
certains symboles.
Reportez-vous à la documentation d'HEVEA.
qui calcule la factorielle de n de façon itérative. On placera le source de ce programme dans le fichier source factorielle.c ;unsigned int factorielle (unsigned int n) { unsigned int i = 1, res = 1; while (i n) res = res * i++; return res; }
% gcc -g -Wall -Werror -ansi -pedantic -o factorielle factorielle.c
indique que dans la fonction factorielle du fichier source factorielle.c, il y a une erreur. C'est une erreur de syntaxe à la ligne 6 (while (i n)) où il manque un opérateur entre i et n. La seconde erreur est une admonestation (warning) à la ligne 11 (main()), où le type retourné par la fonction main a été fixé par défaut à int. Lisez donc toujours bien les messages d'erreurs. Exécutez ensuite ce programme.% gcc -g -Wall -Werror -ansi -pedantic -o factorielle factorielle.c factorielle.c: In function `factorielle': factorielle.c:6: parse error before `n' cc1: warnings being treated as errors factorielle.c: At top level: factorielle.c:11: warning: return-type defaults to `int'
% factorielle 362880
et terminez son exécution (cont). Le programme a bien calculé la factorielle de 12, et non pas de 10. Recommencez avec n=13, et vérifiez que le résultat n'est pas égal à 13 fois le précédent. Les entiers de type int ne font bien que 32 bits sur cette machine.(xxgdb) set n=12
#if ARCH = i386 /* code pour un intel i386 */ #endif #if ARCH = alpha /* code pour un DEC Alpha */ #endif
qui calcule la factorielle de n de façon récursive. Placez les corps de ces fonctions dans une directive #ifdef/#endif de la manière suivante :unsigned int factorielle_recursive (unsigned int n);
De cette manière, si la macro RECURSIVE est définie, seule la fonction factorielle_recursive() sera définie, et l'appel à la fonction factorielle() sera un appel à factorielle_recursive(). Sinon seule factorielle_iterative() est définie, et un appel à factorielle sera un appel à factorielle_iterative().#ifdef RECURSIVE unsigned int factorielle_recursive (unsigned int n) { ... } unsigned int factorielle (unsigned int n) { return factorielle_recursive (n); } #else unsigned int factorielle_iterative (unsigned int n) { ... } unsigned int factorielle(unsigned int n) { return factorielle_iterative (n); } #endif
Vous voyez apparaître les déclarations de types, variables et fonctions standard, puis celles contenues dans% gcc -E -P factorielle.c | grep -v '^[ ]*$' | more
<stdio.h>
,
et enfin la définition de factorielle_iterative(),
factorielle() et main(). Recommencez en
définissant la macro RECURSIVE :
C'est bien maintenant la version récursive qui est définie.% gcc -E -P -D RECURSIVE factorielle.c | grep -v '^[ ]*$'
% gcc -D RECURSIVE -g -Wall -Werror -ansi -pedantic -o factorielle factorielle.c % xxgdb factorielle
(xxgdb) print n $1 = 4 (xxgdb) frame 3 #3 0x804840d in factorielle_recursive (n=7) at factorielle.c:5 (xxgdb) print n $2 = 7
et incluez ce fichier dans main.c :extern unsigned int factorielle(unsigned int);
Remarquez l'utilisation des doubles quotes pour indiquer au compilateur de chercher le fichier d'entêtes factorielle.h dans le répertoire courant en premier. Sans utiliser make, pour compiler le programme, il faut exécuter les commandes suivantes:#include <stdio.h> #include "factorielle.h" ...
L'option -c de gcc permet de spécifier au compilateur de ne pas faire l'édition de liens, et de ne générer que les fichiers objets .o.% gcc -c -Wall -Werror -ansi -pedantic factorielle.c % gcc -c -Wall -Werror -ansi -pedantic main.c % gcc -Wall -Werror -ansi -pedantic -o factorielle factorielle.o main.o
Les lignes correspondantes aux commandes à exécuter commencent par une tabulation. Lancez la compilation par la commande make (ou make factorielle si la première règle de dépendance ne concerne pas factorielle). Les trois compilations sont automatiquement exécutées. En modifiant la date du fichier factorielle.c, et en recompilant,CC = gcc CFLAGS = -Wall -Werror -ansi -pedantic CFLAGS += -g factorielle: factorielle.o main.o $(CC) $(CFLAGS) -o factorielle factorielle.o main.o factorielle.o: factorielle.c $(CC) -c $(CFLAGS) factorielle.c main.o: main.c $(CC) -c $(CFLAGS) main.c
% touch factorielle.c % makeseule la compilation de factorielle.c et l'édition de liens sont exécutées, le fichier main.c étant resté inchangé.
Partisan du moindre effort (et de la moindre erreur), on peut rassembler l'ensemble des fichiers .o dans une variable OBJ et utiliser la variable automatiqueCC = gcc CFLAGS = -Wall -Werror -ansi -pedantic CFLAGS += -g factorielle: factorielle.o main.o $(CC) $(CFLAGS) -o factorielle factorielle.o main.o .PHONY: clean realclean clean: $(RM) factorielle.o main.o realclean : clean $(RM) factorielle
$@
:
On termine alors la séance de TP par :CC = gcc CFLAGS = -Wall -Werror -ansi -pedantic CFLAGS += -g OBJ = factorielle.o main.o factorielle: $(OBJ) $(CC) $(CFLAGS) -o $@ $(OBJ) .PHONY: clean realclean clean: $(RM) $(OBJ) realclean : clean $(RM) factorielle
% make realclean rm -f factorielle.o main.o rm -f factorielle
Ce document a été traduit de LATEX par HEVEA.