Partage
  • Partager sur Facebook
  • Partager sur Twitter

Manipulation de tableau dans des structures

Sujet résolu
    16 novembre 2022 à 22:21:36

    Bonjours,

    Je suis encore débutant en C et j'amerais votre aide pour factoriser le code suivant (sans utiliser de boucle for si possible). Apres quelque recherche et essais infructueux je n'ai toujours pas réussi :euh:

    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    /*  Définition de la structure de noeud  */
    struct quadNoeud{
      int valeur[3];
      struct quadNoeud* fils[4];
    };
    
    /*  Définition du type quadtree qui est un pointeur sur noeud  */
    typedef struct quadNoeud * quadtree;
    
    
    /*  On alloue un noeud  */
    struct quadNoeud* initQuadNoeud(int x[3]){
        struct quadNoeud* n;
    	n = malloc(sizeof(struct quadNoeud));
    	n -> valeur[0] = x[0]; // a factoriser 
        n -> valeur[1] = x[1];
        n -> valeur[2] = x[2];
    	n -> fils[0] = NULL;
    	n -> fils[1] = NULL;
        n -> fils[2] = NULL;
        n -> fils[3] = NULL;
    	return n;
    }
    
    
    
    int main(){
            int t[3] = {1,2,3};
            quadtree a = initQuadNoeud(t);
            
    }
    



    -
    Edité par XarTOkS 16 novembre 2022 à 22:23:01

    • Partager sur Facebook
    • Partager sur Twitter
      16 novembre 2022 à 22:41:55

      Salut,

      Un quadtree c'est récursif, donc dans tes lignes 23 à 26, au lieu d'allouer NULL, il faut (ou pas) rappeler la fonction initQuadNoeud.

      Le ou pas, c'est selon le nombre d'éléments que tu veux ranger dans ton quadtree. Ici tu ne passes qu'une seule coordonnée.

      Le quadtree doit aussi contenir sa boite englobante en général. 

      Pour quoi veux tu faire un quadtree ? maitrises tu le concept ?

      Autre chose, pourquoi veux tu éviter les boucles for ?

      • Partager sur Facebook
      • Partager sur Twitter

      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        16 novembre 2022 à 23:23:04

        Fvirtman a écrit:

        Je vois le concept, on a travaillé dessus en cours d'algorithmique. On a réalisés quelques fonctions de manipulation en pseudo-code

        J'essaye donc de retranscrire ce pseudo code en C.

        Pour les boucles for, je voulais savoir si il était possible de faire en sorte que n->valeur pointe vers l'adresse que pointe le tableau x en parametre.

        Pour définir le noeud, il nous est dit que la fonction doit iniatiliser un noeud avec pour valeur le tableau passer en parametre et d'initialiser chaque fils a NULL.



        • Partager sur Facebook
        • Partager sur Twitter
          17 novembre 2022 à 0:01:36

          Bonsoir,

          pourquoi vouloir factoriser alors qu'il n'y a pas lieu de factoriser dans ce cas. Tu peux aussi t'essayer à un C un peu plus moderne, même si tu es à XLII … 

          struct quadNoeud *initQuadNoeud(int x[static restrict 3]){
              struct quadNoeud *n = malloc(sizeof *n );
              if (n) {
                  *n = (struct quadNoeud) {
                      .valeur = { [0]=x[0], [1]=x[1], [2]=x[2], },
                  };
              }
              return n;
          }
           

          à la limite tu peux extraire les lignes 4/6 en une fonction d'initialisation de struct quadNoeud, même si l'intérêt me semble limité.

          • Partager sur Facebook
          • Partager sur Twitter
            17 novembre 2022 à 0:34:36

            Et memcpy ne serait pas plus simple?
            On copie un tableau de 3 int dans un tableau de 3 int ...

            > Pour les boucles for, je voulais savoir si il était possible de faire en sorte que n->valeur pointe vers l'adresse que pointe le tableau x en parametre.
            Très dangereux. Si tu modifies le tableau d'origine, tu modifies "toutes" les instances de tes noeuds.

            -
            Edité par PierrotLeFou 17 novembre 2022 à 0:39:57

            • Partager sur Facebook
            • Partager sur Twitter

            Le Tout est souvent plus grand que la somme de ses parties.

              17 novembre 2022 à 0:40:12

              PierrotLeFou a écrit:

              Et memcpy ne serait pas plus simple?
              On copie un tableau de 3 int dans un tableau de 3 int ...

              [...]

              Plus simple ? ou plus lisible ? ça dépend. En général, avec les options d'optimisations, l'appel à memcpy sera optout.

              Ici on connait la taille du tableau, et le PO n'a pas jugé nécessaire de la définir en «constante» (dans le sens d'un #define). Mais de là à «factoriser avec une boucle sans utiliser for» … enfin bref passons. Si l'API est bien pensée il n'y aura pas d'autres endroits où ce genre de code devrait apparaître, a priori.


              PierrotLeFou a écrit:

              [...]> Pour les boucles for, je voulais savoir si il était possible de faire en sorte que n->valeur pointe vers l'adresse que pointe le tableau x en parametre.

              Très dangereux. Si tu modifies le tableau d'origine, tu modifies "toutes" les instances de tes noeuds.

              -
              Edité par PierrotLeFou il y a moins de 30s


              tout dépend de l'API … si il est clair qui est le propriétaire des données …

              Le gros désavantage (enfin à voir) sera une non localité des données.

              -
              Edité par White Crow 17 novembre 2022 à 0:42:05

              • Partager sur Facebook
              • Partager sur Twitter
                17 novembre 2022 à 0:54:19

                Ça pourrait avoir l'air de ceci? (non testé)
                    myCopy(n->valeur, x, 3);
                ...
                void myCopy(int *dst, int *src, int lg) {
                    if(lg <= 0) return;
                    *dst = *src;
                    myCopy(dst+1, src+1, lg-1);
                }
                • Partager sur Facebook
                • Partager sur Twitter

                Le Tout est souvent plus grand que la somme de ses parties.

                  19 novembre 2022 à 17:38:52

                  Merci à tous de votre aide
                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 novembre 2022 à 19:50:43

                    Le saviez-tu ?

                    A priori on pourrait être tenté d'écrire une macro

                    #define copie(dest, source) memcpy(dest, source, sizeof(source))
                    
                    
                    

                    mais piège, ça va merder avec des tableaux reçus en paramètres, qui ne sont pas des tableaux, mais  des pointeurs


                    Phénomène visible avec le code suivant

                    #include <stdio.h>
                    
                    int truc(int n, int t[n]) {
                    	printf("taille = %zu\n", sizeof(t));
                    }
                    
                    int main() {
                    	int t[10];
                    	truc(10, t);
                    }
                    
                    

                    qui donne



                    $ ./a 
                    taille = 8
                    

                    Et la taille d'un pointeur, c'est la taille d'un pointeur, pas du tableau dont il indique le début.

                    Heureusement le compilateur le signale

                    $ make a
                    cc     a.c   -o a
                    a.c: Dans la fonction « truc »:
                    a.c:4:33: attention: « sizeof » sur le tableau « t » en paramètre de fonction retournera la taille de « int * » [-Wsizeof-array-argument]
                        4 |  printf("taille = %zu\n", sizeof(t));
                          |                                 ^
                    a.c:3:21: note: déclaré ici
                        3 | int truc(int n, int t[n]) {
                          |                 ~~~~^~~~
                    

                    Moralité : TOUJOURS lire les avertissements. Et mieux : mettre d'office l'option qui va bien (gcc: -Werror) pour s'obliger à en tenir compte et à régler les problèmes (*).

                    retour au sujet : il faut une macro avec la taille du tableau en paramètre

                    #define copie(dest, source, nb_elements) memcpy(dest, source, (nb_elements) * sizeof(source))



                    (*) évidemment, si vous devez maintenir un projet existant qui a trouze mille avertissements pour des trucs bénins, ça va peut être pas être possible à cause du temps qu'il faudrait y passer.   Mais pour un exercice de débutant, ou un projet qu'on veut faire démarrer sur des bases saines, it'a a no brainer. Zero warnings.

                    -
                    Edité par michelbillaud 19 novembre 2022 à 19:58:11

                    • Partager sur Facebook
                    • Partager sur Twitter
                      15 décembre 2022 à 4:51:54 - Message modéré pour le motif suivant : Message complètement hors sujet


                        15 décembre 2022 à 9:07:00

                        @KamgaFostsoChristElise Bonjour, merci de ne pas squatter les sujet des autres surtout pour une question qui n'a rien à voir avec le sujet. Créer votre propre sujet dans le respect des règles du forum. 

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Manipulation de tableau dans des structures

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown