UNIVERSITÉ BORDEAUX I Département premier cycle Sciences
Janvier 1995
Notes de cours et de TD autorisées. Autres documents interdits.
Les 3 exercices sont indépendants ; donnez 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.
|
|
Ecrire, en langage C, la fonction integrale , qui effectue ce calcul approché ; on suppose la fonction f écrite par ailleurs. Veiller à spécifier au mieux les paramètres.
Une meilleure approximation est obtenue en remplaçant f, sur [xi xi+1], par la fonction constante égale à :
|
| ||||||||||||||||||||||
#define MAX 20
void f (int *t, int *u, int n) {
int i, j;
for (j = 0; j <= MAX; j++)
u [j] = 0;
for (i = 0; i < n; i++) {
j = t [i];
u [j]++;
}
}
On suppose donné un tableau notes, contenant les dix valeurs
suivantes :
|
f (notes, a, 10) ?
Que calcule, de façon générale, la fonction f ?
Cette fonction comporte une instruction dangereuse : laquelle ? Que faudrait-il ajouter pour rendre cette fonction sûre ?
|
|
double integrale (double a, double b, int n) {
int i;
double x = a, delta = (b - a) / n, s = 0;
for (i = 0; i < n; i++) {
s = s + f (x);
x = x + delta;
}
return s * delta;
}
De nombreuses variantes sont possibles, par exemple, sans utiliser de variable x (mais au prix de multiplications supplémentaires) :
for (i = 0; i < n; i++)
s = s + f (a + i * delta);
La seconde méthode de calcul (plus précise) consiste à remplacer :
|
double integrale (double a, double b, int n) {
int i;
double x = a, delta = (b - a) / n, s = ( f(a) + f(b) ) / 2;
for (i = 1; i < n; i++) {
x = x + delta;
s = s + f (x);
}
return s * delta;
}
Si on ne remarque pas la simplification ci-dessus, on peut écrire aussi, pour éviter de calculer inutilement deux fois f à chaque itération :
double
x = a, delta = (b - a) / n,
s = 0, u = f (a), v;
for (i = 0; i < n; i++) {
x = x + delta;
v = f (x);
s = s + (u + v) / 2;
u = v;
}
|
void suite (long *u, int n) {
int i, j;
u [0] = 1;
for (i = 1; i <= n; i++) {
u [i] = 0;
for (j = 0; j < i; j++)
u [i] = u [i] + u [j] * u [i - j - 1];
}
}
Evidemment, la solution suivante est équivalente :
for (i = 0; i < n; i++) {
u [i + 1] = 0;
for (j = 0; j <= i; j++)
u [i + 1] = u [i + 1] + u [j] * u [i - j];
}
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
La fonction f enregistre, dans le tableau u, le nombre d'occurrences de chaque note dans le tableau t (par exemple pour préparer un histogramme).
L'instruction dangereuse est j = t [i]; u [j]++ , car elle suppose que le tableau t ne contient que des entiers entre 0 et 20 ; des fautes de saisie peuvent alors entraîner un comportement dangereux (ou un "plantage") du programme. Il est conseillé d'écrire plutôt :
j = t [i];
if (j >= 0 && j <= MAX)
u [j]++;