Vous êtes sur la page 1sur 16

Université Mohamed 1er Année 2011/2012

Ecole Nationale des Sciences Appliquées Filière STPI


Oujda Niveau CP2, Semestre 1
Prof. E.M. DAOUDI
Cours programmation en Langage C
Liste d’exercices avec correction : N°3
Très important : Il faut implémenter les programmes proposés pour les tester et
éventuellement les corriger.
Exercice 1: Donner les résultats d’exécution du programme C suivant, justifier vos réponses :
#include<stdio.h>
void somme(int, int, int);
void produit(int, int);
void difference(int, int, int *);
int S,P;
main(){
int x=8, y=7, c;
somme(x,y,S);
printf(" S= %d \n ",S);
/* Solution :
- S=0 : en effet dans la procédure somme() on passe la valeur et non l’adresse de S. */
produit(x,y) ;
printf(" P= %d S= %d \n ",P,S);
/* Solution : P= 0 S=15.
- P=0 : en effet, il n’a y pas de relation entre la variable globale P, et la variable P
déclarée localement dans la procédure produit(). Comme P est une variable globale
alors elle est initialisée à 0 par défaut.
- S=15 : En effet, la variable S utilisé dans la procédure produit() c’est la variable
globale S. Puisque sa valeur est modifiée dans la procédure produit(), cette
modification est prise en compte. */
difference(x,y,&c) ;
printf(" c= %d \n",c);
/* Solution :
- c=1 : en effet, on passe l’adresse de c et non la valeur. */
}
void somme(int x, int y, int S) {
S=x+y;
}
void produit(int x, int y) {
int P;
P=x*y;
S=x+y;
}

______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
void difference(int x, int y, int *z) {
*z=x-y ;
}

Exercice 2: Quelles sont les valeurs affichées par les fonctions printf() dans le programme suivant :
#include<stdio.h>
int n, k ;
void fonction_test(int, int * );
main() {
int k=1, x=2, j;
printf(" k= %d n= %d x= %d j= %d \n ", k, n, x, j);
/* Solution: k= 1, n= 0, x= 2, j= 2293672
- k=1: en effet, k est une variable locale initialisée à 1.
- n=0: Puisque n est une variable globale, elle est initialisée par défaut à 0
- x=2 : en effet, x est une variable locale initialisée à 2.
- j= 2293672: en effet, j est une variable locale non initialisée, elle prend une valeur
“quelconque”.
*/
fonction_test(x, &j);
printf(" k= %d n= %d x= %d j= %d \n ", k, n, x, j);
/* Solution: k= 1, n= 5, x= 2, j= 10
- k=1: en effet, k est une variable locale initialisée à 1.
Attention: Ne pas la confondre avec la variable globale k utilisée dans la procédure
fonction_test().
- n=5: en effet, n est une variable globale. Puisque elle est modifiée dans la
procédure. Cette modification est prise en compte après la sortie de la procédure.
- x=2 : en effet, x est une variable locale initialisée à 2. Dans l’appel la procédure
fonction_test(), on passe la valeur et non l’adresse de x.
- j= 10: en effet, dans l’appel de la procédure fonction_test(), on passe l’adresse de j
(passage par adresse), donc toute modification de j dans la procédure, elle sera
prise en compte à la sortie de la procédure.
*/
}
void fonction_test(int x, int *j) {
int i=3;
n=x+i;
k=8;
x=x+k;
*j=x;
}

______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
Exercice 3 : Soit T un tableau de N éléments de type int.
1. Ecrire un programme qui calcule le nombre d’éléments pairs, le nombre d’éléments impairs
et le nombre d’éléments égaux à 0, du tableau T.
2. Refaire la question 1 en utilisant une procédure.

