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 :

Pointeurs de matrices ??


Sujet :

C

  1. #1
    Invité
    Invité(e)
    Par défaut Pointeurs de matrices ??
    Bonjour à tous,

    J'ai vu qu'en C il était possible d'écrire pour créer une matrice 9*9. Si l'on veut écrire ça "sous forme de pointeurs", doit-on faire ?

    Je suis dans le cas d'une fonction qui doit renvoyer cette matrice : doit-elle être de type long** ? Et quand je renvoie cette matrice, suffit ou je dois mettre autre chose ? Et enfin : quand j'envoie cette matrice à une fonction, que dois-je écrire ???


    Merci


    EDIT : j'ai aussi fait un test, pour passer une matrice [9][9] en argument, et bizarrement, long maFonction(long matrice[][]) ne fonctionne pas, mais long maFonction(long matrice[][9]) fonctionne !!! Comment ça se fait ???

  2. #2
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    EDIT : j'ai aussi fait un test, pour passer une matrice [9][9] en argument, et bizarrement, long maFonction(long matrice[][]) ne fonctionne pas, mais long maFonction(long matrice[][9]) fonctionne !!! Comment ça se fait ???
    Rien de tel qu'une petite explication :

    http://www.ldsol.com/doc/ansi-c/node62.htm#SECTION00693000000000000000

  3. #3
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Sinon, pour en revenir à ton problème :

    J'ai vu qu'en C il était possible d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    long matrice[9][9]
    pour créer une matrice 9*9
    Oui là tu crée un tableau bi-dimensionnel.

    Si l'on veut écrire ça "sous forme de pointeurs", doit-on faire
    ?
    Oui, là tu as crée un pointeur sur un pointeur de long. Ca peut te permettre de créer un objet qui pourra faire office d'une matrice. Il ne faudra pas cependant oublier d'effectuer une allocation mémoire pour ta matrice.

    Je suis dans le cas d'une fonction qui doit renvoyer cette matrice : doit-elle être de type long** ?
    Si tu le fais comme précédement, oui.

    Et enfin : quand j'envoie cette matrice à une fonction, que dois-je écrire ???
    un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    void maFct( long ** matrice )
    ...

  4. #4
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    long maFonction(long matrice[][9]) : Le compilateur a besoin de connaitre la taille du type d'argument que tu lui passes : ici un pointeur vers des tableaux de 9 longs, donc si tu incrémentes le pointeur dans la fonction il se calera automatiquement en début de tableau de 9 (ligne 0, ligne 1 ...).
    Si tu déclares une matrice sous la forme long tab[X][Y], tu ne peux pas la passer sous la forme **tab, le compilo refusera, tu peux faire long maFonction(long matrice[][9]) ou long maFonction(long (*matrice)[9]) .

    Voilà un exemple de code pour illustrer :
    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
    #include <stdio.h>
     
    void affi(int (*tab)[3])
    {
      int i , j;
     
      for(i = 0; i < 3; i++, tab++)
      {
        for(j = 0; j < 3; j++)
    	  printf("%3d", (*tab)[j]);
     
    	puts("");
      }
    }
     
    int main(void)
    {
      int tab[3][3];
      int i, j;
     
      for(i = 0; i < 3; i++)
      {
        for(j = 0; j < 3; j++)
    	  tab[i][j] = i*3 + j;
     
      }
      affi(tab);
      return 0;
    }
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  5. #5
    Membre du Club

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 52
    Points : 50
    Points
    50
    Par défaut
    En fait ça dépends si tu souhaites faire une allocation statique ou dynamique.

    Une allocation statique reserve l'espace en mémoire dés que tu a écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    long matrice[9][9]
    ce qui te coute en mémoire (en octet) :
    un long vaut 4 octets soit 32 bits

    tu as 9 cases en largeur et 9 cases en hauteur => 81 cases

    donc un total de 4*9*9 = 324 octets mémoires (pour rien car il n'y a pas encore de donnée dans ton tableau).

    avec une allocation dynamique en utilisant
    tu as un pointeur de pointeur sur une zone mémoire (qui n'est pas encore définie)!

    tu alloues la zone mémoire dés que tu souhaites l'utiliser comme ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    matrice = (long **) malloc(9 *sizeof(long));
    for (i = 0 ; i < 9 ; i++)
    	matrice[i] = (long *)malloc(9*sizeof(long));
    et ensuite dés que tu n'en a plus besoin tu la libère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for (i = 0 ; i < 9 ; i++)
    	free(matrice[i]);
    free(matrice);
    Pour avoir les deux fonction malloc et free il faut faire Voilà j'espère avoir put t'aider.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Merci à vous, c'est beaucoup plus clair maintenant

  7. #7
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: Pointeurs de matrices ??
    Citation Envoyé par jo_le_coco
    J'ai vu qu'en C il était possible d'écrire pour créer une matrice 9*9. Si l'on veut écrire ça "sous forme de pointeurs", doit-on faire ?
    On peut (c'est pas une FAQ ?).

    Methode générale :

    Il faut créer un tableau de Y pointeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long **matrice = malloc(Y * sizeof *matrice);
    puis, après les vérifications d'usage, créer Y tableaux de X long dont on range les adresses dans le tableau de pointeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int i;
     
    for (i = 0; i < Y; i++)
    {
       matrice[i] = malloc (X * sizeof *matrice[i]);
    }
    ensuite, on peut accéder aux données en faisant matrice[i][j]

    Quand on a plus besoin de la matrice, penser à libérer les blocs dans le bon ordre...
    Pas de Wi-Fi à la maison : CPL

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par websurfeur
    tu alloues la zone mémoire dés que tu souhaites l'utiliser comme ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    matrice = (long **) malloc(9 *sizeof(long));
    for (i = 0 ; i < 9 ; i++)
    	matrice[i] = (long *)malloc(9*sizeof(long));
    Ecriture inutilement complexe et difficile à maintenir...

    http://emmanuel-delahaye.developpez....tes.htm#malloc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    long **matrice = malloc (9 *sizeof *matrice);
    for (i = 0 ; i < 9 ; i++)
    {
       matrice[i] = malloc (9 * sizeof *matrice[i]);
    }
    Le même en double
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    double **matrice = malloc (9 *sizeof *matrice);
    for (i = 0 ; i < 9 ; i++)
    {
       matrice[i] = malloc (9 * sizeof *matrice[i]);
    }
    et hop, un changement.

    Et je ne parle pas des constantes magiques (9) pour définir la taille...
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Invité
    Invité(e)
    Par défaut
    Ca reste quand même très complexe

    Citation Envoyé par Emmanuel Delahaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    long **matrice = malloc (9 *sizeof *matrice);
    for (i = 0 ; i < 9 ; i++)
    {
       matrice[i] = malloc (9 * sizeof *matrice[i]);
    }
    Je ne comprends pas vraiment ce code :

    Je connais les allocations dynamiques, mais là je suis un peu dérouté

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par jo_le_coco
    Je ne comprends pas vraiment ce code :
    J'ai pourtant tout expliqué avant. Je t'engage à relire mes messages.
    Je connais les allocations dynamiques, mais là je suis un peu dérouté
    Tu as lu l'article dont j'ai mis le lien ?
    Pas de Wi-Fi à la maison : CPL

  11. #11
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Je ne comprends pas vraiment ce code
    http://rperrot.developpez.com/articl...ocationC/#L1.2

  12. #12
    Invité
    Invité(e)
    Par défaut
    J'ai bien tout lu, mais je débute, et quand je me trouve devant une pléthore de pointeurs, d'allocations, de tableaux, de tableaux à plusieurs dimensions... je succombe

    Bon mais grosso modo, je comprends. Par contre, il reste UN truc que je ne saisis vraiment pas : dans ton lien, tu dis que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long *p = malloc (sizeof (long));
    peut être remplacé par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long *p = malloc(sizeof *p)
    Mais comment est-ce que l'ordinateur peut deviner quelle est la taille de *p ??? Et, du même genre, comment, dans ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long **matrice = malloc (9 *sizeof *matrice);
    l'odinateur sait-il la taille de *matrice, qui n'a même pas été déclaré ??

    Et, dernière petite question (après j'arrête, promis ) : pourquoi ne pas faire simplement au besoin avec des constantes #define au lieu des 9 ?

  13. #13
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    sizeof a deux formes, une avec parenthèse et une sans.

    Celle avec parenthèse attend un type et celle sans attend une expression.

    Ici, c'est une expression qu'on attend.

    L'expression en question est celle ci :
    Or ceci est le type du pointeur, c'est à dire long, du coup, ça revient strictement au même que sizeof(long). C'est un raccourci pour faciliter les choses.

    L'odinateur sait-il la taille de *matrice, qui n'a même pas été déclaré ??
    Pour lui, *matrice est un pointeur d'entier long, ça fonctionne comme avant.

  14. #14
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Pourquoi ne pas faire simplement ...
    C'est toi qui veux utiliser les pointeurs :

    Si l'on veut écrire ça "sous forme de pointeurs", doit-on faire

  15. #15
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par jo_le_coco
    J'ai bien tout lu, mais je débute, et quand je me trouve devant une pléthore de pointeurs, d'allocations, de tableaux, de tableaux à plusieurs dimensions... je succombe
    Euh, c'est bien toi qui a parlé denon ?
    Bon mais grosso modo, je comprends. Par contre, il reste UN truc que je ne saisis vraiment pas : dans ton lien, tu dis que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long *p = malloc (sizeof (long));
    peut être remplacé par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long *p = malloc(sizeof *p)
    Mais comment est-ce que l'ordinateur peut deviner quelle est la taille de *p ???
    Il ne devine pas, il sait et il calcule. *p est une forme simplifiée de p[0], c'est à dire un élément (ici, le premier) du tableau pointé par p.

    sizeof p[0] retourne donc la taille de p[0]. Pour calculer la taille, le compilateur n'a besoin que du type. Comme p a été défini avec un type, il peut en déduire la taille de l'objet.
    Et, du même genre, comment, dans ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long **matrice = malloc (9 *sizeof *matrice);
    l'odinateur sait-il la taille de *matrice, qui n'a même pas été déclaré ??
    Heink ? Et ça,c'est pas une défintion ?
    Et, dernière petite question (après j'arrête, promis ) : pourquoi ne pas faire simplement au besoin avec des constantes #define au lieu des 9 ?
    Oui, bien sûr, mais encore une fois, ce n'est pas moi qui ai abordé le long ** matrice...
    Citation Envoyé par jo le croco
    pour créer une matrice 9*9. Si l'on veut écrire ça "sous forme de pointeurs", doit-on faire
    Pas de Wi-Fi à la maison : CPL

  16. #16
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par PRomu@ld
    Or ceci est le type du pointeur, c'est à dire long,
    Ce n'est pas un type c'est un objet (c'est pour ça qu'il n'y a pas de parenthèses)
    Pas de Wi-Fi à la maison : CPL

  17. #17
    Invité
    Invité(e)
    Par défaut
    Je pensais que c'était indispensable dans mon cas d'utiliser les pointeurs... mais ça m'aura appris bien des choses sur les allocations Merci à vous

  18. #18
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Oups, je me suis planté, je voulais dire :

    Or ceci est du type du pointeur, c'est à dire long
    Encore une fois de plus je ne me relis pas ...

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

Discussions similaires

  1. pointeur sur matrice de chaine
    Par chessop dans le forum Débuter
    Réponses: 11
    Dernier message: 20/03/2010, 10h59
  2. tableau de pointeurs et matrices
    Par chessop dans le forum Débuter
    Réponses: 2
    Dernier message: 18/03/2010, 21h04
  3. fonctions, pointeurs et matrices C++
    Par inforum dans le forum C++
    Réponses: 7
    Dernier message: 19/10/2009, 19h59
  4. [Débutant] Initialiser pointeur vers matrice
    Par scarabee10 dans le forum C
    Réponses: 4
    Dernier message: 03/06/2009, 16h21
  5. Matrice de pointeurs de fonctions
    Par sebduth dans le forum C
    Réponses: 15
    Dernier message: 18/07/2003, 14h03

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