Vous êtes sur la page 1sur 4

GI1 - Correction TD1 programmation structure 2012-2013

Exercice 1 Concatnation de deux chanes de caractres


crire une fonction char* concat_string(char* s1,char* s2) qui prend en arguments deux chanes de
caractres et qui renvoie leur concatnation (il faut allouer un nouveau tableau pour la contenir). On pourra
utiliser le fait quune chane de caractres se termine par le caractre 0 (lentier zero, pas le caractre
reprsentant le chiffre 0).

char * concat_string(char * s1,char * s2)


{
int i=0;
int j=0;
int tmp=0;
int k=0;
char * res;
while(s1[i]!=\0){
i++;
}
while(s2[j]!=\0){
j++;
}
tmp=i+j+1;
res=malloc(tmp *sizeof(char));
for(k=0;k<i;k++)
res[k]=s1[k];
for(;k<tmp;k++)
res[k]=s2[ki];
res[tmp]=\0;
return res;
}

Exercice 2 On se donne une structure livre :


struct lvr{
char titre[20];
int cote;
int prix;
};
On veut crer une bibliothque de plusieurs livres, sous la forme dun tableau de lvr.
crire une fonction struct lvr * init(int n) qui renvoie un tableau de n livres, qui alloue la mmoire ncessaire
et qui initialise les champs 0 ou la chane de caractre vide. Comment utiliser cette fonction dans un main ?
crire une fonction void affiche_bib(int n, struct lvr * b) qui affiche un tableau de n livres.

struct lvr * init(int n) void affiche_bib(int n,struct lvr * bib){


{ int i=0;
int i=0; for(;i<n;i++){
struct lvr * res= (struct lvr *)malloc(n *sizeof(struct printf("titre : %s, cote :%i, prix : %i \n",bib[i].titre,
lvr)); bib[i].cote,bib[i].prix);
for(;i<n;i++){ }
res[i].titre[0]=\0;
res[i].cote=0; int main(){
res[i].prix=0; struct lvr* bib = init(2);
} aff_lvr(bib[0]);
return res; aff_lvr(bib[1]);
} }

b) crire une fonction void echange_lvr(int i, int j, struct lvr * bib) qui fait lchange des livres dindice i et j
dans le tableau bib.

1
void echange_lvr(int i, int j, struct lvr * bib){
struct lvr tmp;
tmp = bib[i];
bib[i]=bib[j];
bib[j]=tmp;
}

Exercice 3 Somme et produit de deux polynmes


On reprsente toujours un polynme par un tableau de double. Mais on enrobe le tout dans une structure pour
stocker le degr en mme temps :
struct polynome
{
int d ;
double _ t ;
};

crire des fonctions :


struct polynome _ somme( struct polynome _ P, struct polynome _ Q)
et
struct polynome _ produi t ( struct polynome _ P, struct polynome _ Q),
calculant la somme et le produit de leurs arguments.

struct polynome * somme( struct polynome * P,


struct polynome * Q) {
struct polynome * res=malloc ( sizeof ( struct struct polynome * produit ( struct polynome * P,
polynome ) ) ; struct polynome * Q) {
int i ; struct polynome * res=malloc (sizeof (struct
double * j ; polynome ) ) ;
i f (P>d<Q>d ) { int i, j ;
struct polynome * tmp=P; res>d=P>d+Q>d ;
P=Q; res>t=malloc (( r e s>d+1) * sizeof (double ) ) ;
Q=tmp ; for ( i =0; i<=res>d ; i++) res>t [ i ]=0;
} for ( i =0; i<=P>d ; i ++) {
res>d=P>d ; for ( j =0; j<=Q>d ; j++) r e s>t [ i+j ]+=P>t [ i
res>t=malloc ( (P>d+1) * sizeof (double ) ) ; ] * Q>t [ j ] ;
for (i =0; i<=Q>d ; i++) res>t [ i ]=P>t [ i }
]+Q>t [ i ] ; return res ;
for ( ; i<=P>d ; i++, j++) res>t [ i ]=P>t [ i ] ; }
return res ;
}

Exercice 4 Pile
Une pile est une structure de donne dans laquelle on peut rentrer des lments, puis les ressortir dans lordre
inverse. Nous allons raliser une pile dentiers avec des tableaux. Une premire mthode consiste stocker tous
les entiers dans un tableau, et tout recopier dans un tableau plus grand dune case lorsque lon veut ajouter un
lment, et dans un tableau plus petit dune case lorsque lon veut enlever un lment. Par exemple, on travaille
avec la structure :

struct pi l e_s impl e


{
int t a i l l e ;
int * t ;
};

a) crire des fonctions


void empi le ( int x , struct pi l e_s impl e * p i l e )
et
int d e p i l e ( struct pi l e_s impl e * p i l e )
Pour depile on suppose quon ne lappellera jamais quand la pile est vide.
a)

