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 :

Tableau à deux dimensions


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut Tableau à deux dimensions
    Bonjour à tous,

    je viens de faire quelques petites "expériences" et la je suis tombé sur quelque chose d'étrange :

    On déclare un tableau à deux dimensions de 8 sur 8 qu'on initialise à zéro. Ensuite on fait quelque affichage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    printf("0x%08x\ttab2 : 0x%08x vers 0x%08x vers %d\n",&tab2D,tab2D,*tab2D,**tab2D);
    /*Résultat console : 0x0028fd40 tab2 : 0x0028fd40 vers 0x0028fd40 vers 0 */
    J'en tire comme conclusion que l'adresse de tab2D est 0x0028fd40 et que son contenu est 0x0028fd40. Déjà rien que ça c'est bizarre, un pointeur qui pointe vers lui-même ?

    Ensuite, si c'est le cas, il pointe vers lui même et à un moment (à tab2D[0][0]) il s'arrête, le contenu change et devient 0. Oui je sais que c'est pas vrai mais c'est là que je comprends pas, qu'est-ce qui cloche ?

    Merci de votre éclaircissement

  2. #2
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Trademark Voir le message
    J'en tire comme conclusion que l'adresse de tab2D est 0x0028fd40 et que son contenu est 0x0028fd40. Déjà rien que ça c'est bizarre, un pointeur qui pointe vers lui-même ?

    Ensuite, si c'est le cas, il pointe vers lui même et à un moment (à tab2D[0][0]) il s'arrête, le contenu change et devient 0. Oui je sais que c'est pas vrai mais c'est là que je comprends pas, qu'est-ce qui cloche ?
    En paramètre de fonction, le nom d'un tableau représente un pointeur sur le premier élément de celui-ci. tab2D contient donc l'adresse du premier élément du tableau.
    En outre l'adresse d'un tableau est égale à celle de son premier membre. Ce qui explique que &tab2D et tab2D aient la même valeur (mais pas le même type).

    Dans le cas d'un tableau multidimensionnel, les différents éléments d'un tableau sont contigus en mémoire. Il faut voir ça comme un tableau unidimensionnel (de taille 8*8 soit 64 ici), la notation [x][y] pour accéder à un élément du tableau étant juste une notation permettant de rendre la manipulation de tels tableaux plus simples.
    Or *tab2D (qui est équivalent à tab2D[0]) représente l'adresse de la première ligne du tableau qui est elle aussi égale à l'adresse du tableau et de son premier élément.

    **tab2D pour sa part contient la valeur du premier élément du tableau soit 0 ici.

    Au passage, pour afficher des adresses en C, on utilise %p pas %X et il faut caster le pointeur en void*.

  3. #3
    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 détailler un peu :

    Rappel : Si T est un tableau, alors sauf lorsqu'il est l'opérande des opérateurs sizeof ou & (adresse de), sizeof T ou &T, T est une valeur égale à l'adresse du premier élément de T.

    On a int tab2D[8][8];

    - &tab2D est l'adresse du tableau. Sa valeur va correspondre au début du tableau int[8][8] en mémoire. Le type de cette adresse est int (*)[8][8]

    - tab2D est, dans ce contexte, l'adresse du premier élément du tableau : &tab2D[0].
    Cette valeur va correspondre à l'adresse du premier tableau de tab2D. Il n'est pas étonnant qu'on obtienne la même valeur que précédemment. Toutefois, les éléments du tableau étant des objets tableaux de 8 int, le type est différent : int (*)[8]

    - plus délicat *tab2D : On pourrait s'attendre que puisque tab2D est l'adresse du début du tableau, on obtienne le premier int du tableau.
    Mais non.
    *tab2D est équivalent à *& tab2D[0]. Or l'expression *&X est égale à X. Naturellement, il faut que X soit un objet (on ne parle pas ici des fonctions) pour qu'on puisse prendre son adresse et que &X est un sens. Or tab2D[0] est un bien objet tableau dans le contexte de l'opérateur &.
    Donc *tab2D ~ *& tab2D[0] ~ tab2D[0]. tab2D[0] étant un tableau, ceci est égal, dans ce contexte, à l'adresse de son premier élément donc à l'adresse du premier int du premier tableau de 8 int. Il n'est pas étonnant qu'on obtienne la même valeur que précédemment, mais le type est encore différent : int *

    - La dernière expression ,**tab2D, peut sembler déconcertante, car le double déréférencement n'a en général rien à voir avec les tableaux 2D (on les trouvent avec les tableaux de pointeurs).
    D'après ce qui précède *tab2D est équivalent à tab2D[0] et donc **tab2D ~ *tab2D[0] ~ * & tab2[0][0] ~ tab2[0][0]. Le type est int.


    Note :
    Déjà rien que ça c'est bizarre, un pointeur qui pointe vers lui-même ?
    Un pointeur qui pointe sur lui-même impose que ce pointeur soit un objet, or dans toute cette affaire, il n'y a aucun objet pointeur, seulement des valeurs "adresse de ...". Les seuls objets sont des tableaux et des int.

  4. #4
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Bon je vais vous paraitre dur de comprenur mais :

    Pour moi une case mémoire possède un contenu et une adresse.
    Si l'adresse est la même pour deux cases mémoires alors le contenu doit l'être également.

    Adresse de tab[0][0] : 0028FE40
    Adresse de tab : 0028FE40

    Contenu de tab[0][0] : 0
    Contenu de tab : 0028FE40

    Pourquoi ?

  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
    Il faut voir que si, le plus souvent, à une position mémoire correspond un objet (en C) unique et bien identifié, ce n'est pas le cas si on a un objet aggrégat.

    Par exemple :
    - A la position mémoire X se trouve un tableau de int, mais à cette même position se trouve le premier élément du tableau, un int. Un tableau de int et un int sont en C des objets différents.
    De même, si à la position X se trouve une structure, à cette même position se trouve le premier champ de la structure.

    Donc on peut dire qu'à tout objet correspond une position mémoire unique, mais la réciproque n'est pas vraie : à une position mémoire peuvent se trouver plusieurs objets C de type différents.

    J'emploie à dessein le terme "position mémoire" et non "adresse", parce que, en C, une adresse est un concept plus riche : non seulement, elle repère une position en mémoire, mais elle identifie le type de l'objet à cette position donc lève l'ambiguité lorsqu'à une même position mémoire se trouvent plusieurs objets différents :
    Si on a une adresse A du type T * , alors *A est l'objet de type T situé à l'emplacement mémoire repéré par A.

    -----------
    Si on reprend l'exemple :

    - tab est un tableau situé à la position mémoire M.

    - * tab :
    Comme tab n'est pas opérande de sizeof ou de &, tab est ici du type "adresse d'un élément du tableau tab". Comme c'est l'adresse du premier élément, il repère la position mémoire M.
    *tab sera donc l'élément du tableau situé à la position mémoire M (un tableau dans notre cas).

    - **tab :
    Dans l'exemple, *tab est un tableau et repère la position mémoire M. On peut alors faire le même raisonnement que précédemment pour analyser **tab :
    Comme *tab n'est pas opérande de sizeof ou de &, *tab est ici du type "adresse d'un élément du tableau *tab". Comme c'est l'adresse du premier élément, il repère la position mémoire M.
    **tab sera donc l'élément du tableau *tab situé à la position mémoire M et dans l'exemple, on obtient un int.

  6. #6
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Alors une adresse mémoire est caractérisé par un type et une position mémoire, est-ce valable dans les autres langages ou uniquement en C ?

    En théorie il pourrait y avoir plus d'adresse mémoire que de position mémoire alors ?

    Donc on peut dire qu'à tout objet correspond une position mémoire unique, mais la réciproque n'est pas vraie : à une position mémoire peuvent se trouver plusieurs objets C de type différents.
    Pourtant *tab et tab ont la même position mémoire.

    Une dernière question, depuis le début j'essaye de visualiser un schéma de ce que tout ça pourrait donner. Est-ce que c'est possible de dessiner, de se représenter ces objets ou alors peut-on considérer que ca ferait un paradoxe ?

    Merci à vous.
    Bonne journée.

    Hors sujet : Vous travaillez dans quelle université ?

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

Discussions similaires

  1. [Tableaux] tri de tableau deux dimensions
    Par oursquetaire dans le forum Langage
    Réponses: 8
    Dernier message: 27/12/2005, 14h27
  2. Affichage d'un tableau à deux dimensions.
    Par Allan dans le forum C
    Réponses: 3
    Dernier message: 11/12/2005, 18h29
  3. Réponses: 1
    Dernier message: 18/11/2005, 11h38
  4. tri alphabétique dans un tableau deux dimensions
    Par *!!cocco!!* dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 06/12/2004, 21h38
  5. Passage d'un tableau à deux dimensions
    Par karl3i dans le forum C
    Réponses: 3
    Dernier message: 20/10/2003, 14h50

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