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 :

Problème dans une fonction avec des structures


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2020
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2020
    Messages : 18
    Points : 11
    Points
    11
    Par défaut Problème dans une fonction avec des structures
    Bonjour ou bonsoir, j'aimerais comprendre mon erreur dans la fonction decomposition_arithmetic(). En effet je n'arrive pas a remplir le tableau "dec_array" avec des valeurs, je fais une allocation mémoire avec 8 structures dans mon tableau, après dans la boucle while() j'essaie de mettre en position 0 la valeur du premier quotient avec (*(dec_array + i)).quotient = d_nb.quotient; mais cela ne marche pas et je ne comprends pas pourquoi ! Merci d'avance pour toutes aides ! Et si vous avez des remarques pour améliorer mon code je suis preneur !

    erreur dans le terminal :
    error: request for member ‘quotient’ in something not a structure or union (*(dec_array + i)).quotient = d_nb.quotient;
    Et petite remarque l'affichage avec printf() est juste la pour comprendre 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
     
    typedef struct _Dec Decomposition;
     
    struct _Dec {
      long long quotient;
      long long rest;
    };
     
    Decomposition decomposition_number(long long nb) {
      Decomposition d = {d.quotient = nb / pivot_number(nb), d.rest = nb % pivot_number(nb)};
      return d;
    }
     
     
    long long *decomposition_arithmetic(long long nb) {
      long long *dec_array = malloc(8 * sizeof(Decomposition));
     
      if (dec_array == NULL) {
        fprintf(stderr,"Allocation impossible\n");
        exit(EXIT_FAILURE);
      }
     
      int i = 0;
      Decomposition d_nb = decomposition_number(nb);
      //printf("nb = %lld * %lld + %lld = %lld\n", d_nb.quotient, pivot_number(nb), d_nb.rest, nb);
      while (d_nb.rest != 0) {
        (*(dec_array + i)).quotient = d_nb.quotient; //ne marche pas
        (*(dec_array + i)).rest = d_nb.rest; //ne marche pas non plus
        //printf("new_quotient = %lld\n", d_nb.quotient);
        //printf("new_rest = %lld\n", d_nb.rest);
        Decomposition d_quotient = decomposition_number(d_nb.quotient);
        Decomposition d_rest = decomposition_number(d_nb.rest);
        //printf("dec_quotient : %lld = %lld * %lld + %lld\n", d_nb.quotient, d_quotient.quotient, pivot_number(d_nb.quotient), d_quotient.rest);
        //printf("dec_rest : %lld = %lld * %lld + %lld\n", d_nb.rest, d_rest.quotient, pivot_number(d_nb.rest), d_rest.rest);
        d_nb.quotient = d_quotient.rest;
        d_nb.rest = d_rest.rest;
        i++;
      }
      return dec_array;
      free(dec_array);
      dec_array = NULL;
    }

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Regarde attentivement la déclaration de ton pointeur dec_array :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long long *dec_array = malloc(8 * sizeof(Decomposition));
    De quel type est-il ? / Quel type t'attends-tu à avoir avec (*(dec_array + i)) ?
    Et pour l'erreur liée qui viendra juste après, quel type est retourné par la fonction decomposition_arithmetic() ?

    Note que tes deux lignes après le return :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      return dec_array;
      free(dec_array);
      dec_array = NULL;
    }
    ne sont jamais exécutées.
    Et heureusement dirais-je, car si tu libères ton tableau à ce moment-là, tu ne pourras pas l'utiliser une fois sorti de ta fonction.
    Tu ne dois le libérer que lorsque tu ne t'en sers plus. Pas avant.

    Sinon il est plus simple d'écrire dec_array[i].quotient plutôt que (*(dec_array + i)).quotient.

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Modaak Voir le message
    je fais une allocation mémoire avec 8 structures dans mon tableau
    Oui mais comme tu stockes le retour de l'allocation dans un pointeur long long, le compilo croit que ton truc c'est un long long.
    Si j'écris float pi=3.1416; long *pt=&pi (avec tous les casts qui vont bien pour que le compilo accepte enfin de claquer l'adresse d'un float dans un pointeur long), chaque fois que je demanderai affiche(*pt), le bouzin essaiera de traduire ce qu'il y a à cette adresse en long. C'est pas sa faute, je lui ai dit "étoile pt c'est un long" donc il me fait confiance et il tente bravement de m'écouter. Et même si le contenu de ces 4 cases est le même (un long fait 4 octets comme un float), les conventions de codage entre long et float ne sont pas les mêmes.
    C'est exactement comme si un texte écrit de cette façon (extrait de l'Odyssée):
    Citation Envoyé par odyssée
    Alors survint l'âme du Thébain Tirésias, le sceptre d'or en main. Il me reconnut et me dit: «Descendant de Zeus, fils de Laërte, Ulysse aux mille expédients, » pourquoi donc, malheureux, quittant la lumière du soleil, es-tu venu voir les morts et la région sans joie? Mais éloigne-toi de la fosse, écarte la pointe de ton épée, que je boive du sang et te dise la vérité. » Il parlait ainsi; moi, je m'éloignai et remis au fourreau mon épée aux clous d'argent.
    Tu cherchais à le lire de cette façon
    Citation Envoyé par odyssée
    alorssurvintl'âmeduthébaintirésias,lesceptred'orenmainilmereconnutetmeditdescendantdezeus,filsdelaërteulysseauxmilleexpédientspourquoidoncmalheureux,quittantlalumièredusoleilestuvenuvoirlesmortsetlarégionsansjoiemaiséloignetoidelafosseécartelapointedetonépéequejeboivedusangettediselavéritéilparlaitainsimoi,jem'éloignaietremisaufourreaumonépéeauxclousd'argent
    Le texte reste le même hormis que j'ai supprimé les espaces, les majuscules et la ponctuation (merci à sed et à tr) => illisible

    Citation Envoyé par Modaak Voir le message
    Et si vous avez des remarques pour améliorer mon code je suis preneur !
    Ben déjà j'aimerais comprendre ce que tu cherches à faire. Ok un quotient et un reste je vois ce que ça représente (bien qu'il soit plus pratique d'utiliser des fractions ne serait-ce que pour faire ensuite des calculs) mais pourquoi "8" ???
    Et comme il manque certaines fonctions (comme par exemple pivot_number())...

    Ah, accessoirement, on ne quitte jamais une fonction avec exit(). Tu t'imagines si les programmeurs de malloc() ou de fopen() avaient procédés de la même manière ? Tu ne pourrais jamais savoir que ça n'a pas marché.
    Si un truc se passe mal dans la fonction, elle doit renvoyer le souci à son appelant qui, lui, prendra une décision qui, bien évidemment, ne sera pas non plus de quitter mais soit de trouver une solution alternative, soit renvoyer le souci à son propre appelant et etc etc jusqu'au main qui, seul, a le droit de quitter le programme. Ok en debug ça peut rester mais pas pour un produit fini.

    Et bien entendu, le free(dec_array) juste après l'avoir retourné... (ok, je te retourne un truc alloué et rempli mais tu pourras pas l'utiliser car je l'ai libéré de son allocation juste après et de toute façon comme ma fonction s'est terminée au return ben en fait l'instruction ne s'est pas exécutée donc il est toujours alloué mais je ne le sais même pas...)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2020
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2020
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Nice ! Merci pour les conseils, j'ai résolue le problème. Mais j'ai changé d'avis pour le tableau dynamique, j'ai fais un tableau à deux dimensions pour récupérer mes calculs. J'aimerais avoir votre avis sur mon 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
    long long **create_two_dimensional_array(const int lignes, const int colonnes) { //array[lignes][colonnes]
      long long **array = malloc(lignes * sizeof(long long*));
      for (int i = 0; i < lignes; i++) {
        array[i] = malloc(colonnes * sizeof(long long));
      }
      return array;
    }
     
    void free_two_dimensional_array(long long **array, const int lignes) {
      for (int i = 0; i < lignes; i++) {
        free(array[i]);
      }
      free(array);
      array = NULL;
    }

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    tu en penses quoi de ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    long long* create_two_dimensional_array(const int nb_lines, const int nb_columns) {
    // test if ((nb_lines > 0) && (nb_columns > 0))
      return ( malloc(nb_lines* nb_columns * sizeof(long long)) );
    }
     
    void free_two_dimensional_array(long long* array) {
      if (array != NULL) {
        free(array);
        array = NULL;
      }
    }
    avec 1 accès *(array+ i + j * nb_columns).

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2020
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2020
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ben déjà j'aimerais comprendre ce que tu cherches à faire. Ok un quotient et un reste je vois ce que ça représente (bien qu'il soit plus pratique d'utiliser des fractions ne serait-ce que pour faire ensuite des calculs) mais pourquoi "8" ???
    Et comme il manque certaines fonctions (comme par exemple pivot_number())...
    C'est simple mais tellement compliqué en C. Je dois convertir un nombre en toutes lettres. En Python c'est tellement plus simple ^^ mais je dois le faire en C ! La fonction decomposition_arithmetic() est censé décomposer un nombre par exemple je prends 211571 => 2 100 11 1000 5 100 60 11. Comme cela j'ai juste a faire une conversion vers des lettres ! et faire des traitement par rapport à la langue française ! Je vous donne mon projet via Git si vous voulez voir !

    Git clone : git@gitlab.univ-lr.fr:ariberau/spell-number.git

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2020
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2020
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par foetus Voir le message
    tu en penses quoi de ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    long long* create_two_dimensional_array(const int nb_lines, const int nb_columns) {
    // test if ((nb_lines > 0) && (nb_columns > 0))
      return ( malloc(nb_lines* nb_columns * sizeof(long long)) );
    }
     
    void free_two_dimensional_array(long long* array) {
      if (array != NULL) {
        free(array);
        array = NULL;
      }
    }
    avec 1 accès *(array+ i + j * nb_columns).
    C'est tellement plus simple merci ! // test if ((nb_lines > 0) && (nb_columns > 0)) je peux faire des assert() ?
    Mais du coup cela ne fait pas un tableau a deux dimensions ? du genre array[nb_lignes][nb_colonnes] ?

  8. #8
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 562
    Points : 1 253
    Points
    1 253
    Par défaut
    Citation Envoyé par Modaak Voir le message
    J'aimerais avoir votre avis sur mon code
    Bonjour,

    Oui, moi je ne vois aucun intérêt à s’embêter avec un tableau dynamique.

    P.-S. : en français, ne pas oublier la Belgique et la Suisse

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par Modaak Voir le message
    je peux faire des assert() ?
    assert, test avec NULL si négatif ce que tu veux.


    Citation Envoyé par Modaak Voir le message
    Mais du coup cela ne fait pas un tableau a deux dimensions ? du genre array[nb_lignes][nb_colonnes] ?
    En C, les tableaux multi-dimensions n'existent pas il sont stockés contiguë en mémoire lignes par lignes.
    Les tableaux dynamiques qui sont 1 tableau de tableaux sont intéressants si justement les tableaux (les lignes en gros) ont des tailles différentes


    Citation Envoyé par Modaak Voir le message
    La fonction decomposition_arithmetic() est censé décomposer un nombre par exemple je prends 211571 => 2 100 11 1000 5 100 60 11.
    ce n'est pas difficile ... par contre je te laisse concaténer les "70 10 3 1" en "60 13" par exemple

    Attention c'est la version la + longue parce qu'on décompose par la gauche. Par la droite c'est encore + simple.
    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
    #include <math.h>
    #include <stdlib.h>
    #include <stdio.h>
     
     
    /*****************************************************************************/
    /***********************************  Main  **********************************/
    /*****************************************************************************/
     
    int main(int argc, char** argv)
    {
        size_t numb = 211579;
        size_t rest, length, tens, numeral;
     
    //  First : compute length
        rest   = numb;
        length = 0;
     
        while (rest > 9) {
            rest /= 10;
            ++length;
        }
     
        ++length;
     
        printf("Length: %lu\n", length);
     
    //  Second : decompose
        rest = numb;
        tens = pow(10, (length - 1));
     
        while (rest > 9) {
            numeral = (rest / tens);
     
            printf("%lu %lu ", numeral, tens);
     
            rest = (rest - ((rest / tens) * tens));
            tens /= 10;
        }
     
        printf("%lu 1\n", rest);
     
     
        return EXIT_SUCCESS;
    }

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Modaak Voir le message
    C'est simple mais tellement compliqué en C. Je dois convertir un nombre en toutes lettres. En Python c'est tellement plus simple ^^ mais je dois le faire en C
    Rien ne t'empêche de le faire d'abord en Python, et une fois que ça marche, le réécrire en C. L'algo reste le même. Je dis pas que c'est simple, mais c'est faisable.

    Moi, je serais parti du fait qu'une fois groupés par 3, les nombres s'expriment toujours pareil. Exemple 123123 c'est "cent vingt-trois mille cent vingt-trois" et 456456456 c'est "quatre cent cinquante-six millions quatre cent cinquante-six mille quatre cent cinquante-six". Bref même à 500 chiffres, ce sera toujours "truc trilliards truc trillions truc milliards truc millions truc mille truc".
    Donc j'écrirais une fonction qui ne travaille que pour 3 chiffres. Basée sur les tokens complets des nombres ("un", "deux", "trois", ..., "quinze", "seize", "vingt", "trente", "quarante", "cinquante" et "soixante" car tout nombre de 3 chiffres ce n'est que "x" cent puis une combinaison de ces tokens.
    Et ensuite, je décomposerais mon nombre en groupe de 3, et appliquerais la fonction à chaque groupe. Et comme le dit foetus, dans le bon sens le découpage, car 1234 c'est "mille deux cent trente quatre" et non "cent vingt-trois mille quatre" !!!

    Et attention, 500 s'écrit "cinq cents" mais "534" s'écrit "cinq cent trente-quatre". Oui, je sais, le français n'est pas facile...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/11/2012, 18h14
  2. [VB6] Scrollbar dans une frame avec des textbox
    Par bb62 dans le forum VB 6 et antérieur
    Réponses: 44
    Dernier message: 01/03/2006, 08h16
  3. Réponses: 8
    Dernier message: 02/02/2006, 18h13
  4. Erreur sur une fonction avec des paramètres
    Par Elois dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 05/05/2004, 21h00
  5. Une fonction avec des attributs non obligatoires
    Par YanK dans le forum Langage
    Réponses: 5
    Dernier message: 15/11/2002, 13h39

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