Solution :
/* Question 1. */
#include<stdio.h>
#define N 100
main() {
int n,i; /* n désigne la taille réelle du tableau. i est une variable de travail */
int nbp=0, nbip=0, nbz=0;
/* nbz : désigne le nombre d’éléments nuls
nbp : désigne le nombre d’éléments pairs
nbip : désigne le nombre d’éléments impairs
*/
int Tab[N];
/* saisir la taille et les éléments du tableau Tab */
printf("Entrer la taille reelle du tableau : ");
scanf("%d",&n);
for(i=0; i<n; i++) {
printf("Entrer Tab[%d] : ", i); /* affiche : Entrer Tab[i] */
scanf("%d", &Tab[i]);
}
for(i=0;i<n;i++) { /* On parcourt tous les éléments du tableau Tab */
if(Tab[i]==0) /* On teste si l’élément courant est nul */
nbz++; /* On incrémente le nombre de zéro par 1*/
else if(Tab[i]%2==0) /* On teste si l’élément courant est pair */
nbp++;
else /* Sinon, l’élément courant est impair */
nbip++;
}
printf("Le nombre de zeros est : %d \n",nbz);
printf("Le nombre d elements pairs est : %d \n",nbp);
printf("Le nombre d elements impairs : %d \n",nbip);
getch();
}
/* Question 2 : */
#include<stdio.h>
#define N 100
void pair_impair(int *, int , int *, int *, int *); /* Déclaration de la procédure */
______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
main() {
int n, i;
int nbp=0,nbip=0,nbz=0;
int Tab[N];
printf("Entrer la taille reelle du tableau : ");
scanf("%d",&n);
for(i=0; i<n; i++) {
printf("Entrer Tab[%d] : ", i);
scanf("%d", &Tab[i]);
}
pair_impair(Tab, n, &nbp, &nbip, &nbz); /* Appel de la procédure */
printf("Le nombre de zeros : %d \n",nbz);
printf("Le nombre d elements pairs : %d \n",nbp);
printf("Le nombre d elements impairs : %d \n",nbip);
getch();
}
void pair_impair(int T[], int n, int *pp, int *ip, int *nz) {
int i;
for(i=0; i<n; i++) {
if(T[i]==0)
*nz=*nz+1;
else if(T[i]%2==0)
*pp=*pp+1;
else
*ip=*ip+1;
}
}

Exercice 4 : Soit T un tableau de n éléments triés par ordre croissant.


1. Ecrire une procédure qui insère (ajoute) un élément dans le tableau en préservant l'ordre des
éléments du tableau.
2. Ecrire une procédure qui effectue la suppression d'un élément du tableau.
3. Ecrire une fonction non récursive qui détermine la position dans le tableau T d’un élément
donné.

Solution:

Question 1:
/* le but est de rajouter dans un tableau trié une valeur donnée. Pour préserver
l’ordre, on doit tout d’abord, chercher la position pour insérer la valeur x.
*/
______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
int cherche_position(int T[],int n, int x) {
int pos;
pos=0;
while ((T[pos]<x) && (pos!=n))
pos=pos+1;
return pos;
}
/* La procédure insertion () suivante, permet d’insérer une valeur x en
préservant l’ordre des éléments du tableau.
Remarque 1 : On doit tout d’abord chercher la position « pos » dans la quelle
on insère x, et ensuite effectue l’insertion de x.
Remarque2 : On doit faire un décalage vers la droite à partir de la position
« pos ».
Remarque 3 : La taille du tableau augmente de 1 puisque on rajoute un élément
dans le tableau.
Remarque 4 : Il faut faire les tests de validité : si n=N, on ne peut pas rajouter
d’éléments dans le tableau : N est la taille maximale.
*/
void insertion(int T[], int *n, int x) {
int j;
int pos;
/*Appel de la fonction cherche_position() pour déterminer la position
d’insertion de x */
pos= cherche_position(T,*n, x) ;
if (pos==*n) /* Pas besoin de faire le décalage*/
T[*n]=x; /* On insère en fin du tableau : en position */
else{ /* On doit faire un décalage vers la droite de la manière suivante: */
/* T[n] =T[n-1], T[n-1] =T[n-2], … , T[pos+1] =T[pos ] */
for (j=*n; j>pos; j--)
T[j]=T[j-1];
T[pos]=x; /* après le décalage, on insère x à sa position dans le tableau */
}
*n=*n+1; /* puisque on a rajouter un élément, la taille augmente de 1 */
}
Question 2:
/* la procédure supression () suivante permet de supprimer un élément d’une
position « pos » donnée
Remarque 1 : Pour ne pas laisser une case vide dans le tableau, on doit faire un
décalage vers la gauche des éléments du tableau à partir de la position « pos »
de la manière suivante :
T[pos]=T[pos+1], T[pos+1]=T[pos+2], …., T[n-2]=T[n-1];
______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
Remarque 2 : Puisque on supprime un élément, la taille du tableau doit
diminuer de 1
*/
void supression(int T[],int *n, int pos ) {
int j;
for (j=pos; j<*n-1; j++) {
T[j]=T[j+1];
}
*n=*n-1;
}

