IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

Minimum générique dans un tableau


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Minimum générique dans un tableau
    Bonjour,

    J'ai un exercice à faire mais je suis un peu perdu. Je ne vois pas comment démarrer.
    L'objectif est d'écrire une fonction générique qui calcule la plus petite valeur contenue dans un tableau générique.
    Voici l'exercice:

    1. Déterminer la signature d’une fonction qui prend deux données génériques en argument et qui renvoie la plus petite des deux. En faire un type.
    2. Ecrire une telle fonction générique qui calcule la plus petite valeur entre deux entiers.
    3. Ecrire une telle fonction générique qui calcule la plus petite valeur entre deux chaînes de caractères (il est conseillé d’utiliser la fonction strcmp de string.h).
    4. Déterminer la signature de la fonction min tab qui répond à l’objectif de l’exercice. Elle est paramétrée, entre autres, par un tableau générique et une fonction de calcul de la plus petite valeur entre deux valeurs données.
    5. Donner le corps de la fonction min tab.
    6. En supposant que tab est un tableau d’entiers de taille 64, écrire une suite d’instructions qui calcule et affiche sa plus petite valeur, en utilisant min tab.
    7. En supposant que tab est un tableau de 64 chaînes de caractères et toutes de taille 96, écrire une suite d’instructions qui calcule et affiche sa plus petite valeur, en utilisant min tab.

    Excusez-moi si ça vous parait super simple mais je débute...
    Merci de votre aide !!

  2. #2
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 469
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 469
    Points : 6 102
    Points
    6 102
    Par défaut
    Bonjour,

    Je te conseille d'analyser la documentation de qsort.

    Signature :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void qsort( void *ptr, size_t count, size_t size,
                int (*comp)(const void *, const void *) );
    Exemple d'utilisation :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
     
    int compare_ints(const void* a, const void* b)
    {
        int arg1 = *(const int*)a;
        int arg2 = *(const int*)b;
     
        if (arg1 < arg2) return -1;
        if (arg1 > arg2) return 1;
        return 0;
     
        // return (arg1 > arg2) - (arg1 < arg2); // possible shortcut
        // return arg1 - arg2; // erroneous shortcut (fails if INT_MIN is present)
    }
     
    int main(void)
    {
        int ints[] = { -2, 99, 0, -743, 2, INT_MIN, 4 };
        int size = sizeof ints / sizeof *ints;
     
        qsort(ints, size, sizeof(int), compare_ints);
     
        for (int i = 0; i < size; i++) {
            printf("%d ", ints[i]);
        }
     
        printf("\n");
    }
    Pour ton exercice, il faudra utiliser le même genre de technique avec des void*.
    Remarque : Le type pointeur de fonction de comparaison que tu utiliseras ne sera pas le même que le type du 4e paramètre de qsort, car l'énoncé oblige tes fonctions de comparaison à retourner l'argument le plus petit.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    merci de ta réponse.
    Quand tu dis qu'il faut que j'utilise cette technique avec des void* ça veut dire que j'enlève tous les const ?
    Et pour le 4ème argument de la fonction sort, je ne comprends pas pourquoi je dois le modifier ? int cmp(const void *a, const void *b)
    Ce paramètre permet de comparer deux arguments pour retourner une valeur positive, négative ou 0.
    Mais effectivement il faudrait que ça retourne uniquement le plus petit argument car si je mets: int ints[] = { -2, -99 }; en tant que tableau à trier (1er argument de la fonction qsort), il va me retourner: -99 -2 alors qu'on veut ici juste le -99.

  4. #4
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 469
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 469
    Points : 6 102
    Points
    6 102
    Par défaut
    Citation Envoyé par orca10 Voir le message
    Quand tu dis qu'il faut que j'utilise cette technique avec des void* ça veut dire que j'enlève tous les const ?
    Non. Je me suis mal exprimé. Dans ton exo, il est préférable d'utiliser des const void* plutôt que des void*. Comme ça, tu pourras utiliser ta fonction de recherche sur des tableaux constants, par exemple const int tab[] = {-2, -99};.

    Citation Envoyé par orca10 Voir le message
    Et pour le 4ème argument de la fonction sort, je ne comprends pas pourquoi je dois le modifier ? int cmp(const void *a, const void *b)
    Parce que tu dois retourner le plus petit argument qui n'est pas forcément représentable sous forme de int. Par exemple, à la question 3, il faut comparer des chaînes de caractères.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Oui ok j'ai compris pour les const void*.

    Pour le 4ème argument je vois bien la problématique mais je ne sais pas comment on peut faire pour que ce soit générique. Si j'ai bien compris c'est à dire peut importe si c'est deux entiers, deux chaines, deux doubles etc... la fonction sera exécutée. Donc à la place de ça: int cmp(const void *a, const void *b), je me doute qu'il faut juste changer le "int" du début pour que ce soit générique mais je ne vois pas comment on fait. Il y a surement une écriture particulière qui prend tous les types de valeurs non ?

  6. #6
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 469
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 469
    Points : 6 102
    Points
    6 102
    Par défaut
    Le plus pertinent serait que la fonction de comparaison retourne l'adresse de la donnée la plus petite, sans s'embêter à recopier la donnée.
    Par exemple, lors de la comparaison de deux chaînes de caractères, la fonction retournerait l'adresse d'une des deux chaînes, sans recopier les caractères.
    La réponse à la question 1 est alors :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef const void * (*GetMin)(const void * x, const void * y);
    Si la fonction de comparaison devait copier la donnée la plus petite, alors la réponse à la question 1 serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef void (*CopyMin)(void* dest, const void * x, const void * y);
    Mais cela aurait plusieurs inconvénients :
    • La fonction cumulerait deux responsabilités qui ne sont pas liées : comparer et copier. Le code aurait été plus flexible s'il s'agissait de deux fonctions séparées.
    • La fonction ne serait pas utilisable pour les données qu'on ne peut pas copier.
    • La fonction ne serait pas performante pour les données dont la copie serait coûteuse et non nécessaire.

  7. #7
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par orca10 Voir le message
    Donc à la place de ça: int cmp(const void *a, const void *b), je me doute qu'il faut juste changer le "int" du début pour que ce soit générique mais je ne vois pas comment on fait.
    Surtout pas, ici int en tant que type de retour n'a pas de rapport avec le type des éléments du buffer. Il est employé pour pouvoir transmettre trois plages de valeurs entières distinctes : négative, nulle et positive. Réfère-toi à la documentation de qsort et/ou str*cmp, memcmp pour en comprendre la fonction.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo