En plus des commentaires que les gens t'ont donné, j'en rajoute une couche. :-)
Si tu utilises gcc ou clang, je te conseille fortement l'utilisation de ces options de compilation sur la ligne de commande : -Wall -Wextra -pedantic -Werror. Si tu apprends sous Windows, Visual C++ peut aussi se régler avec un niveau d'avertissement maximal. Pour les projets qu'on donne aux élèves en fac/IUT/école d'ingé, il y n'y a jamais de bonne raison de laisser un warning/avertissement du compilateur traîner. Dans la vraie vie non plus d'ailleurs, m'enfin parfois on a pas le choix...
scanf retourne une valeur qui peut-être utilisée pour savoir s'il y a eu une erreur de lecture. J'avais oublié de rentrer la taille du tableau avant de lire les nombres, et du coup scanf a gobé mon "10.4" goulûment sans sourciller. Et du coup il a évidemment tronqué l'entrée dans stdin.
sscanf, fscanf, etc., sont « sûres » en supposant que les entrées soient déjà formatées comme il faut (hint: en C il ne faut jamais assumer quoi que ce soit sauf si on maîtrise la chaîne complète de production/consommation — et encore, même ainsi il faut rester vigilant).
Tu imbriques une boucle for dans une autre boucle for, ce qui fait que tu mélanges les valeurs pour la variable i.
Je te conseille fortement d'utiliser C99. Si ton prof dit que c'est pas autorisé, je te conseille de quand même insister, car la norme C99 a 15 ans, et il serait temps que les profs se mettent à jour (je ne parle même pas de C11).
Même si tu dois rester sur du C89 (celui qui est généralement enseigné), il y a plein de façons de rendre ton code plus lisible et plus facile à déboguer.
Utiliser la notation « pointeur » comme tu le fais n'est pas incorrecte, mais comme tu accèdes très clairement à ptr comme à un tableau, la notation indicée me semble plus indiquée.
Voici une version utilisant la notation C89 pour déclarer les variables au plus près de leur utilisation dans le code. Je n'ai pas touché à la logique du code lui-même, sauf pour la boucle imbriquée pour pouvoir lui donner un indice différent de i (qui est un bug hein !). J'ai aussi transformé les accès « pointeur » en accès « tableau » pour que ce soit plus lisible :
/* Version pure C89 -- Attention, tous les bugs sont restés ! */#include <stdio.h>#include <stdlib.h>floatTrie_selection(double*ptr,intTaille){inti;double*tab=malloc(Taille*sizeof(double));;if(tab==NULL){printf(" erreur d'allocation\n");returnEXIT_FAILURE;}for(i=0;i<Taille-1;i++){intmax=i;intj,ii;for(j=i+1;j<Taille;j++){if(ptr[max]<ptr[j]){doubletm=ptr[i];ptr[i]=ptr[max];ptr[max]=tm;max=j;}}for(ii=0;ii<Taille;ii++){printf("tab[%d]=%f\n",ii+1,ptr[ii]);}}}intmain(){inti,N;double*tab;printf("taille du tableau :\n");scanf("%d",&N);tab=malloc(N*sizeof(double));if(tab==NULL){printf(" erreur d'allocation\n");return(EXIT_FAILURE);}for(i=0;i<N;i++){printf(" tab[%d]:",i);scanf("%f",tab+i);}printf("tableau non trie\n");for(i=0;i<N;i++){printf("tab[%d]:%f\n",i,tab[i]);}printf("tableau trie\n");Trie_selection(&tab,N);free(tab);return0;}
Voici le même code, version C99 :
/* Version C99 -- Attention, les bugs ne sont TOUJOURS PAS corrigés ! */#include <stdio.h>#include <stdlib.h>floatTrie_selection(double*ptr,intTaille){double*tab=malloc(Taille*sizeof(double));;if(tab==NULL){printf(" erreur d'allocation\n");returnEXIT_FAILURE;}for(inti=0;i<Taille-1;i++){intmax=i;for(intj=i+1;j<Taille;j++){if(ptr[max]<ptr[j]){doubletm=ptr[i];ptr[i]=ptr[max];ptr[max]=tm;max=j;}}for(inti=0;i<Taille;i++){printf("tab[%d]=%f\n",i+1,ptr[i]);}}}intmain(){printf("taille du tableau :\n");intN;scanf("%d",&N);double*tab=malloc(N*sizeof(double));if(tab==NULL){printf(" erreur d'allocation\n");return(EXIT_FAILURE);}for(inti=0;i<N;i++){printf(" tab[%d]:",i);scanf("%f",tab+i);}printf("tableau non trie\n");for(inti=0;i<N;i++){printf("tab[%d]:%f\n",i,tab[i]);}printf("tableau trie\n");Trie_selection(&tab,N);free(tab);return0;}
Enfin, en utilisant les options que je préconise au-dessus, je me fais engueuler par gcc :
$ gcc -std=c99 -Wall -Werror -Wextra -pedantic -o tri99 tri99.c
tri99.c: In function ‘main’:
tri99.c:46:9: error: format ‘%f’ expects argument of type ‘float *’, but argument 2 has type ‘double *’ [-Werror=format=]
scanf("%f",tab+i);
^
tri99.c:54:5: error: passing argument 1 of ‘Trie_selection’ from incompatible pointer type [-Werror]
Trie_selection(&tab,N);
^
tri99.c:4:7: note: expected ‘double *’ but argument is of type ‘double **’
float Trie_selection(double *ptr, int Taille)
^
tri99.c: In function ‘Trie_selection’:
tri99.c:31:1: error: control reaches end of non-void function [-Werror=return-type]
}
^
cc1: all warnings being treated as errors
En regardant chaque erreur sortie par le compilateur, je peux réparer une bonne partie de tes bugs (je garde la forme C99) :
#include <stdio.h>#include <stdlib.h>voidTrie_selection(double*ptr,intTaille){double*tab=malloc(Taille*sizeof(double));;if(tab==NULL){printf(" erreur d'allocation\n");exit(EXIT_FAILURE);}for(inti=0;i<Taille-1;i++){intmax=i;for(intj=i+1;j<Taille;j++){if(ptr[max]<ptr[j]){doubletm=ptr[i];ptr[i]=ptr[max];ptr[max]=tm;max=j;}}for(inti=0;i<Taille;i++){printf("tab[%d]=%f\n",i+1,ptr[i]);}}}intmain(){printf("taille du tableau :\n");intN;scanf("%d",&N);double*tab=malloc(N*sizeof(double));if(tab==NULL){printf(" erreur d'allocation\n");return(EXIT_FAILURE);}for(inti=0;i<N;i++){printf(" tab[%d]:",i);scanf("%lf",tab+i);}printf("tableau non trie\n");for(inti=0;i<N;i++){printf("tab[%d]:%f\n",i,tab[i]);}printf("tableau trie\n");Trie_selection(tab,N);free(tab);return0;}
J'ai remplacé le retour de ta fonction de tri par void (vu que tu ne retournes pas de valeur et que gcc se plaint). Du coup, j'utilise la fonction exit dans ta fonction de tri au lieu du return EXIT_FAILURE. J'ai enlevé le & devant tab dans ton main puisque le compilateur nous dit qu'on passe double ** alors que la fonction de tri prend un double *. J'ai changé %f pour %lf aussi.
Malgré tout ça, il y a de sérieux problèmes de logique liés à l'algorithmique.
# Quelques commentaires additionnels
Posté par lasher . En réponse au message aider moi avec les pointeurs. Évalué à 3.
Salut,
En plus des commentaires que les gens t'ont donné, j'en rajoute une couche. :-)
gccouclang, je te conseille fortement l'utilisation de ces options de compilation sur la ligne de commande :-Wall -Wextra -pedantic -Werror. Si tu apprends sous Windows, Visual C++ peut aussi se régler avec un niveau d'avertissement maximal. Pour les projets qu'on donne aux élèves en fac/IUT/école d'ingé, il y n'y a jamais de bonne raison de laisser un warning/avertissement du compilateur traîner. Dans la vraie vie non plus d'ailleurs, m'enfin parfois on a pas le choix...scanfretourne une valeur qui peut-être utilisée pour savoir s'il y a eu une erreur de lecture. J'avais oublié de rentrer la taille du tableau avant de lire les nombres, et du coup scanf a gobé mon "10.4" goulûment sans sourciller. Et du coup il a évidemment tronqué l'entrée dansstdin.scanfest la fonction du diable, tellement que des gens dédient des pages complètes à son sujet. Je suppose que tes profs te demandent de l'utiliser, mais je te conseille fortement d'utiliserfgetsetstrtolà la place (je donne un exemple en bas).sscanf,fscanf, etc., sont « sûres » en supposant que les entrées soient déjà formatées comme il faut (hint: en C il ne faut jamais assumer quoi que ce soit sauf si on maîtrise la chaîne complète de production/consommation — et encore, même ainsi il faut rester vigilant).fordans une autre bouclefor, ce qui fait que tu mélanges les valeurs pour la variablei.ptrcomme à un tableau, la notation indicée me semble plus indiquée.Voici une version utilisant la notation C89 pour déclarer les variables au plus près de leur utilisation dans le code. Je n'ai pas touché à la logique du code lui-même, sauf pour la boucle imbriquée pour pouvoir lui donner un indice différent de
i(qui est un bug hein !). J'ai aussi transformé les accès « pointeur » en accès « tableau » pour que ce soit plus lisible :Voici le même code, version C99 :
Enfin, en utilisant les options que je préconise au-dessus, je me fais engueuler par
gcc:En regardant chaque erreur sortie par le compilateur, je peux réparer une bonne partie de tes bugs (je garde la forme C99) :
J'ai remplacé le retour de ta fonction de tri par
void(vu que tu ne retournes pas de valeur et quegccse plaint). Du coup, j'utilise la fonctionexitdans ta fonction de tri au lieu dureturn EXIT_FAILURE. J'ai enlevé le&devanttabdans tonmainpuisque le compilateur nous dit qu'on passedouble **alors que la fonction de tri prend undouble *. J'ai changé%fpour%lfaussi.Malgré tout ça, il y a de sérieux problèmes de logique liés à l'algorithmique.