Question 3 :
/* La fonction cherche_position () permet de chercher la position d’une valeur
donnée x.
si x existe dans le tableau, il donne sa position
si non, il donne la position d’insertion de la valeur x */
int cherche_position(int T[],int n, int x) {
int pos;
pos=0;
while ((T[pos]<x) && (pos!=n))
pos = pos+1;
return pos;
}
Un Programme complet : Exemple d’utilisation
#include<stdio.h>
#define N 100
int cherche_position(int *,int ,int );
void insertion(int *, int *, int);
void supression(int *,int *, int );
main() {
int n,pos;
int i,x;
int Tab[N];
printf("Entrer la taille reelle du tableau : ");
scanf("%d",&n);
for(i=0; i<n; i++) {
printf("Entrer Tab[%d] : ",i);
scanf("%d",&Tab[i]);
}
printf("Entrer l'element à rajouter dans le tableau : ");
scanf("%d",&x);
______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
insertion(Tab,&n,x);
/* Affichage pour tests */
for(i=0;i<n;i++) {
printf(" Tab[%d] = %d : \n",i,Tab[i]);
}
printf("Entrer la position de l element a supprimer : ");
scanf("%d",&pos);
supression(Tab,&n,pos );
/* Affichage pour tests */
for(i=0;i<n;i++) {
printf(" Tab[%d] = %d : \n",i,Tab[i]);
}
getch();
}
int cherche_position(int T[],int n, int x) {
int pos;
pos=0;
while ((T[pos]<x) && (pos!=n))
pos = pos+1;
return pos;
}
void insertion(int T[], int *n, int x) {
int j;
int pos;
pos= cherche_position(T,*n, x) ;
if (pos==*n)
T[*n]=x;
else{
for (j=*n; j>pos; j--)
T[j]=T[j-1];
T[pos]=x;
}
*n=*n+1;
}
void supression(int T[],int *n, int pos ) {
int j;
for (j=pos; j<*n-1; j++) {
T[j]=T[j+1];
}
*n=*n-1;
}
______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
Exercice 5: Le but de cet exercice est d’écrire des programmes pour trier, par ordre croissant, les
éléments d’un tableau de type float.
1. Ecrire un programme qui saisi au clavier les éléments d’un tableau tab de type float,
2. Ecrire une fonction nommée pos_max qui retourne la position du plus grand élément d’un
tableau de type float. Exemple pour A=[1, 4, 8, 3, 6, 7], la fonction pos_max retourne 2 qui
est la position du plus grand élément du tableau A.
3. Utiliser la fonction pos_max dans un programme pour trier les éléments du tableau tab.
Solution :
Question 1:
#include<stdio.h>
#define N 100
int pos_max(float *, int ) ;
main() {
int n, i, pos;
float x, memo;
float Tab[N];
/* saisi de la taille et des éléments du tableau Tab */
printf("Entrer la taille reelle du tableau : ");
scanf("%d",&n);
for(i=0;i<n;i++) {
printf("Entrer Tab[%d] : ",i);
scanf("%f",&Tab[i]);
}
/* trie par ordre croissant */
for (i=0;i<n;i++) {
/* appel de la fonction pos_max() qui cherche la position du plus grand
élément dans le sous tableau Tab[0 ; n-i] (contient les éléments en
positions 0 à n-i-1) */
pos = pos_max(Tab,n-i);
/* Puisque on fait un trie par ordre croissant, alors on doit mettre le
plus grand élément trouvé (l’élément en position « pos ») en fin du sous
tableau (en position « n-i-1 »). */
memo=Tab[pos];
Tab[pos]=Tab[n-i-1];
Tab[n-i-1]=memo;
}
for(i=0;i<n;i++) { /* Affichage pour vérification */
printf(" Tab[%d] = %f : \n", i, Tab[i]);
}
getch();
}
______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
int pos_max(float T[], int n) {
float g;
int i, pos;
g=T[0];
pos=0;
for(i=1;i<n;i++) {
if (g<T[i]) {
g=T[i];
pos=i;
}
}
return pos;
}
Exercice 6 :
1. Ecrire une fonction nommée fact() qui calcule la factorielle d’un entier :
a. de manière itérative.
b. de manière récursive.
2. Refaire les questions a et b sous forme de procédures.
3. Ecrire un programme qui demande en entrée un entier n et donne en sortie n! en utilisant la
fonction (procédure) fact().

Solution:
Question 1
a. long fact(int n) { /*fonction non récursive */
int i;
long f=1;
for(i=1;i<=n;i++)
f=f*i;
return f;
}
b. long rfact(int n) { /* fonction non récursive */
int i;
long f=1;
if(n==1)
f=1;
else
f=rfact(n-1)*n;
return f;
}
Question 2
a. void pfact(int n, long *f) { /* procédure non récursive */
int i;
*f=1;
for(i=1; i<=n;i++)
*f=(*f)*i;
}
______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
b.

