Tri d'un tableau

Fermé
aurel94 Messages postés 73 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 1 décembre 2013 - 17 nov. 2012 à 13:22
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 - 18 nov. 2012 à 20:21
Bonjour,
Voila je dois faire un programme sous Geany (avec les contraintes de mon école) . Il faut écrire une fonction indiceInsert qui étant donné un tableau de flottant "tab" de taille "taille" contenant "nbE1" éléments triés par ordre croissant et un flottant f , retourne l'indice auquel f doit être inséré pour que le tableau reste trié . Si le tableau est plein ou si l'élément est déja présent , la fonction retourne la valeur -1 .

Voila le programme que je propose avec un test dans la fonction main :
#include <cini.h>

int indiceInsert (float tab[] , int taille , float f) {
int i=0, nbe1 ;
nbe1=taille ;
while (tab[i]<f && i<taille) {
i = i++ ;
}
nbe1 = nbe1++ ;
if(tab[i] == f && nbe1>taille) {
return (-1) ;
}
else {
return (i) ;
}
}

int main () {
int test ;
float tab1 [] = {1,2,3,4} ;
test = indiceInsert (tab1 , 5 , 5) ;
if (test==-1) {
printf ("le tableau est trop grand ou la valeur est déja contenu") ;
}
else {
printf ("l'élément ce trouve à la place : %d" , test ) ;
}
return 0 ;
}




