Aide exercice informatique C :

Aide exercice informatique C : - C - Programmation

Marsh Posté le 13-01-2012 à 22:42:19    

Bonsoir à tous,  
 
Je révise mon partiel d'informatique en C et je suis pas loin de détruire mon écran avec une batte cloutée dans la mesure où mon programme n'a pas vraiment envie de faire ce que je veux ...
 
Voici l'énoncé de l'exercice :
 
 http://opus.grenet.fr/dokeos/inpg/ [...] BIBLIOVIRT
 
En gros là je suis bloqué sur les questions 7 et 8  ... Je vous transmet en dessous mon code, qui ne me parait pas faux. Sur code block, j'arrive à le compiler mais l'écran est noir et aucun signe de réponse ... Je suppose que mes fautes sont sur les fonctions inversetab et tri ... peut être sur adressemin mais ça m'étonnerait quand même ! Le main est juste un test des fonctions !
 
 
 
int* adressemin(int tab[], int nb)  {
 
    int* p = tab ; int min = *p ; int* adresse = tab ;
 
    for (p=tab+1 ; p=tab + nb ; p++) {
 
    if (min> *p) { min = *p ; adresse = p ;}
 
 
    } return adresse ;}
 
int indicemin(int tab[] , int nb) {
 
int i ; int indice = 0 ; int min = tab[0];
 
for (i=1;i<nb;i++) { if (min>tab[i]) {indice=i;
}
 
} return indice ; }
 
 
int echangeentier (int*a, int *b) {
 
int transit = *a ;
*a = *b ;
*b = transit ;
 
 
 
}
 
void inversetab(int tab[], int nb){
 
 
int* debut = NULL ;
int* fin = tab+nb ;
 
 
for (debut=tab ; debut>fin  ; debut++) {
 
echangeentier(debut,fin);
fin=fin -1;
 
}
 
 
}
 
 
void tri(int tab[], int nb) {
 
 
int* k = NULL ;
int* dernierindice = tab+nb ;
 
for (k=tab;k=dernierindice;dernierindice-- ) {
 
    int* p = adressemin(tab,5);
 
echangeentier(p,dernierindice);  }
}
 
main(){
 
 
 
int tab[5] = {1,2,3,4,5} ;
 
 
tri(tab,5);
int i ;
for (i=0;i<5;i++){printf("%d" , tab[i]);}
 
 
}
 
 
Voilà je suis désolé sans le code couleur c'est pas très agréable à lire, mais si vous pouviez m'aider et m'indiquer mes erreurs ça serait vraiment sympa !  
 
Bonne soirée et merci !
 
 
 
 
 
 

Reply

Marsh Posté le 13-01-2012 à 22:42:19   

Reply

Marsh Posté le 14-01-2012 à 00:56:32    

Un exemple de réponse:

Code :
  1. int* adressemin(int tab[], int nb)  {
  2.     int* p   = tab;
  3.     int* fin = tab + nb;
  4.     int* min = p;
  5.     while (++p < fin)
  6.         if (*min > *p)
  7.             min = p;
  8.     return min;
  9. }
  10. int indicemin(int tab[] , int nb) {
  11.     return (adressemin(tab, nb) - tab);
  12. }
  13. void echangeentier(int *a, int *b) {
  14.     int tmp = *a;
  15.     *a = *b;
  16.     *b = tmp;
  17. }
  18. void inversetab(int tab[], int nb) {
  19.     int* deb = tab - 1;
  20.     int* fin = tab + nb;
  21.     while (++deb < --fin)
  22.         echangeentier(deb, fin);
  23. }
  24. void tri(int tab[], int nb) {
  25.     int* sorted = tab + nb;
  26.     while (sorted > tab)
  27.         echangeentier(adressemin(tab, sorted - tab), --sorted);
  28. }


Ce que tu as fait pour le 7 peut aussi marcher, aux erreurs suivantes près:

Citation :

