UNIVERSITÉ BORDEAUX I Département premier cycle Sciences
Juin 1995
Polycopié, notes de cours et de TD autorisés.
Autres documents interdits.
Les 3 exercices sont indépendants ; donner des réponses simples et précises : les fonctions C demandées sont très courtes (quelques lignes). Ecrire des généralités, ou copier des fonctions vues en cours ou en TD, vous fera perdre du temps sans vous rapporter aucun point.
|
typedef int nombre [MAX];
Veiller, dans tous les cas, à la qualité des en-têtes
de fonctions.
Note : ici, comme dans le reste de l'exercice, on ne demande aucune conversion d'une base dans une autre.
Comment proposez-vous de traiter le cas où le nombre de chiffres de x+y dépasse MAX ?
struct complexe {double reel, imaginaire; };
et on dispose des fonctions :
struct complexe somme (struct complexe u, struct complexe v); struct complexe produit (struct complexe u, struct complexe v); double module (struct complexe z);Soit f la fonction définie par f(z) = z2+c , où c désigne une constante complexe, et soit zn la suite définie par la récurrence :
|
Note : veiller à bien spécifier les paramètres de cette fonction.
void decompose (long n) {
long d;
for (d = 2; d * d <= n;)
if (n % d == 0) {
printf (" %d", d);
n = n / d;
}
else d++;
printf (" %d\n", n);
}
Par exemple, si n = 200, cette fonction affiche : 2 2 2 5 5.
Modifier cette fonction pour qu'elle affiche chaque facteur avec sa multiplicité ; par exemple, si n = 200, la fonction modifiée affiche : 2 puissance 3, 5 puissance 2.
void afficher (nombre x) {
int i, j;
for (i = MAX - 1; i > 0 && x [i] == 0; i--);
for (j = i; j >= 0; j--)
printf ("%d", x [j]);
printf ("\n");
}
Variantes et remarques :
void afficher (int *x) ou : void afficher (int x [])
for (; i >= 0; i--) printf ("%d", x [i]);
void somme (nombre z, nombre x, nombre y, int base) {
int i, retenue = 0;
for (i = 0; i < MAX; i++) {
z [i] = x [i] + y [i] + retenue;
if (z [i] >= base) {
retenue = 1;
z [i] = z [i] - base;
}
else
retenue = 0;
}
}
Noter que la base est un paramètre de cette fonction, car il est impossible d'additionner x et y sans connaître la base utilisée.
Le nombre de chiffres de x+y dépasse MAX si et seulement si la fonction se termine avec retenue = 1. Le moyen le plus simple de le signaler à l'utilisateur (qui en fera ce qu'il voudra), est de transformer cette fonction en une fonction booléenne : remplacer void par int dans l'en-tête, et ajouter
return retenue;
à la fin (2 points).
Remarque : certains étudiants n'ont pas utilisé de variable retenue , et ont écrit :
for (i = 0; i < MAX; i++) {
z [i] = x [i] + y [i] + z [i];
if (z [i] >= base) {
z [i + 1] = 1;
z [i] = z [i] - base;
}
else
z [i + 1] = 0;
}
Mais cette solution est fausse pour la première
et la dernière valeur de i :
z [0] n'est pas initialisé, et surtout
z [MAX] n'existe pas.
struct complexe f (struct complexe z, struct complexe c) {
return somme ( produit (z, z), c );
}
int disque (struct complexe z, struct complexe c,
int n, double r) {
int i;
for (i = 1; i <= n; i++)
z = f (z, c);
return ( module (z) <= r );
}
La variante suivante est évidemment correcte, mais peu élégante :
if ( module (z) <= r )
return 1;
else
return 0;
void decompose (long n) {
long d;
int multiplicite;
for (d = 2; d * d <= n; d++) {
multiplicite = 0;
while (n % d == 0) {
multiplicite++;
n = n / d;
}
if (multiplicite > 0)
printf ("%d puissance %d, ", d, multiplicite);
}
if (n > 1)
printf ("%d", n);
printf ("\n");
}
Ne pas oublier if (multiplicite > 0) avant printf.
La solution voisine :
int multiplicite = 0;
for (d = 2; d * d <= n;) {
if (n % d == 0) {
multiplicite++;
n = n / d;
}
else {
if (multiplicite > 0)
printf ("%d puissance %d, ", d, multiplicite);
multiplicite = 0;
d++;
}
}
a été considérée comme correcte, mais en fait
elle pose des problèmes délicats quand on sort de la boucle :
le dernier diviseur d a-t-il bien été affiché,
et sinon est-il égal à n ?