2
void empile ( int x , struct pil e_s impl e * p i l e ) { int d e p i l e ( struct pi l e_s impl e * p i l e ) {
int * t ; int * t ;
int i ; int x ;
t=mal loc ( ( p i l e>t a i l l e +1) * ( s izeof ( int ) ) int i ;
); x=p i l e>t [ p i l e>t a i l l e 1] ;
for ( i =0; i<p i l e>t a i l l e ; i++) t [ i ]=p i l e>t p i l e>t a i l l e ;
[i]; t=mal loc ( p i l e>t a i l l e * ( sizeof ( int ) ) ) ;
t [ i ]=x ; for ( i =0; i<p i l e>t a i l l e ; i++) t [ i ]=p i l e>t
p i l e>t a i l l e ++; [i];
f r e e ( p i l e>t ) ; f r e e ( p i l e>t ) ;
p i l e>t=t ; p i l e>t=t ;
} return x ;}
Maintenant, cela est trs inefficace puisque lon recopie toute la pile chaque opration. Il est plus astucieux de
garder un tableau partiellement rempli. Lorsquon dborde, plutt que dallouer un tableau dune case plus
grand, on alloue un tableau deux fois plus grand. Lorsque lon dpile, on ne recopie dans un tableau plus petit
que quand le tableau est aux trois quarts vide, auquel cas on divise sa taille par deux. On travaille donc avec le
type suivant :
struct pi l e_amor t i e {
int t a i l l e ;
int n ;
int * t ;
};

taille reprsente toujours le nombre dlments du tableau t, tandis que n reprsente le nombre de cases
effectivement remplies dans t. Au-del de la nme case, il y a du vide que lon peut remplir.
b) Rcrire les fonctions empile et depile pour des struct pile_amortie.
b)
void empi le ( int x , struct pi l e_amor t i e * p i l e int d e p i l e ( struct pi l e_amor t i e * p i l e ) {
){ int x ;
i f ( p i l e>t a i l l e==p i l e>n ) { p i l e>n;
int * t ; x=p i l e>t [ p i l e>n ] ;
int i ; i f ( p i l e>n<=p i l e>t a i l l e / 4 ) {
p i l e>t a i l l e *=2; int * t ;
t=mal loc ( ( p i l e>t a i l l e ) * ( s izeof ( int ) ) ) ; int i ;
for ( i =0; i<p i l e>n ; i++) t [ i ]=p i l e>t [ i ] ; p i l e>t a i l l e /=2;
f r e e ( p i l e>t ) ; t=mal loc ( p i l e>t a i l l e * ( s izeof ( int ) ) ) ;
p i l e>t=t ; for ( i =0; i<p i l e>n ; i++) t [ i ]=p i l e>t [ i ] ;
} f r e e ( p i l e>t ) ;
p i l e>t [ p i l e>n]=x ; p i l e>t=t ;
p i l e>n++; }
} return x ;
}

Exercice 5 Files FIFO


Une file FIFO (First In, First Out), est une structure de donnes dans laquelle on peut empiler des lments, puis
les dpiler dans le mme ordre. Par exemple, si partir dune file vide, on empile 1, 10, 6 et 11, puis que lon
dpile quatre fois, on obtient dabord 1 puis 10, puis 6 et enfin 11. On va voir une mthode pour implmenter
une file, base sur une liste simplement chaine.
Lide est de maintenir non seulement un pointeur vers le dbut de la liste, mais aussi vers la fin. Pour empiler
un lment, on lajoute la fin de la liste, tandis que pour dpiler, on retire llment du dbut de la liste. On
utilise par exemple les types suivants :struct Li s t e
{
int v a l eur ;
struct Li s t e _ suivant ;
};
struct Fi l e {
struct Li s t e _ debut ;
struct Li s t e _ f i n ;
};

3
crire une fonction struct File * alloue_file(void) qui cre une file vide.

struct Fi l e _ a l l o u e_f i l e ( void ) {


struct Fi l e * r=mal loc ( s izeof ( struct Fi l e ) ) ;
r>debut=NULL;
r>f i n=NULL;
return r ;

crire une fonction int est_vide(struct File * f) qui teste si une file est vide.

int es t_vide ( struct Fi l e * f ) {


return f>debut !=NULL;
}

crire une fonction void empile(int x, struct File * f) qui empile lentier x la fin de la file f.

void empile ( int x , struct File * f ) {


struct Li s t e _ l=mal loc ( s izeof ( struct Fi l e ) ) ;
l>suivant=NULL;
l>v a l eur=x ;
i f ( f>f i n ) {
f>f in>suivant=l ;
f>f i n=l ;
} el se {
f>f i n=l ;
f>debut=l ;
}
}

crire une fonction int depile(struct File * f) qui retire de la file f son premier lment, et le renvoie en rsultat.

int d e p i l e ( struct Fi l e * f ) {
a s s e r t ( f>debut !=NULL) ;
int x=f>debut>v a l eur ;
struct Li s t e _ tmp=f>debut>suivant ;
f r e e ( f>debut ) ;
i f ( f>debut==f>f i n ) {
f>debut=NULL;
f>f i n=NULL;
} el se f>debut=tmp ;
return x ;
}

crire une fonction void detruit_file(struct File * f) qui dsalloue une file.
void d e t r u i t_f i l e ( struct Fi l e * f ) {
while ( f>debut ) d e p i l e ( f ) ;
free(f);
}