for (debut=tab ; debut>fin  ; debut++) {

mauvais test: c'est debut<fin que tu veux tester
de plus

Citation :

int* fin = tab+nb ;

c'est pas bon: la fin du tableau est en tab+nb-1
 
Bon, ce que tu as fait pour la partie 8 est bourré d'erreurs, mais en s'inspirant un peu de ton code, on pourrait aboutir à:

Code :
  1. void tri(int tab[], int nb) {
  2. int k ;
  3. for (k = nb; k > 0; k-- ) {
  4.     int* p = adressemin(tab,k);
  5.     echangeentier(p, tab+k-1); 
  6.     }
  7. }


 
A+,


Message édité par gilou le 14-01-2012 à 02:22:13

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 14-01-2012 à 10:42:36    

Merci , en gros si je comprend bien, dans la boucle For, on ne met pas une condition d'arrêt mais une condition pour continuer la boucle ? Un peu comme dans un while quoi ?
 
Sinon effectivement ton code est beaucoup plus propre, merci, il faut que je pense à la boucle while pendant mon partiel !
 
Edit : Je suppose également que mes erreurs étaient largement dues à la décrémentation de la variable dernierindice alors que la variable de ma boucle était k. Est-ce qu'il est totalement interdit ou inefficace de décrémenter incrémenter une autre variable que notre variable de parcours dans la boucle ?
 
 
Merci encore pour ton aide !


Message édité par ocelotsnipe le 14-01-2012 à 10:48:02
Reply

Marsh Posté le 14-01-2012 à 11:45:36    

Citation :

Merci , en gros si je comprend bien, dans la boucle For, on ne met pas une condition d'arrêt mais une condition pour continuer la boucle ? Un peu comme dans un while quoi ?


Oui.
Le plus simple, c'est de penser à une boucle de base qui en général a cette forme:
for (i = 0; i < N; i++) { ... }
qui équivaut à
i = 0; while (i < N) { ..; i++;}
Le test i < N est une condition pour continuer la boucle.
 
 

Citation :

Sinon effectivement ton code est beaucoup plus propre, merci, il faut que je pense à la boucle while pendant mon partiel !

Oui enfin bon, je me suis amusé a utiliser délibérément des pointeurs, mais dans un examen ou les boucles for et les indices ne sont pas interdit, plutôt que faire

Code :
  1. void affiche(int tab[], int nb) {
  2.     int* p   = tab - 1;
  3.     int* fin = tab + nb;
  4.     while (++p < fin)
  5.         printf("%d ", *p);
  6.     printf("\n" );
  7. }


il vaut mieux faire  

Code :
  1. void affiche(int tab[], int nb) {
  2.     int i;
  3.     for (i = 0; i < nb; ++i)
  4.         printf("%d ", tab[i]);
  5.     printf("\n" );
  6. }


ça montre à l'examinateur que tu connais en plus des pointeurs et des whiles, et les tableaux et les for.
 
Ce qui est important dans mon code, c'est de comprendre l'arithmétique des pointeurs:
dans indicemin, quand je fais return (adressemin(tab, nb) - tab);
adressemin(tab, nb) - tab n'est pas la différence numérique entre les deux adresse, parce que adressemin(tab, nb) et tab sont tous deux des pointeurs sur des entiers.
 
Quand p et q sont deux pointeurs sur un même type d'objet, avec p <= q, q-p, c'est l'entier n tel que q = p+n  (ça permet d'écrire q = p + (q-p) )
 
Ton code de tri aurait pu s'écrire

Code :
  1. void tri(int tab[], int nb) {
  2. int k ;
  3. for (k = nb; k > 0; --k ) 
  4.     echangeentier(adressemin(tab,k), tab+k-1); 
  5. }


 
1) On cherche le minimum sur le tableau de taille k: adressemin(tab,k)
2) on échange la valeur de ce minimimum avec celle du dernier élément du tableau, donc d'indice k-1: echangeentier(adressemin(...), tab+(k-1));
3) puisque le dernier élément est trié, on recommence sur le tableau sans son dernier élément, donc en diminuant k de 1 (le --k de la boucle)
4) On a commencé avec le tableau entier (le k = nb de la boucle) on s’arrête quand le tableau à trier n'a plus d'élément à trier (k = 0) d'ou la condition k > 0 de la boucle.
 
Si on veut montrer à son examinateur qu'on est bon, on peut même faire la boucle avec for (k = nb; k > 1; --k ) en justifiant ça par le fait qu'un tableau à un élément est déjà trié et donc que la boucle est inutile lorsque k = 1.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 14-01-2012 à 12:24:34    

Et pour inversetab, il faut penser ainsi au départ:
 

Code :
  1. void inversetab(int tab[], int nb) {
  2.     int* deb = tab;
  3.     int* fin = tab + nb -1;
  4.     while (deb < fin) {
  5.         echangeentier(deb, fin);
  6.         ++deb;
  7.         --fin;
  8.     }
  9. }


On se place au début et a la fin du tableau, on échange le début et la fin, on avance le début d'un cran et on diminue la fin d'un cran
et on recommence tant que deb < fin.
 
Après, on se dit que ça serait bien de virer les ++deb; et --fin; de la boucle pour les mettre juste dans le test de boucle, on regarde ce qu'il faut modifier dans le code si on fait ça, et on voit qu'il faut reculer d'un cran avant le début du tableau au départ (int* deb = tab - 1;) et un cran après la fin du tableau (int* fin = tab + nb;) et on arrive à la forme que je t'ai donnée.
 
Si on veut se faire mousser auprès de l'examinateur, on peut aussi indiquer une autre solution, moins efficace, mais qui est récursive (ce qui montrera qu'on connait la récursivité)
 

Code :
  1. void inversetab(int tab[], int nb) {
  2.     if (nb > 1) {   
  3.         echangeentier(tab, tab+nb-1);
  4.         inversetab(tab+1, nb-2);
  5.     }
  6. }


 
A+,


Message édité par gilou le 14-01-2012 à 12:24:54

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-01-2012 à 20:55:53    

EDIT : En fait ça fonctionne je suis un boulet, il y avait une erreur dans ma fonction swap ! Merci quand même pour votre aide dans les post précédents.
 
 
 
 
 
Bonsoir, je reviens à la charge pour une autre petite question.  
 
 
 
Je rencontre des problèmes dans la dernière question de cette annale :  
http://tdinfo.phelma.grenoble-inp. [...] 200901.pdf
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. void swap(double* ax, double* ay) { double inter;
  4. inter = *ax ;
  5. *ax = *ay ;
  6. *ay = inter  ; }
  7. void tritab(double tab[], int nb ) {
  8. double*p1 ; double *p2 ;
  9. for (p1=tab , p2=tab+1 ; p2<tab+nb ; p1++ , p2++)
  10.   {if (*p1>*p2){swap(p1,p2); }}
  11. if(nb>0) {tritab(tab,nb-1);}
  12. }
  13. }
  14. main() {
  15. double tab1[4]={4,3,2,1} ;
  16. tritab(tab1,4);
  17. int i;
  18. for (i=0;i<4;i++) {printf("%lf", tab1[i]);}
  19. }


 
 
 
Sur le papier, mon code me semble fonctionnel mais une fois compilé ce n'est pas le cas. Mon partiel étant sur papier j'aimerai bien connaître l'erreur dans mon raisonnement. J'ai voulu utiliser la récursivité comme vous me l'avez montré et l'idée de base me semble correcte. J'ai peut être une erreur dans la boucle, je ne sais pas.
 
Pourriez vous me donner un coup de main dans la soirée, mon partiel étant demain matin :D ! Merci.


Message édité par ocelotsnipe le 16-01-2012 à 21:12:08
Reply

Marsh Posté le 16-01-2012 à 23:16:55    

Bonsoir,
Pour ma part, le programme fonctionne et répond aux exigences du sujet.

1.0000002.0000003.0000004.000000Appuyez sur une touche pour continuer...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed