Forum Programmation.c aider moi avec les pointeurs

Posté par  . Licence CC By‑SA.
Étiquettes :
-7
1
oct.
2014

slt les amis , pouvez vous m'aider j'ai un probleme avec mon programme; je doit creer une fonction nommee Trie_selection qui prend un tableau quelconque le trie et affiche le resultat
mais mon programme ne marche pas.
voila mon code source :

#include <stdio.h>
#include <stdlib.h>

float Trie_selection(double *ptr, int Taille)
{
    double *tab;
    int i,j,max;
    double tm;
    tab=malloc(Taille*sizeof(double));
    if (tab==NULL)
    {
        printf(" erreur d'allocation\n");
        return EXIT_FAILURE;
    }
    for (i = 0;i< Taille-1;i++)
    {
        max = i;
        for (j=i+1;j<Taille;j++)
        {
            if (*(ptr+max)< *(ptr+j))
            {
                max=j;
            tm= *(ptr+i);
            *(ptr+i) = *(ptr+max);
            *(ptr+max)= tm;
            }

        }
        for (i=0;i<Taille;i++)
        {
            printf("tab[%d]=%f\n",i+1,*(ptr+i));
        }
    }
}

int main()
{
    int i,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);
    return 0;
}
  • # peut-etre faudrait il en savoir plus ?

    Posté par  . Évalué à 3. Dernière modification le 01 octobre 2014 à 22:22.

    il compile ?
    il s'execute ?

    si tu fais des tableaux simples genre avec 3 elements A/B/C ou 10/20/30
    cela fonctionne-t-il ?

    tu as essayé avec un debugger ?

    et sinon il dit quoi ton cours ?

    chez moi (OSX) ca compile avec 3 Warnings sur les types

    gcc -o mytest test.c
    test.c:34:1: warning: control may reach end of non-void function [-Wreturn-type]
    }
    ^
    test.c:51:20: warning: format specifies type 'float ' but the argument has type 'double *' [-Wformat]
    scanf("%f",tab+i);
    ~~ ~~~~
    %lf
    test.c:59:20: warning: incompatible pointer types passing 'double *
    ' to parameter of type 'double *'; remove & [-Wincompatible-pointer-types]
    Trie_selection(&tab,N);
    ~~~
    test.c:4:30: note: passing argument to parameter 'ptr' here
    float Trie_selection(double *ptr, int Taille)
    ^
    3 warnings generated.

    et ca marche, enfin le programme s'execute sans erreur,
    juste qu'il ne fait pas ce que tu esperes qu'il va faire

    taille du tableau :
    3
    tab[0]:10
    tab[1]:20
    tab[2]:30
    tableau non trie
    tab[0]:0.000000
    tab[1]:0.000000
    tab[2]:0.000000
    tableau trie
    tab[1]=0.000000
    tab[2]=0.000000
    tab[3]=0.000000

  • # epitech

    Posté par  . Évalué à 5.

    toi aussi tu es dans la piscine C à epitech ? ;)

  • # Corrections

    Posté par  . Évalué à 2.

    1. Il faudrait que tu changes tes "%f" en "%lf" car tu utilises des double et pas des float.
    2. Dans ton appel de "Trie_selection", il ne faut pas mettre de "&" car tab est déjà un pointeur.
    3. Ta boucle d'affichage est dans la fonction de tri (et en plus elle affiche alors que le tri n'est pas terminé), il faut faire l'affichage dans la fonction principale.
    4. Dans la fonction Trie_selection, tu alloues un tableau, et tu ne l'utilises pas (il n'y en a pas besoin car tu modifies directement celui créé dans la fonction main grâce au pointeur)

    Après tout ca, il reste sans doute une petite erreur quelque part car il y a un élément qui n'est pas trié avec les nombres que j'ai testés.

    • [^] # Re: Corrections

      Posté par  . Évalué à 2.

      Il faudrait que tu changes tes "%f" en "%lf" car tu utilises des double et pas des float.

      Nope, %f fonctionne pour float et double (en fait %f prend implicitement un double).

      Tu as raison pour le reste, et même non seulement tab est inutilisé dans Trie_selection, mais en plus il n'est libéré.

      Je me demande aussi pourquoi jhonbouda utilise la notation pointeur *(ptr+deplacement) plutôt que la notation tableau ptr[deplacement].

    • [^] # Re: Corrections

      Posté par  . Évalué à 2. Dernière modification le 08 octobre 2014 à 04:24.

      Je te réponds de nouveau, et autant utiliser %f dans printf visiblement ça marche, autant pour scanf pas du tout et tu as raison, il faut %lf.

  • # Commentaire supprimé

    Posté par  . Évalué à 3.

    Ce commentaire a été supprimé par l’équipe de modération.

    • [^] # Re: Suite à une relecture

      Posté par  (Mastodon) . Évalué à 2.

      Salut,

      Pour rebondir suer ce post :

      Je ne sais pas coder en C (enfin, c'est très vieux), mais je suis développeur quand même (en python > no_troll).
      Il y a un truc qui me choque dans le code présenté ci dessus :
      * mélange de casses (camel + '_') pour le nom de fonction !?
      * noms de variables en français et / ou inconsistant (*ptr, c'est quoi ?)
      * … au moins l'indentation à l'air correcte … mais c'est peut-être le site qui l'a faite

      Ça n'est pas grand chose, mais ça pique aux yeux :)

      Autant prendre tout de suit les bonnes habitudes !

      https://linuxfr.org/users/niconico/journaux/beaute-du-code

      Bon courage pour les études !

  • # puisque tout le monde s'y met

    Posté par  . Évalué à 2. Dernière modification le 02 octobre 2014 à 18:55.

    • un malloc sans free c'est une très mauvaise pratique tu devrai être pendu !!!! on écrit un malloc, on gère le free immédiatement après avoir écrit le malloc, c'est pas dans un TODO qu'on fera si on a le temps.

    • pas de majuscule pour les noms de fonctions/variable, bon c'est pas absolu, notamment si c'est des initiales, mais pour une fonction de tri, on va juste dire tri_selection ou triSelection.

    • le tri peu être fait différemment mais ça c'est une autre histoire, et pleins d'autre cours
      sinon tu peux aussi utiliser

    int fct_comparaison(void *ptr_a, void *ptr_b) { 
       double a=*ptr_a, double b=*ptr_b; 
       return a<b ? -1 : a==b ? 0 : 1 ; 
    }
    qsort( tab, taille, sizeof(double), fct_comparaision );

    mais c'est tricher ;)

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

  • # Il faut apprendre à respecter les règles !

    Posté par  . Évalué à 0.

    aider aidez moi avec les pointeurs

    je doit dois creer créer une fonction

    Je n'ai même pas regardé ton source… Quand je vois à quel point tu ne respectes pas les règles de grammaire que tu as pourtant dû apprendre et réviser pendant des années et des années, tu vas avoir énormément de mal à te faire comprendre d'un compilateur.

  • # Quelques commentaires additionnels

    Posté par  . Évalué à 3.

    Salut,

    En plus des commentaires que les gens t'ont donné, j'en rajoute une couche. :-)

    1. 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…
    2. 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.
    3. scanf est 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'utiliser fgets et strtol à la place (je donne un exemple en bas).
    4. 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).
    5. Tu imbriques une boucle for dans une autre boucle for, ce qui fait que tu mélanges les valeurs pour la variable i.
    6. 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).
    7. 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.
    8. 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>
    
    float Trie_selection(double *ptr, int Taille)
    {
        int i;
        double *tab = malloc(Taille*sizeof(double));;
        if (tab==NULL)
        {
            printf(" erreur d'allocation\n");
            return EXIT_FAILURE;
        }
        for (i = 0;i< Taille-1;i++)
        {
            int max = i;
            int j, ii;
            for (j=i+1;j<Taille;j++)
            {
                if (ptr[max] < ptr[j])
                {
                    double tm = 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]);
            }
        }
    }
    
    int main()
    {
        int i,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);
        return 0;
    }

    Voici le même code, version C99 :

    /* Version C99 -- Attention, les bugs ne sont TOUJOURS PAS corrigés ! */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    float Trie_selection(double *ptr, int Taille)
    {
        double *tab = malloc(Taille*sizeof(double));;
        if (tab==NULL)
        {
            printf(" erreur d'allocation\n");
            return EXIT_FAILURE;
        }
        for (int i = 0;i< Taille-1;i++)
        {
            int max = i;
            for (int j=i+1;j<Taille;j++)
            {
                if (ptr[max] < ptr[j])
                {
                    double tm = ptr[i];
                    ptr[i]    = ptr[max];
                    ptr[max]  = tm;
                    max=j;
                }
    
            }
            for (int i=0;i<Taille;i++)
            {
                printf("tab[%d]=%f\n",i+1,ptr[i]);
            }
        }
    }
    
    int main()
    {
        printf("taille du tableau :\n");
        int N; scanf("%d",&N);
        double* tab=malloc(N*sizeof(double));
        if (tab==NULL)
        {
            printf(" erreur d'allocation\n");
            return(EXIT_FAILURE);
        }
        for (int i=0;i<N;i++)
        {
            printf(" tab[%d]:",i);
            scanf("%f",tab+i);
        }
        printf("tableau non trie\n");
        for (int i=0;i<N;i++)
        {
            printf("tab[%d]:%f\n",i,tab[i]);
        }
        printf("tableau trie\n");
        Trie_selection(&tab,N);
        free(tab);
        return 0;
    }

    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>
    
    void Trie_selection(double *ptr, int Taille)
    {
        double *tab = malloc(Taille*sizeof(double));;
        if (tab==NULL)
        {
            printf(" erreur d'allocation\n");
            exit(EXIT_FAILURE);
        }
        for (int i = 0;i< Taille-1;i++)
        {
            int max = i;
            for (int j=i+1;j<Taille;j++)
            {
                if (ptr[max] < ptr[j])
                {
                    double tm = ptr[i];
                    ptr[i]    = ptr[max];
                    ptr[max]  = tm;
                    max=j;
                }
    
            }
            for (int i=0;i<Taille;i++)
            {
                printf("tab[%d]=%f\n",i+1,ptr[i]);
            }
        }
    }
    
    int main()
    {
        printf("taille du tableau :\n");
        int N; scanf("%d",&N);
        double* tab=malloc(N*sizeof(double));
        if (tab==NULL)
        {
            printf(" erreur d'allocation\n");
            return(EXIT_FAILURE);
        }
        for (int i=0;i<N;i++)
        {
            printf(" tab[%d]:",i);
            scanf("%lf",tab+i);
        }
        printf("tableau non trie\n");
        for (int i=0;i<N;i++)
        {
            printf("tab[%d]:%f\n",i,tab[i]);
        }
        printf("tableau trie\n");
        Trie_selection(tab,N);
        free(tab);
        return 0;
    }

    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.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.