OVH Cloud OVH Cloud

tableau et pointeur : question très simple

21 réponses
Avatar
Lip
bonsoir,

dans le code ci-dessous, je ne vois pas pourquoi
je suis obligé de déréférencer 2 fois &tab pour
avoir la valeur pointée (lignes 'ICI') étant donné
que tab et &tab ont les mêmes valeurs.

Mon raisonnement est le suivant, corrigez-moi si j'ai faux :
- tab est un tableau de 3 entiers, le type de tab est donc int[3],
- &tab est l'adresse du tableau de 3 entiers, c'est donc un pointeur
constant(?) vers un tableau de 3 entiers, le type de &tab est donc
int (*p)[3].
Mais &tab est équivalent à tab, à &tab[0] et à tab+0. Après je ne sais
plus...

Merci de bien vouloir me donner des explications simples et "décortiquées".
Lip


#include <stdio.h>
#include <stdlib.h>

int main(void) {

int tab[3] = {1,2,3};

/* les formes de l'adresse du tableau */
printf("Valeur de tab : %p\n", tab);
printf("Valeur de &tab[0] : %p\n", &tab[0]);
printf("Valeur de tab + 0 : %p\n", tab + 0);
printf("Valeur de &tab : %p\n", &tab);

printf("Valeur pointee : %d\n", **&tab); /* ICI */

printf("\n");

/* les formes des valeurs du dernier élément du tableau */
printf("Forme 1 : %d\n", tab[2]);
printf("Forme 2 : %d\n", *tab + 2);
printf("Forme 3 : %d\n", **&tab + 2); /* ICI */

printf("\n");

printf("Adresse du dernier element de tab : %p\n", &tab[2]);


return EXIT_SUCCESS;
}

10 réponses

1 2 3
Avatar
Emmanuel Delahaye
Lip wrote on 25/10/04 :
dans le code ci-dessous, je ne vois pas pourquoi
je suis obligé de déréférencer 2 fois &tab pour
avoir la valeur pointée (lignes 'ICI') étant donné
que tab et &tab ont les mêmes valeurs.


Si tab est un tableau, les valeurs sont les même, mais le type est
différent.

Mon raisonnement est le suivant, corrigez-moi si j'ai faux :
- tab est un tableau de 3 entiers, le type de tab est donc int[3],


Non, c'est int *.

- &tab est l'adresse du tableau de 3 entiers, c'est donc un pointeur
constant(?) vers un tableau de 3 entiers, le type de &tab est donc
int (*p)[3].


Oui.

Mais &tab est équivalent à tab, à &tab[0] et à tab+0. Après je ne sais
plus...


Même valeur, mais pas le même type

#include <stdio.h>
#include <stdlib.h>

int main(void) {

int tab[3] = {1,2,3};

/* les formes de l'adresse du tableau */
printf("Valeur de tab : %pn", tab);
printf("Valeur de &tab[0] : %pn", &tab[0]);
printf("Valeur de tab + 0 : %pn", tab + 0);
printf("Valeur de &tab : %pn", &tab);

printf("Valeur pointee : %dn", **&tab); /* ICI */


'*' et '&' s'annulent, reste *. *tab est bien le contenu de tab + 0,
soit la valeur tab[0].

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"

Avatar
Emmanuel Delahaye
Charlie Gordon wrote on 25/10/04 :
La question a trouvé réponse, mais que dire de ces quelques lignes :

#include <stdio.h>

int main(void) {
printf("main = %pn", (void*)(main));


Comportement indéfini. Le type de main (adresse de fonction) ne peut
pas être converti en (void*) de façon portable (pointeur d'objet).

Le reste à l'avenant.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"

Avatar
Jean-Marc Bourguet
Emmanuel Delahaye writes:

Lip wrote on 25/10/04 :
dans le code ci-dessous, je ne vois pas pourquoi
je suis obligé de déréférencer 2 fois &tab pour
avoir la valeur pointée (lignes 'ICI') étant donné
que tab et &tab ont les mêmes valeurs.


Si tab est un tableau, les valeurs sont les même, mais le type est
différent.

Mon raisonnement est le suivant, corrigez-moi si j'ai faux :
- tab est un tableau de 3 entiers, le type de tab est donc int[3],


Non, c'est int *.


Ah?

$ cat emmanuel.c
#include <stdio.h>
int main() {
int tab[3];
if (sizeof(tab) != sizeof(int*)) {
printf("Pourquoi Emmanuel si le type de tab est int*?n");
}
return 0;
}
$ como433 --c99 -A -o emmanuel emmanuel.c
Comeau C/C++ 4.3.3 (Oct 24 2003 16:00:23) for RedHat_LINUX_INTEL_ELF
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C99

$ ./emmanuel
Pourquoi Emmanuel si le type de tab est int*?

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Charlie Gordon
"Emmanuel Delahaye" wrote in message
news:
Charlie Gordon wrote on 25/10/04 :
La question a trouvé réponse, mais que dire de ces quelques lignes :

#include <stdio.h>

int main(void) {
printf("main = %pn", (void*)(main));


Comportement indéfini. Le type de main (adresse de fonction) ne peut
pas être converti en (void*) de façon portable (pointeur d'objet).



Moi qui croyais justement que void* était potentiellement différent de char*
justement à cause de cela. On m'aurait menti ?
Quel est le format de printf pour convertir la valeur d'un pointeur de fonction
?

Chqrlie.


Avatar
Emmanuel Delahaye
Charlie Gordon wrote on 25/10/04 :
#include <stdio.h>

int main(void) {
printf("main = %pn", (void*)(main));


Comportement indéfini. Le type de main (adresse de fonction) ne peut
pas être converti en (void*) de façon portable (pointeur d'objet).


Moi qui croyais justement que void* était potentiellement différent de char*
justement à cause de cela. On m'aurait menti ?


Euh...

Quel est le format de printf pour convertir la valeur d'un pointeur de
fonction ?


Je n'en connais pas. Afficher l'adresse d'une fonction a un interêt
pratique limité... Le fichier .map des linkers est fait pour ça...

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"



Avatar
Emmanuel Delahaye
Jean-Marc Bourguet wrote on 25/10/04 :
- tab est un tableau de 3 entiers, le type de tab est donc int[3],


Non, c'est int *.


Ah?


Ok, message supprimé.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"



Avatar
Lip

Ok, message supprimé.


Tu l'avais mis aujourd'hui ou hier le message que tu as supprimé ?
Lip

Avatar
Antoine Leca
En 417e85e8$0$295$, Lip va escriure:
Ok, message supprimé.


Tu l'avais mis aujourd'hui ou hier le message que tu as supprimé ?


Message-ID:
Date: Mon, 25 Oct 2004 21:20:18 +0200

Mais les cancels sur Usenet, ce n'est pas d'une efficacité garantie.


Antoine


Avatar
Lip

Mais les cancels sur Usenet, ce n'est pas d'une efficacité garantie.


oui, mais justement, c'était pour déterminer si je l'avais copié/collé
dans mes doc en même temps que toutes les autres réponses. Je ne
voudrais pas avoir copié une erreur.. Et obtenir la réponse ici m'aurait
évité de fouiller dans mes Go de copiés/collés sur ce sur forum.
Lip

Avatar
Lip

Message-ID:


arf.. j'avais pas vu..
Lip

1 2 3