Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Tableaux multidimensionnels et déréférencement

43 réponses
Avatar
Lucas Levrel
Bonjour,

Quelqu'un pourrait-il éclairer ma lanterne sur les points suivants ? Je
prends des exemples bidimensionnels pour simplifier mais je m'intéresse
aux tableaux avec un nombre quelconque de dimensions.

1) Si je déclare
int table[3][4];
table est de type int(*)[4], et table[i] est de type int[4].
Confirmez-vous que néanmoins table[i] n'existe pas en mémoire, et que le
compilateur ne crée qu'un genre de int *t qui pointe vers table[0][0],
puis remplacera table[i] par t+4*i ? (D'où l'obligation que toutes les
dimensions sauf la première soient connues à la compilation.)
Du coup, je n'ai aucun intérêt à déclarer
int table[3*4];
puis à gérer moi-même l'accès à l'élément (i,j) avec table[4*i+j].

2) Passons aux tableaux dynamiques. Par exemple, je veux un tableau de
dimensions (n,p). Je peux faire
int **table=malloc(n*sizeof(int*));
for(int i=0;i<n;i++) int *table[i]=malloc(p*sizeof(int));
table[i][j]= (...)
Alors, lorsque j'accéderai à table[i][j], il y aura déréférencement de
(table+i), *(table+i) contient l'adresse de table[i][0], on y ajoute j
pour trouver l'adresse de table[i][j].

Je peux aussi faire
int *table=malloc(n*p*sizeof(int));
table[p*i+j]= (...)
Alors il n'y aura pas le déréférencement ci-dessus, mais une
multiplication et une addition.

Différence : par la première méthode, 1 déréférencement et 1 arithmétique
de pointeur (= une addition, après compilation ?), par la seconde, une
multiplication et une addition.

Avec D dimensions, ça donne D-1 fois cette différence. L'une des deux
méthodes est-elle plus rapide ? (Si ça dépend de l'architecture, disons
sur un processeur « ordinaire » (Intel ou AMD, pas Cray), en espérant que
cette précision suffise !)

3) Pour la deuxième méthode, afin de rendre le code plus lisible je peux
faire
inline int *element(int i,int j){return table+p*i+j};
*element(i,j)= (...)
ou bien
#define element(i,j) table[p*i+j]
element(i,j)= (...)
Est-ce que ça fait une différence dans le code compilé ?

Merci pour vos lumières !

--
LL

3 réponses

1 2 3 4 5
Avatar
candide
Antoine Leca a écrit :

Que veut dire « tous » ? Les types du C décrivent un ensemble infini
(peut-être même non dénombrable, mais cela fait trop longtemps que ce
sujet ne me préoccupe plus pour que je ne sois pas 100% sûr).



J'aurais dit qu'il y a avait un nombre fini de types [ou infini dénombrable si
on fait abstraction de : 5.2.4.1 Translation limits]
Avatar
espie
In article <4a3aacc4$0$2470$,
candide wrote:
Marc Espie a écrit :


Le fait d'avoir un successeur, c'est deja une structure algebrique, et c'est



Ça dépend ce que tu entends par "successeur". A mon avis, la notion de
"successeur" dans N préexiste à la définition des opérations algébriques sur N,
comme l'addition. Souvent, on définit N par la notion de successeur, de mémoire,
ça donne :


Tu confonds operations algebriques classiques et structure algebrique en
general. Une structure algebrique, c'est un ensemble avec des operateurs.
Ceux-ci peuvent verifier certaines proprietes, a choisir.

0 comme l'ensemble vide,
puis 1 comme l'ensemble {vide}
puis 2 comme 1 union {1} et donc 2={vide,{vide}}
et plus généralement le successeur de x (déjà défini) comme x+=x union {x}.



L'abus de Bourbaki nuit a la sante...

Si on a un ensemble E muni d'une relation R (autrement dit un graphe orienté),
on peut facilement définir la notion de successeur d'un élément x de E en disant
qu'il s'agit de n'importe quel élément y tel que x R y et pour lequel il
n'existe aucun élément z distinct de x ou y tel que x R z et z R y (imaginer une
arborescence par exemple : tous les éléments sauf les feuilles ont un
"successeur").



Ca demande "juste" l'axiome du choix dependant. C'est donc pas gagne pour
un graphe infini (toujours l'abus de Bourbaki)

T'as juste aussi le probleme que ca ne va pas forcement donner ce que tu
voudrais pour un graphe avec cycle...

La notion de successeurs n'est pas si simple que ca, et d'un certain point
de vue, N est effectivement un ensemble muni d'une relation de successeur
qui verifie certaines proprietes... si tu en oublies, tu tombes sur beaucoup
d'autres modeles de la meme relation. Pour certaines applications, il n'est
meme pas clair que N soit le meilleur modele de la relation voulue...

(ne te fatigue pas a commenter la-dessus si tu n'as pas le vocabulaire,
typiquement si tu n'as pas fait un peu de theorie des modeles, au sens branche
de la logique mathematique).

N dote de son successeur habituel, et [0,1[ dote de la topologie triviale ou
tout point est isole).



"Topologie triviale" je vois pas ce que c'est (par contre topologie grossière
OK, topologie discrète OK). "Point isolé " : je vois pas ce que tu veux dire. En
topologie, quand on parle d'un point "isolé" c'est par rapport à une partie, par
exemple chaque élément de N est un point isolé de N pour la topologie
usuelle sur R.



C'est pourtant clair dans le contexte! c'est effectivement la topologie
discrete, vu qu'avec ce successeur, toutes les orbites d'elements sont
deconnectees.
Avatar
Antoine Leca
Le 18/06/2009 21:14, candide écrivit :
Antoine Leca a écrit :

Que veut dire « tous » ? Les types du C décrivent un ensemble infini
(peut-être même non dénombrable, mais cela fait trop longtemps que ce
sujet ne me préoccupe plus pour que je ne sois pas 100% sûr).



J'aurais dit qu'il y a avait un nombre fini de types [ou infini dénombrable si
on fait abstraction de : 5.2.4.1 Translation limits]



5.2.4.1 n'a d'effet que sur les programmes strictement conformes (et le
programme fourni par l'implémentation pour satisfaire cet alinéa).

Le C ne s'arrêtant pas aux programmes s.c. (nonobstant les opinions de
certains participants au forum comp.lang.c), il est indispensable de
faire l'effort de cette abstraction.


Antoine
1 2 3 4 5