2 problèmes :
- 2 warning du type : warning: operation on `i' may be undefined sur i et nbE1 et quand je remplace i = i++ par i=i+1 sa marche (pourquoi ? c'est un mystère ...)
-Quand sa compile bien après remplacement , le programme m'affiche la taille du tableau et pour une valeur très très grande il m'affiche 12 :O

Bref j'ai besoin de votre aide !



18 réponses

armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
Modifié par armasousou le 17/11/2012 à 13:37
Les valeurs élévées sont clasique de l'affichage de la valeur d'un pointeur ^^
On évite de faire plusieurs return dans une fonction, ici on peut en faire qu'un avec un ternaire.

Je vais c/c le code sur mon geany et je te dirai ou ça coince :)

Edit: sans stdio et stdlib, tu vas avoir du mal par contre.
Reedit : i=i++ est incohérent, soit tu met i++; soit i=i+1; ^^

Ps: ta façon de mettre les accolades, je trouve ça deguelasse :/ Essaye de t'inspirer des normes.
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
17 nov. 2012 à 13:40
J'ai pas besoin de regarder le code longtemps au final, tu fais beaucoup d'erreur d'incohérences :

Tu écris "nbe=taille; nbe=nbe+1; si nbe > taille" ... bah forcément qu'il sera plus grand ! ^^

Tu passe en parametre taille = 5 alors que ton tableau fait 4, l'erreur viens surement de là.
0
aurel94 Messages postés 73 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 1 décembre 2013 1
17 nov. 2012 à 14:30
Après correction et vérification le programme fonctionne ;) . Merci :) , je pourrai avoir besoin de toi car l'exo n'est pas fini . Maintenant je dois écrire une fonction distincte qui insert f dans tab si l'élement n'est pas présent et si le tableau n'est pas plein !
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
17 nov. 2012 à 15:18
Tu vas tout au bout du tableau, tu deplace la valeur sur sa case de droite. Autant de fois que necessaire.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
aurel94 Messages postés 73 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 1 décembre 2013 1
17 nov. 2012 à 16:42
j'ai fait ce programme et il y a encore plein d'erreur apparement , je ne maitrise pas encore les fonctions :(

#include <cini.h>


int indiceInsert (float tab[] , float f, int taille , int nbe1) {
int i=0 ;
while (tab[i]<f && i<taille) {
i++ ;
}
nbe1++ ;
if(tab[i] == f || nbe1>taille) {
return (-1) ;
}
else {
return (i) ;
}
}

void inserElt {
int indice = indiceInsert(tab1 , VALEUR , TAILLE , nbe1) , i ;
for (i=nbe1 ; i>=indice ; i--) {
tab[i+1]=tab[i] ;
}
}



int main () {
int taille=5 , nbe1=4 , int j ;
float tab1[]={1,2,4,5} ; f=3.25 ;
printf ("l'indice de la valeur insérée est %f" , indiceInsert(tab1,f,taille,nbe1)) ;
for (j=0 ; j<taille ; j++) {
printf ( "%f\n" , tab1[j] ) ;
}
return 0 ;
}
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
17 nov. 2012 à 17:02
Ca peut pas marcher ^^

Tu déclare ton tableau avec une taille de 4 (indice 0 a 3) mais tu dis "ouais euh, la taille c'est 5 au fait" bah nan, tu vas te taper un seg fault parce que tu touche à de la ram qui t'appartient pas ! :)

Fait comme ça :
int taille = 5 , nbe = 4 ;(si tu veux)
et aprés
int tableau[taille]={1,2,3,4}; // je reserve taille (5) cases mais j'en utilise 4.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 843
17 nov. 2012 à 17:12
int tableau[taille]={1,2,3,4};
Attention à l'utilisation de VLA qui ne fonctionne qu'en C99.
Il vaut mieux, surtout pour un exercice d'école, utiliser l'allocation dynamique classique.
Soit : int *tableau = malloc(4*sizeof(*tableau));
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
17 nov. 2012 à 18:23
VLA ? ^^

Et je pense pas que ce soit une bonne idée d'introduire l'alloc dynamique quand elle a déjà du mal a faire un tri a bulle ...
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 843
17 nov. 2012 à 18:35
VLA = Variable Length Array. C'est un mécanisme apporté par C99. Mais en C89/90, on ne peut pas l'utiliser. Donc à oublier pour un exercice scolaire.

Pour l'allocation dynamique, je suis d'accord. Mais c'est la seule façon d'allouer un tableau à l'exécution...
Soit tu utilises int tableau[TAILLE]; avec #define TAILLE 5
Soit tu utilises int *tableau=malloc(...);
Pas d'alternatives...
Ceci dit, rien n'empêche d'allouer statiquement un grand tableau et de n'en utiliser qu'une partie.
0
aurel94 Messages postés 73 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 1 décembre 2013 1
18 nov. 2012 à 15:12
Voila mon programme (corrigé , recorrigé et rerecorrigé) et pourtant de multiples erreurs persistent :

Voila le programme :

#include <cini.h>


int indiceInsert (float tab[] ,int taille , float f, int nbe1) {
int i=0 ;
while (tab[i]<f && i<taille) {
i++ ;
}
nbe1++ ;
if(tab[i] == f || nbe1>taille) {
return (-1) ;
}
else {
return (i) ;
}
}

void inserElt (indice) {
int i ;
for (i=nbe1 ; i>=indice ; i--) {
tab1[i+1]=tab1[i] ;
}
}



int main () {
int j , nbe1=4 , taille = 5 ;
float tab1[taille]={1,2,4,5} , f=3.25 ;
indice = indiceInsert(tab1 ,taille , f , nbe1) ;
printf ("l'indice de la valeur insérée est : %d" , indiceInsert(tab1,taille,f,nbe1)) ;
inserElt(indice) ;
for (j=0 ; j<taille ; j++) {
printf ( "%f\n" , tab1[j] ) ;
}
return 0 ;
}


Voila les erreurs :


In function `inserElt':
error: `nbe1' undeclared (first use in this function)
note: each undeclared identifier is reported only once for each function it appears in
error: `tab1' undeclared (first use in this function)
In function `main':
error: variable-sized object may not be initialized
warning: excess elements in array initializer
warning: (near initialization for `tab1')
warning: excess elements in array initializer
warning: (near initialization for `tab1')
warning: excess elements in array initializer
warning: (near initialization for `tab1')
warning: excess elements in array initializer
warning: (near initialization for `tab1')
error: `indice' undeclared (first use in this function)
error: expected `)' before numeric constant
error: too few arguments to function `indiceInsert'
note: declared here
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
18 nov. 2012 à 15:32
Ta faction inserElt ne connait pas nbe1, il faut que tu le passe en parametre, de même pour tab1.
Pareil tu fais un "indice=" alors qu'a aucun moment tu ne declare "indice".
0
aurel94 Messages postés 73 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 1 décembre 2013 1
18 nov. 2012 à 16:43
#include <cini.h>


int indiceInsert (float tab[] ,int taille , float f, int nbe1) {
int i=0 ;
while (tab[i]<f && i<taille) {
i++ ;
}
nbe1++ ;
if(tab[i] == f || nbe1>taille) {
return (-1) ;
}
else {
return (i) ;
}
}

void inserElt (int indice , int neb1 , float tab1 ) {
int i ;
for (i=nbe1 ; i>=indice ; i--) {
tab1[i+1]=tab1[i] ;
}
}



int main () {
int j , nbe1=4 , taille = 5 , indice ;
float tab1[taille]={1,2,4,5} , f=3.25 ;
indice = indiceInsert(tab1 ,taille , f , nbe1) ;
printf ("l'indice de la valeur insérée est : %d" , indiceInsert(tab1,taille,f,nbe1)) ;
inserElt(indice , nbe1 , tab1) ;
for (j=0 ; j<taille ; j++) {
printf ( "%f\n" , tab1[j] ) ;
}
return 0 ;
}

gcc -DFONTFILE='"/usr/share/libcini/font.ttf"' -Wall -O -o "td8 exo 3" "td8 exo 3.c" -lm -lcini (dans le dossier : /home/eleve)
Compilation échouée.
td8 exo 3.c: In function `inserElt':
td8 exo 3.c:20:9: error: `nbe1' undeclared (first use in this function)
td8 exo 3.c:20:9: note: each undeclared identifier is reported only once for each function it appears in
td8 exo 3.c:21:7: error: subscripted value is neither array nor pointer
td8 exo 3.c:21:17: error: subscripted value is neither array nor pointer
td8 exo 3.c: In function `main':
td8 exo 3.c:29:2: error: variable-sized object may not be initialized
td8 exo 3.c:29:2: warning: excess elements in array initializer
td8 exo 3.c:29:2: warning: (near initialization for `tab1')
td8 exo 3.c:29:2: warning: excess elements in array initializer
td8 exo 3.c:29:2: warning: (near initialization for `tab1')
td8 exo 3.c:29:2: warning: excess elements in array initializer
td8 exo 3.c:29:2: warning: (near initialization for `tab1')
td8 exo 3.c:29:2: warning: excess elements in array initializer
td8 exo 3.c:29:2: warning: (near initialization for `tab1')
td8 exo 3.c:32:2: error: incompatible type for argument 3 of `inserElt'
td8 exo 3.c:18:6: note: expected `float' but argument is of type `float *'

toujours pas ...
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
18 nov. 2012 à 16:57
Met
int taille = 5;
int tab[5] plutot que int tab[taille].

et dans ta 2d fonction, t'as oublié les crochets sur le tableau.
0
aurel94 Messages postés 73 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 1 décembre 2013 1
18 nov. 2012 à 17:23
#include <cini.h>


int indiceInsert (float tab[] ,int taille , float f, int nbe1) {
int i=0 ;
while (tab[i]<f && i<taille) {
i++ ;
}
nbe1++ ;
if(tab[i] == f || nbe1>taille) {
return (-1) ;
}
else {
return (i) ;
}
}

void inserElt (int indice , int nbe1 , float tab1[] ) {
int i ;
if (indice !=-1) {
for (i=nbe1 ; i>=indice ; i--) {
tab1[i+1]=tab1[i] ;
}
}
}



int main () {
int j , nbe1=4 , taille = 5 , indice ;
float tab1[5]= {1,2,4,5} , f=3.25 ;
indice = indiceInsert(tab1 ,taille , f , nbe1) ;
printf ("l'indice de la valeur insérée est : %d" , indiceInsert(tab1,taille,f,nbe1)) ;
inserElt(indice , nbe1 , tab1) ;
for (j=0 ; j<taille ; j++) {
printf ( "%f\n" , tab1[j] ) ;
}
return 0 ;
}



Il compile (yessssssssssssssss) mais me met :
l'indice de la valeur insérée est : 21.000000
2.000000
4.000000
4.000000
5.000000

WTF ? :p
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
18 nov. 2012 à 18:09
Tu vas avoir un soucis là

int indiceInsert (float tab[] ,int taille , float f, int nbe1) {
int i=0 ;
while (tab[i]<f && i<taille) {
i++ ;
}
nbe1++ ; <===================================
if(tab[i] == f || nbe1>taille) {
return (-1) ;
}
else {
return (i) ;
}
}

En C, il y a une notion de portée de variable, ta variable nbe1 reprend la valeur que tu lui a passé (nbe1 du main) MAIS ce n'est PAS la même variable, c'est une COPIE. Du coup, ton nbe1++ (donc nbe1 = 5) est vrai que dans indiceInsert. Après, ton nbe1 (du main) est repris comme base et il est égale à 4 point barre :)

Pour contrer ça, il faut utiliser des pointeurs. c'est une variable qui vaut l'adresse (en ram) d'une valeur.
Ca s'écris comme ça :
int* p = &nbe1; /* Je declare p comme "pointeur d'entier" (* = pointeur) et il est égale à l'adresse (en ram) de nbe1 */

Si tu veux modifier nbe1 du main via une fonction, il faut lui passer le pointeur.

Du coup ton main ça serai genre

int nbe1 = 4 ;
int* pnbe1 = &nbe1;

indice=indiceinsert(..,..,..., pnbe1);


et donc ta fonction change aussi,
déjà elle prend en parametre non pas int nbe1 mais int* choisi_un_nom

ensuite, si tu veux tester la valeur pointé par un pointeur, faut mettre une etoile, tu peux le voir comme ça :

pnbe1 = &nbe1; //pnbe1 vaut l'adresse de nbe1
*pnbe1 = nbe1 // etoile pnbe1 vaut la même chose que nbe1.
0
aurel94 Messages postés 73 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 1 décembre 2013 1
18 nov. 2012 à 18:32
Normalement on est pas sensé utiliser les pointeurs ... Car c'est une notion que l'on a pas encore vu . Je peux pas faire autrement ? Comme déclarer nbe1 comme variable globale par exemple ?
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
18 nov. 2012 à 18:53
Oui, mais alors fait pareil pour taille et tu peux faire int tab[taille] du coup
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 843
18 nov. 2012 à 19:31
Nop, int tab[taille] ça causera un warning...
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
18 nov. 2012 à 19:40
Pas si taille est declaré comme ça:

#define TAILLE = 5;
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 843
18 nov. 2012 à 19:50
Yes. Mais je n'avais pas vu que tu lui avais dit de mettre un #define.
Dans ce cas, TAILLE ne sera pas une variable. Mais effectivement ça marchera.
La syntaxe est :
#define TAILLE 5
Surtout pas de point virgule, et pas de signe égal.
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
18 nov. 2012 à 20:21
Vi, je me suis corrigé après xD j'utilise quasi jamais ces "variables" ^^
0
aurel94 Messages postés 73 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 1 décembre 2013 1
18 nov. 2012 à 18:59
nan c'est pas la solution , il y a encore un soucis ... il m'affiche encore 21 etc ...
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
18 nov. 2012 à 19:29
C/c ton code à chaque fois stp
0
aurel94 Messages postés 73 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 1 décembre 2013 1
18 nov. 2012 à 19:44
#include <cini.h>
int nbe1=4 , taille=5 ;

int indiceInsert (float tab[] ,int taille , float f, int nbe1) {
int i=0 ;
while (tab[i]<f && i<taille) {
i++ ;
}
nbe1++ ;
if(tab[i] == f || nbe1>taille) {
return (-1) ;
}
else {
return (i) ;
}
}

void inserElt (int indice , int nbe1 , float tab1[] ) {
int i ;
if (indice !=-1) {
for (i=nbe1 ; i>=indice ; i--) {
tab1[i+1]=tab1[i] ;
}
}
}



int main () {
int j , indice ;
float tab1[5]= {1,2,4,5} , f=3.25 ;
indice = indiceInsert(tab1 ,taille , f , nbe1) ;
printf ("l'indice de la valeur insérée est : %d" , indiceInsert(tab1,taille,f,nbe1)) ;
inserElt(indice , nbe1 , tab1) ;
for (j=0 ; j<taille ; j++) {
printf ( "%f\n" , tab1[j] ) ;
}
return 0 ;
}
0
armasousou Messages postés 1267 Date d'inscription dimanche 16 août 2009 Statut Membre Dernière intervention 30 décembre 2016 83
18 nov. 2012 à 19:49
Pour faire une variable global, fait plutot :
#define taille 5
0