Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

pointeur de fonction


Sujet :

C

  1. #1
    Nouveau membre du Club
    pointeur de fonction
    Bonjour a toutes et a tous ,
    Avec ce code , je souhaite passer l’adresse de la fonction" tri" a la fonction “affiche”pour que cette derniere puisse l'appeler par la suite. Mais je n’y arrive pas , mes yeux sont hs et j’ai besoin de votre aide
    Voici le code :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include <stdio.h>
    #define TAILLE 5
    int tri(int *tab,int tailletab);
    void affiche(int(*pf),int *tab);
     
    int main(void){
    int i;
    int tab[5];
    int(*pf)(int);
    pf=&tri;
     
    printf("Entrez 5 chiffre:\n");
    for(i=0;i<TAILLE;i++)
    scanf("%d",&tab[i]);
    printf("chiffres entré:\n");
    for(i=0;i<TAILLE;i++)
    printf("%d\n",tab[i]);
    affiche(pf,tab);
    return 0;
    }
    /*------------------------------*/
    int tri(int *tab,int tailletab){
     int i,j,temp;
     for(i=0;i<TAILLE;i++)
     {
      for(j=i+1;j<TAILLE;j++)
      {
       if(tab[j]<tab[i])
       {
        temp=tab[i];
        tab[i]=tab[j];
        tab[j]=temp;
       }
      }
     }
     return *tab;
    }
    /*----------------------------*/
    void affiche(int(*pf),int *tab){
     int i;
     int tab1[TAILLE];
     
     printf("Tableau apres classement:\n");
     for(i=0;i<TAILLE;i++)
     {
      printf("%d\n",tab1[i]);
     }
    }

  2. #2
    Expert éminent
    Il faut lire le cours "pointeurs de fonction" : c'est une syntaxe très lourde parce que, à chaque fois, il faut préciser le type de retour et la signature (ta déclaration est bonne mais dans le passage de paramètres il te manque la signature)
    Et donc pour alléger, il faut utiliser un typedef.

    J'ai corrigé ton code, regarde 1 peu si cela t'intéresse j'ai mis les tests qui vont bien, utiliser le type unsigned int/ size_t parce que les indices ne peuvent être négatifs, travailler directement avec le tableau, ...
    Il faut relire ton cours
    Code c :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    #define G_TAB_SIZE 5 /* G_ global */
     
    #define TAB_IS_VALID(tab, tab_size, min) (tab != NULL) && (tab_size > min)
     
     
    /* Function Type */
     
    typedef void (*t_func) (int*, size_t);
     
     
    /* Forward Declarations */
     
    void tab_display(int*, size_t, char*);
     
    void tab_exec_display(t_func, int*, size_t, char*);
     
    void tab_sort(int*, size_t);
     
     
    /************************************ main ***********************************/
     
    int main (int argc, char** argv)
    {
        int tab[G_TAB_SIZE];
        int* tmp_tab;
        t_func my_func;
        size_t count;
     
        my_func = tab_sort;
        tmp_tab = tab; // tab is const
     
        memset(tmp_tab, 0, (G_TAB_SIZE * sizeof(int)));
     
        printf("Entrez %d chiffre%s", G_TAB_SIZE, ((G_TAB_SIZE > 1)? "s :\n": " :\n"));
        for(count=0; count < G_TAB_SIZE; ++tmp_tab, ++count) {
            scanf("%d", tmp_tab);
        }
     
        tmp_tab = tab;
     
        if (G_TAB_SIZE > 1) {
            tab_display(tmp_tab, G_TAB_SIZE, "\n\nchiffres entrés :");
        } else {
            tab_display(tmp_tab, G_TAB_SIZE, "\n\nchiffre entré :");
        }
     
    /*  tab_exec_display(my_func, tmp_tab, G_TAB_SIZE, NULL); */
        tab_exec_display(my_func, tmp_tab, G_TAB_SIZE, "\n\nTableau après classement :");
     
     
        return EXIT_SUCCESS;
    }
     
     
    /*****************************************************************************/
     
    void tab_display(int* tab, size_t tab_size, char* msg){
        if ( TAB_IS_VALID(tab, tab_size, 0) ) {
            size_t count;
     
            if (msg != NULL) { printf("%s\n", msg); }
     
            for(count=0; count < tab_size; ++tab, ++count) {
                printf("%d\n", (*tab));
            }
        }
    }
     
     
    /*****************************************************************************/
     
    void tab_exec_display(t_func func, int* tab, size_t tab_size, char* msg){
        if ((func != NULL) && TAB_IS_VALID(tab, tab_size, 1)) {
            func(tab, tab_size);
            tab_display(tab, tab_size, msg);
        }
    }
     
     
    /*****************************************************************************/
     
    void tab_sort(int* tab, size_t tab_size){
        if (TAB_IS_VALID(tab, tab_size, 1)) {
            size_t i, j;
            int temp;
     
            for(i=0; i < tab_size; ++i) {
                for(j=(i + 1); j < tab_size; ++j) {
                    if (tab[j] < tab[i]) {
                        temp   = tab[i];
                        tab[i] = tab[j];
                        tab[j] = temp;
                    }
                }
            }
        }
    }

  3. #3
    Nouveau membre du Club
    Merci d'avoir pris le temps de me repondre . Ton exemple ne m'aide pas , car trop complexe . Mais tu as raison , je vais etudier le chapitre a fond , ca a l'air plus balaise que je le pensais . Bon dimanche

  4. #4
    Expert confirmé
    Bonjour,
    • Ligne 3, 22 et 36 : Pourquoi ta fonction tri() retourne-telle int? Pourquoi retourner le premier élément du tableau? Ne rien retourner et donner un type retour void est préférable.
    • Ligne 9 : Tu écris un pointeur de fonction qui selon toi reçoit un unique paramètre int et retourne un int!
    • Ligne 10 : Tu lui affectes l'adresse d'une fonction mais les 2 types ne correspondent pas. La fonction a 2 paramètres! le pointeur devrait peut-être être void (*pf)(int*,int);;
    • Ligne 4 et 39 : Là tu ne sais plus écrire la syntaxe pour un pointeur de fonction, relis ta ligne 9 après l'avoir corrigée;
    • Dans la fonction affiche() tu ne te sers pas de ton pointeur de fonction et tu affiches un tab1[] jamais initialisé. Peut être que tu pourrais appeler ton pointeur de fonction en lui passant les paramètres attendus (*pf)( tab , TAILLE_TAB ); pour lui faire trier le tableau avant de l'afficher.

  5. #5
    Nouveau membre du Club
    Merci beaucoup pour tes explications . Je pense avoir surestimé mes capacités , je vais commencer par étudier les pointeurs de fonction depuis le debut avec ce que je peux glaner ca et la sur le net . Merci

  6. #6
    Expert éminent
    Citation Envoyé par dalfab Voir le message
    • Ligne 4 et 39 : Là tu ne sais plus écrire la syntaxe pour un pointeur de fonction, relis ta ligne 9 après l'avoir corrigée;
    • Dans la fonction affiche() tu ne te sers pas de ton pointeur de fonction et tu affiches un tab1[] jamais initialisé. Peut être que tu pourrais appeler ton pointeur de fonction en lui passant les paramètres attendus (*pf)( tab , TAILLE_TAB ); pour lui faire trier le tableau avant de l'afficher.
    Je l'ai signalé : il manque la signature du pointeur dans son passage de paramètres.

    Mais cela ne sert à rien de pointer ce qu'il ne va pas dans son code : on voit clairement que @chris7522 a galéré et a fait des expérimentations de code.
    C'est pour cela que j'ai préféré corriger son code.

    Parce que, en définitive, malgré que cela s'appelle "pointeur", ce sont quand même des pointeurs ultra simples : on ne les déférence jamais et le C est permissif parce qu'il autorise l'omission de l'opérateur & lorsqu'on prend l'adresse d'une fonction : soit my_func = tab_sort; soit my_func = &tab_sort;
    Mais apparemment, @chris7522 ne maîtrise pas la notion de typedef et ne sait pas travailler avec le C99, le type size_t

  7. #7
    Nouveau membre du Club
    Comment pourrai je maitriser toutes ces choses puisque j'ai commencé le C en mai de cette année . Et pour compliquer un peu les choses , j'ai 48 ans et je suis defficient visuel . Ceci etant dit foetus , je te suis reconnaissant d'avoir prit le temps de toutes ces explications . Je ne suis pas sur qu'a ta place ,j'aurai ete aussi genereux . Donc merci a toi

###raw>template_hook.ano_emploi###