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 :

Définition de tableau dynamique dans une fontion


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 20
    Par défaut Définition de tableau dynamique dans une fontion
    Bonjour à tous et toutes,

    Ça fait un petit bout de temps que je cherche par moi même, que je fouine sur le net et que je relis la FAQ pour trouver cette info .

    Pour plus de clarté, prenons un exemple concret:
    Je défini un pointeur dans mon main, et ensuite j'aimerais en faire un tableau dynamique, mais au lieu de faire ça dans mon main, passer mon pointeur en argument dans une fonction faisant le boulot à ma place
    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
    void allocMemoire(char**** tab, int a, int b, int c)
    {
        int i, j;
        *tab=malloc(a*sizeof(char**));
        for (i=0; i<a; i++)
        {
            (*tab)[i]=malloc(b*sizeof(char*));
            for (j=0; j<b; j++)
                (*(*tab)+i)[j]=malloc(c*sizeof(char));
        }
    }
     
    int main()
    {
        char*** T;
        allocMemoire(&T,11,8,2);
        return 0;
    }
    Première question, ce code est-il juste (je n'arrive pas à le vérifier) ? Si non, que faut-il changer ?

    Bien cordialement à tous,
    Clément.

  2. #2
    Membre émérite
    Avatar de bpy1401
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2003
    Messages
    511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2003
    Messages : 511
    Par défaut
    Bonjour nuwanda03


    je n'ai pas vraiment compris ton exemple.
    Il y a combien de dimensions dans ton tableau ?
    Ca correspond à quoi les valeurs 10 dans tes boucles.


    char**** tab
    • char * tab, certains développeur on du mal,
    • char ** tab, ceux qui peuvent répondre sont déjà plus rares
    • char *** tab, oulala
    • char **** tab, la j'arrête de chercher, c'est trop pour moi


    le nom d'un tableau, qu'il soit de une, deux ou x dimensions est toujours un pointeur , un simple char * tab est dans tous les cas suffisant.

    Je me demande si tu ne confond pas le nombre d'étoile avec la dimension de ton tableau
    Page sur Developpez : http://pbriand.developpez.com

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 20
    Par défaut
    Bonjour à tous les deux,

    Pour répondre à bpy1401: les valeurs 10 sont une erreur de ma part (j'ai légèrement modifié mon code pour le sujet, et j'avais oublié ce détail).

    Et effectivement le nombre d'étoile définit la dimension de mon tableau (non ? ). Donc 3 étoiles pour mon tableau à 3 dimensions, et 4 étoiles pour un pointeur vers mon tableau de 3 dimension, pas vrai ?

    Merci diogene, je vais essayer de voir comment tout ça fonctionne.

    Pour conclure, il faut bien passer en argument dans ma fonction l'adresse de mon tableau (&tab), ma fonction attendant en paramètre un pointeur de tableau de 3 dimensions (donc char**** tab), vous confirmez ?

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Pour opérer un test de base, il suffit d'écrire dans le tableau et de regarder son contenu.

    Hélas, ce code est faux.
    1- lors de la construction du tableau, conserver la logique du code, sinon on risque d'avoir un conflit sur les dimensions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        *tab=malloc(a*sizeof(char**));
        for (i=0; i<a; i++)
        {
            (*tab)[i]=malloc(b*sizeof(char*));
            for (j=0; j<b; j++)
    2- cette ligne est fausse : (*(*tab)+i)[j] ce devrait être (*((*tab)+i))[j] . Mais, il est beaucoup plus clair d'écrire (*tab)[i][j].

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    @bpy1401
    char * tab, certains développeur on du mal,
    char ** tab, ceux qui peuvent répondre sont déjà plus rares
    char *** tab, oulala
    char **** tab, la j'arrête de chercher, c'est trop pour moi
    Ne pas confondre "développeur" et "développeur débutant"

    un simple char * tab est dans tous les cas suffisant.
    Ceci est faux.

    Je me demande si tu ne confond pas le nombre d'étoile avec la dimension de ton tableau
    Dans ce contexte, les choses sont liées car il construit des tableaux de pointeurs et pas seulement un tableau de char.

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Le nombre d'étoiles indique le nombre de dimensions du tableau. 4 étoiles ça commencent un peu à piquer le cerveau quand même ^^

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 20
    Par défaut
    Oui, le nombre d'étoiles comme le nombre de dimension de notre tableau. Mais quand on doit passer un tableau comme paramètre de fonction pour en modifier le contenu, il faut donner son adresse (&tab) et le considérer dans la fonction comme un tableau de dimension initiale + 1. Finalement ce n'est pas plus compliqué qu'avec un simple pointeur, ou bien une variable que l'on souhaiterait modifier hors de la fonction où elle est définie en indiquant l'adresse de celle-ci.

    Par exemple, j'ai 10 tableaux de 3 dimensions (donc 3 étoiles), et je veux les initialiser, ou les modifier. Soit je le fais dans mon main, mais c'est tout de même un peu lourd avouerez vous. Soit je passe par une fonction, mais ça implique de travailler avec des tableaux de 4 dimensions (si on peut voir ça comme ça), donc 4 étoiles.

    Si vous avez d'autres solutions, tout aussi efficaces mais moins ésotériques, je prends avec plaisir.

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Et effectivement le nombre d'étoile définit la dimension de mon tableau (non ? ). Donc 3 étoiles pour mon tableau à 3 dimensions, et 4 étoiles pour un pointeur vers mon tableau de 3 dimension, pas vrai ?
    Dans ton cas oui, parce que tu n'as pas un vrai tableau à trois dimensions mais des tableaux de pointeurs :

    - Tu as créé a*b tableaux (à une dimension) de c char chacun (type des éléments char). L'adresse de début de ces tableaux est donc du type char*

    - Tu as mis l'adresse de début de ces a*b tableaux dans a tableaux (à une dimension) de b pointeurs chacun (type des éléments char *). L'adresse de début de ces tableaux est donc du type char**

    - Tu as mis l'adresse de début de ces a tableaux dans un tableau (à une dimension) de a pointeurs (type des éléments char**). L'adresse de début de ce tableau est donc du type char***

    - Enfin, comme tu veux retourner cette adresse par la liste des paramètres de la fonction, il faut donner l'adresse d'un pointeur où on veut mettre celle du premier élément de ce tableau (de type char***) d'où le paramètre de type char****. (Mais, pourquoi ne pas utiliser plutôt la valeur de retour de la fonction ?)

    Le cas d'un vrai tableau à trois dimensions (tableau de tableaux de tableaux de char), comme celui-ci char tab[10][10][10]; , est complètement différent.

  9. #9
    Membre émérite
    Avatar de bpy1401
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2003
    Messages
    511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2003
    Messages : 511
    Par défaut
    Citation:
    un simple char * tab est dans tous les cas suffisant.
    Ceci est faux.
    Doigene, si je ne me trompe pas, un tableau en c, c'est juste une zone de mémoire, la taille de cette zone dépendant du nombre de case dans ton tableau. Pour l'allocation, les dimensions ne sont utilsie que pour connaitre la taille de la zone.

    la définition de tes dimensions est utilisé par le compilateur pour calculer l'offset entre le début de la zone et la position d"information.

    C'est pour cette raison que je dis que char * tab peut être suffisant pour l'allocation. Il pourra ensuite être utilisé par tab[x][y][z] sans soucis.

    tout ceci, c'est pour dire qu'il n'a aucun lien entre la dimension d'un tableau et le nombre d'étoile (d'indirection pour être plus précis) pour le pointeur.
    Page sur Developpez : http://pbriand.developpez.com

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 20
    Par défaut
    Merci beaucoup diogene, ça a beau être compliqué, on s'y retrouve avec tes explications. Utiliser la valeur de retour de la fonction peut être une solution, mais je voulais savoir s'il était possible, et comment, faire autrement. Et justement, si je voulais récupérer la valeur de retour dans un char***, il me faudrait créer un tableau de char de dimension 3 dans ma fonction et de renvoyer l'adresse tout simplement ?

    En tout cas merci beaucoup pour ces remarques, ça m'avance bien niveau compréhension.

  11. #11
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    @bpy1401
    Tu omets de considérer que le C est un langage typé. Un tableau alloué par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char * tab = malloc(a*b*c);
    ou 
    char tab[a*b*c];
    ne peut pas être utilisé par tab[x][y][z]. Au mieux, on peut simuler en calculant soi-même la position des éléments, du genre tab[b*c*x+c*y+z].
    Alors que si tab est défini par char tab[a][b][c] , il peut l'être.
    Le cas présenté par le PO également parce qu'il a des tableaux (à une dimension, ce qui permet d'esquiver la difficulté des vrais tableaux à plusieurs dimensions) de pointeurs pour gérer l'accès aux données qui l'interessent.

    tout ceci, c'est pour dire qu'il n'a aucun lien entre la dimension d'un tableau et le nombre d'étoile (d'indirection pour être plus précis) pour le pointeur.
    Cela est exact effectivement. la présence de ces * chez le PO n'est pas lié à la multidimensionnalité (qui se réduit à 1 dans son cas) mais à la présence de tableaux de pointeurs.

  12. #12
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    @nuwanda03 :
    C'est beaucoup plus simple que ça :
    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
    char *** allocMemoire(int a, int b, int c)
    {
     // les tests de réussite des allocations mémoire sont omis 
        int i, j;
        char ***tab=malloc(a*sizeof(char**)); 
        for (i=0; i<a; i++)                               
        {
            tab[i]=malloc(b*sizeof(char*));
            for (j=0; j<b; j++)
                tab[i][j]=malloc(c*sizeof(char));
        }
        return tab;
    }
     
    int main(void)
    {
        char*** T =  allocMemoire(11,8,2);
    // prévoir une fonction de libération de la mémoire allouée
        return 0;
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Conception] Insertion de champs d'un tableau dynamique dans une base de données
    Par loreleï85 dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 12/05/2011, 14h39
  2. Réponses: 4
    Dernier message: 01/01/2007, 10h26
  3. [SQL] Modification de champs d'un tableau dynamique dans une base de données
    Par loreleï85 dans le forum PHP & Base de données
    Réponses: 18
    Dernier message: 27/06/2006, 16h55
  4. Réponses: 1
    Dernier message: 23/06/2006, 11h19
  5. Réponses: 9
    Dernier message: 22/06/2006, 20h06

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