void rpfact(int n, long *f) { /* procédure récursive */


int i;
if(n==1)
*f=1;
else {
rfact(n-1, f);
*f=(*f)*n;
}
}
Question 3
#include<stdio.h>
long fact(int);
long rfact(int );
void pfact(int, long *);
void rpfact(int, long * );

main() {
int n;
long f1,f2;
double r, rr;

printf("Entrer un entier n :");


scanf("%d",&n);
f1=fact(n); /* Appel de la function fact() */
pfact(n,&f2); /* Appel de la procédure pfact() */
printf("fonction non recursive : %d! = %d \n",n,f1);
printf("procedure non recursive : %d! = %d \n",n,f2);
getch();
}
long fact(int n) { /* fonction non recursive */
int i;
long f=1;
for(i=1; i<=n; i++)
f=f*i;
return f;
}
long rfact(int n) { /* fonction récursive */
int i;
long f=1;
if(n==1)
f=1;
else
f=rfact(n-1)*n;
return f;
}
void pfact(int n, long *f) { /* procédure non récursive */
int i;
*f=1;
for(i=1; i<=n;i++)
*f=(*f)*i;
}
______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
void rpfact(int n, long *f) { /* procédure récursive */
int i;
if(n==1)
*f=1;
else {
rfact(n-1, f);
*f=(*f)*n;
}
}

Exercice 7 : Ecrire une fonction récursive qui calcule la somme S=1.0+1.0/2+…..+1.0/n

Solution :
#include<stdio.h>
double serie(int);
double rserie(int);
main() {
int n;
double r1, r2;
printf("Entrer un entier n :");
scanf("%d",&n);
r1=serie(n);
r2=rserie(n);
printf("fonction non recursive : serie(%d) = %f \n",n,r1);
printf("fonction recursive : rserie(%d) = %f \n",n,r2);
getch();
}
double serie(int n) {
int i;
double s=0;
for(i=1;i<=n;i++)
s=s+1.0/i;
return s;
}
double rserie(int n) {
int i;
double s=0;
if (n==1)
s=1;
else
s=rserie(n-1)+1.0/n;
return s;
}

______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
Exercice 8 : Le but de l’exercice est de calculer xn, avec x de type float et n de type int, en utilisant
moins de multiplications.
1. Quel est le nombre de multiplications pour calculer xn.
2. Ecrire une fonction non récursive qui calcule xn en effectuant n-1 multiplications.
3. Utiliser la fonction précédente dans un programme pour calculer yk avec y et k sont saisis au
clavier.
4. Ecrire une fonction récursive qui calcule xn en effectuant seulement log2(n) multiplications.
5. Refaire la question 4 sous forme d’une procédure.

Solution :
Question 1 :
xn = x*x*….*x
Le nombre de multiplications est égal à (n-1)
Question 2 :
Soit puissance() une fonction non récursive qui retourne xn Elle peut être définie
de la manière suivante :
double puissance(double x, int n) {
int i;
double p=1.0;
for(i=1; i<=n; i++)
p=p*x;
return p;
}
Question 3
#include<stdio.h>
double puissance(double , int );
main() {
int k;
double y, r;
printf("Entrer le reel x :");
scanf("%lf",&y);
printf("Entrer la puissance n :");
scanf("%d",&k);
r=puissance(y,k);
printf("fonction puissance : %f puissance %d = %f \n",y, k, r);
getch();
}

______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
double puissance(double x, int k) { /* définition de la fonction non récursive */
int i;
double p=1.0;
for(i=1;i<=k;i++)
p=p*x;
return p;
}
double rpuissance(double x, int k) { /* définition de la fonction récursive */
if (k==0)
return 1;
else
return x*rpuissance(x,k-1);
}
Question 4
/* On se place dans le cas ou n est une puissance de 2 : n= 2k */
double lpuissance(double x, int n) { /* fonction récursive */
int i;
double p;
if(n==0)
p=1;
else
if (n==2)
p=x*x;
else{
p=puissance(x,n/2);
p=p*p;
}
return p;
}

Question 5:
void ppuissance (double x, int n, double *p) { /* procédure récursive */
int i;
if(n==0)
*p=1;
else
if (n==2)
*p=x*x;
else {
ppuissance(x, n/2, p);
*p=(*p)*(*p);
}
}

______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
Exercice 9: Le but de cet exercice est de calculer, pour une valeur X donnée de type double, la
valeur numérique d'un polynôme de degré n: P(X) = anXn + an-1Xn-1 + ... + a1X + a0. Les valeurs de
n, de X et les coefficients an, ..., a0 et de X sont saisis au clavier.

I. Calcule de P(X) en utilisant explicitement les puissances Xk où k est un entier.


1. Ecrire une fonction nommée PUISSANCE qui calcule Xk, où k est un entier.
2. Ecrire un programme qui :
a. Saisi le degré n du polynôme P(X), les coefficients ai, pour 0≤i≤n, et la valeur de X.
b. Appelle la fonction PUISSANCE pour calculer P(X).
3. Donner le nombre de multiplications que nécessite ce programme.
II. Calcule de P(X), sans calculer explicitement les puissances Xk, en utilisant le schéma de Horner
qui procède de la façon suivante :
P(X) = X(…. X(X(anX + an-1) + an-2)... + a1) + a0
Par exemple pour n=3, P(X) = X(X(a3X + a2) + a1) + a0
1. Ecrire un programme qui calcule P(X) en utilisant le schéma de Horner. Le degré n du
polynôme P(X), les coefficients ai pour 0≤i≤n, et la valeur de X, sont saisis au clavier.
Donner le nombre de multiplications que nécessite ce programme.

Solution :
I. Question I.1 :
double puissance(double x, int k) { /* fonction non récursive */
int i;
double p=1.0;
for(i=1; i<=k; i++)
p=p*x;
return p;
}
ou
double rpuissance(double x, int k) { /* fonction récursive */
if (k==0)
return 1;
else
return x*rpuissance(x, k-1);
}
Question I.2
Solution1: allocation dynamique
#include<stdio.h>
double puissance(double , int ); /* Déclaration de la fonction puissance() */
main() {
int n, i; /* n = degrés du Polynôme */
double x, Px; /* Px =P(x)
double *a; /* un pointeur vers une zone mémoire dans laquelle on
sauvegarde les coefficients du Polynôme */

______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
printf("Entrer le degres du polynome : ");
scanf("%d",&n);
/* Réservation de la mémoire pour n réels double précision */
a=(double *)malloc(n*sizeof(double)); /* Allocation de la mémoire: /*
for(i=0; i<n; i++) { /* saisie des coefficients du polynôme */
printf("Entrer a%d : ",i);
scanf("%lf", (a+i)); /* lecture du coefficient ai */
}
printf("Entrer la valeur de x : ");
scanf("%lf",&x);
Px=0;
for (i=0;i<n;i++) { /* le calcul de P(x)=a0+a1x+ a2x2 + an xn */
Px=Px+(*(a+i))*puissance(x,i); /* Appel de la fonction puissance() */
}
printf(" P(%f) = %f : \n",x,Px); /* affiche la valeur de P(x) */
getch();
}
double puissance(double x, int k) { /* Définition de la fonction puissance() */
int i;
double p=1.0;
for(i=1; i<=k; i++)
p=p*x;
return p;
}

Solution2: en utilisant les tableaux


#include<stdio.h>
#define N 100
double puissance(double , int );
main() {
int n, i;
double x, Px;
double a[N]; /* les éléments du tableau « a » sont les coefficients
du polynôme P */
printf("Entrer le degres du polynome : ");
scanf("%d",&n);
for(i=0; i<n; i++) {
printf("Entrer a%d : ",i);
scanf("%lf",&a[i]); /* saisie des coefficients */
}
printf("Entrer la valeur de x : ");
scanf("%lf",&x);
Px=0;
for (i=0; i<n; i++) {
Px=Px+a[i]*puissance(x,i);
}
______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,
printf(" P(%f) = %f : \n", x, Px);
getch();
}
double puissance(double x, int k) {
int i;
double p=1.0;
for(i=1;i<=k;i++)
p=p*x;
return p;
}

I. Question II.1 :
#include<stdio.h>
#define N 100
main() {
int n, i;
double x, Px;
double a[N];
printf("Entrer le degres du polynome : ");
scanf("%d",&n);
for(i=0; i<=n; i++) {
printf("Entrer a%d : ",i);
scanf("%lf", &a[i]);
}
printf("Entrer la valeur de x : ");
scanf("%lf",&x);
/* calcul de P(X) avec le schéma de Horner
P(X) = X(…. X(X(anX + an-1) + an-2)... + a1) + a0
*/
Px=a[n]*x;
for (i=n-1; i>=1; i--) {
Px=x*(Px+a[i]);
}
Px=Px+a[0];
printf(" P(%f) = %f : \n",x,Px);
getch();
}

______________________________________________________________
« Programmation C », année 2011-2012, ENSAO, Niveau CP2 Semestre I,

Vous aimerez peut-être aussi