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 :

Premières galères avec les tableaux et les pointeurs


Sujet :

C

  1. #21
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    c'est que &tab a une signification, puisque je peux faire ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int tab[10];
    int (*pTab)[10] = &tab; //équivaudrait à int[10]* pTab = &tab;
    La question n'est pas si &tab a ou n'a pas de signification (oui c'est ce que j'ai écrit dans mon dernier post mais c'était une maladresse et j'ai d'ailleurs bien précisé que ma retranscription n'était pas à l'exacte réplique des idées échangées la dernière fois qu'on avait évoqué ce sujet) mais plutôt de savoir si &tab est réellement identique à tab. Comment deux adresses identiques pourraient référencer deux objets différents qui cohabiteraient ensembles ? j'ai essayé d'afficher pTab et *pTab mais j'obtiens la même chose.

    Accessoirement on peut écrire à la place int *pTab=tab et obtenir le même résultat.

    On retrouve d'ailleurs la même question avec les pointeurs de fonctions
    Code c : 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
    #include <stdio.h>
     
    void affiche(int n)
    {
    	printf("%d\n", n);
    }
     
    int main()
    {
    	void (*pt)(int)=affiche;
    	(*pt)(5);  // Ou bien (*************pt)(5)
    	printf("%p\n", pt);
    	printf("%p\n", *pt);
    	printf("%p\n", **pt);
    	printf("%p\n", ***pt);
    	printf("%p\n", ****pt);
    }
    On peut mettre autant d'étoiles que l'on veut dans le printf(), l'adresse affichée est toujours la même. Et on peut de la même façon mettre autant d'étoiles que l'on veut lors de l'appel du pointeur...
    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]

  2. #22
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Comment deux adresses identiques pourraient référencer deux objets différents qui cohabiteraient ensembles ?
    Ce n'est pas choquant, et c'est d'ailleurs le cas avec une structure et le premier champ de la structure. Il y a un rapport d'un objet à un sous-objet.
    Dans le cas évoqué dans la discussion, l'objet est le tableau et le sous-objet son premier élément.

    De plus, dire que les adresses sont identiques est un abus : une adresse en C n'est pas simplement un repère d'une position mémoire, c'es aussi un type et on ne peut pas dissocier les deux. Même si le repère est identique, si le type est différent alors les adresses (en C) sont différentes.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  3. #23
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ah, les pointeurs de fonctions sont une autre paire de manches, car là on tombe sur des trucs qui ne veulent pas dire grand-chose en C (notamment, on a des types "pointeur de fonction" mais pas vraiment de types "fonction", d'ailleurs on ne peut pas faire d'arithmétique de pointeurs sur un pointeur de fonction alors qu'on le peut pour un pointeur de tableau).

    Je pense que le coup des tableaux est assez similaire à celui des structures: Il me semble qu'il y a une garantie en C qu'un pointeur de structure pointe vers la même adresse qu'un pointeur vers son premier champ (garantie absente en C++ dès que la virtualité entre en jeu).

    Edit: Diogene m'a devancé
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #24
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par diogene Voir le message
    une adresse en C n'est pas simplement un repère d'une position mémoire, c'est aussi un type et on ne peut pas dissocier les deux. Même si le repère est identique, si le type est différent alors les adresses (en C) sont différentes.
    Merci de cette précision. Ce qui me donne alors une idée pour "voir" physiquement cette différence: jouer avec l'arithmétique des pointeurs (évoquée aussi par Médinoc)

    Petit exemple
    Code c : 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
    #include <stdio.h>
     
    void affiche(int *tab, int n)
    {
    	int i;
    	printf("Adresse reçue: %p\n", tab);
    	for (i=0; i < n; i++)
    		printf("tab[%d]=%d (%p)\n", i, tab[i], &tab[i]);
    	fputc('\n', stdout);
    }
     
    int main()
    {
    	int tab[][5]={
    		{5, 4, 3, 2, 1},
    		{10, 8, 6, 4, 2},
    	};
    	int (*pt)[5]=tab;
    	affiche(*pt, 5);
    	pt++;
    	affiche(*pt, 5);
    }

    Et le résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Adresse reçue: 0x7fffc0ebf5b0
    tab[0]=5 (0x7fffc0ebf5b0)
    tab[1]=4 (0x7fffc0ebf5b4)
    tab[2]=3 (0x7fffc0ebf5b8)
    tab[3]=2 (0x7fffc0ebf5bc)
    tab[4]=1 (0x7fffc0ebf5c0)
     
    Adresse reçue: 0x7fffc0ebf5c4
    tab[0]=10 (0x7fffc0ebf5c4)
    tab[1]=8 (0x7fffc0ebf5c8)
    tab[2]=6 (0x7fffc0ebf5cc)
    tab[3]=4 (0x7fffc0ebf5d0)
    tab[4]=2 (0x7fffc0ebf5d4)
    Bien que les adresses soient les mêmes au départ, on voit bien que pt++ a fait avancer le pointeur de 20 octets c'est à dire d'un "tableau" de 5 entiers tandis que les sous-adresses n'avancent que de 4 octets. Et on a un résultat proportionnellement équivalent si on prend des tableaux de 6 entiers.

    Merci à vous deux de vos idées
    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. les tableaux et le pointeur !prob
    Par t_zano dans le forum Débuter
    Réponses: 10
    Dernier message: 28/07/2009, 20h09
  2. Problème avec les tableaux et les structures
    Par al-khawarrizmi dans le forum Débuter
    Réponses: 2
    Dernier message: 10/06/2008, 16h17
  3. [Listeners] Les listeners et les tableaux d'objets
    Par TheDoci dans le forum AWT/Swing
    Réponses: 5
    Dernier message: 29/06/2007, 09h43
  4. les tableaux et les colonnes
    Par imsse dans le forum C#
    Réponses: 4
    Dernier message: 22/05/2007, 16h45

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