Tri d'un tableau

aurel94 Messages postés 73 Date d'inscription   Statut Membre Dernière intervention   -  
armasousou Messages postés 1268 Date d'inscription   Statut Membre Dernière intervention   -
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 !



A voir également:

18 réponses

armasousou Messages postés 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
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   Statut Membre Dernière intervention   1
 
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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
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   Statut Membre Dernière intervention   1
 
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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
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   Statut Contributeur Dernière intervention   1 846
 
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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
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   Statut Contributeur Dernière intervention   1 846
 
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   Statut Membre Dernière intervention   1
 
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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
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   Statut Membre Dernière intervention   1
 
#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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
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   Statut Membre Dernière intervention   1
 
#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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
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   Statut Membre Dernière intervention   1
 
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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
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   Statut Contributeur Dernière intervention   1 846
 
Nop, int tab[taille] ça causera un warning...
0
armasousou Messages postés 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
Pas si taille est declaré comme ça:

#define TAILLE = 5;
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
Vi, je me suis corrigé après xD j'utilise quasi jamais ces "variables" ^^
0
aurel94 Messages postés 73 Date d'inscription   Statut Membre Dernière intervention   1
 
nan c'est pas la solution , il y a encore un soucis ... il m'affiche encore 21 etc ...
0
armasousou Messages postés 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
C/c ton code à chaque fois stp
0
aurel94 Messages postés 73 Date d'inscription   Statut Membre Dernière intervention   1
 
#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 1268 Date d'inscription   Statut Membre Dernière intervention   83
 
Pour faire une variable global, fait plutot :
#define taille 5
0