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

10 réponses

1 2 3 4 5
Avatar
Gabriel Dos Reis
ld writes:

[...]

| >  Disons qu'il faut arriver à exprimer un infini non déno mbrable avec
| > un nombre fini de symbole, et c'est pas évident à faire avec
| > une sémantique raisonnable.
|
| Sans aller chercher bien, loin, le lambda calcul le permet parce
| qu'une fonction peut se renvoyer elle-même. Par exemple x.xx ne peut
| pas être type parce qu'il ne peut pas être réduit (expansi on infinie).

Cela dépend de la version du lambda calcul. Ce que tu dis est vrai da ns
la théroie du lambda calcul simplement typé. Par contre,

x . x x

est typeable dans la théorie des types avec intersection; le type est

(S / (S -> T)) -> T

où S et T sont des variables de type arbitraites.
Vori page 46 de

http://projecteuclid.org/DPubS?verb=Display&version=1.0&service=UI &handle=euclid.ndjfl/1040067315&page=record

Je sais que c'est anathème sur ce forum, mais je ne peux resister à  
l'envie d'écrire

struct S {
S operator()(S s) const { return s; }
};

S apply_self(S s) { return s(s); }

int main() {
S s = apply_self(S());
}

:-)

-- Gaby
Avatar
Manuel Pégourié-Gonnard
Marc Espie scripsit:

ld wrote:
dénombrable veut dire qu'on peut les compter ou autrement dit, trouver
le successeur d'un élément. Ca n'a rien à voir avec le nombre
d'éléments de l'ensemble, mais avec la possibilité de les énumérer
(discret vs continu).





Euh, si, être dénombrable ça a tout à voir avec le nombre d'éléments,
puisque ça veut dire avoir le même cardinal que N.

La notion de denombrabilite n'a rien a voir avec l'idee de discret vs
continu.



Bien d'accord, mais j'en profite pour préciser un source possible de
confusion : on dit parfois d'un ensemble ayant le cardinal de R qu'il a
la puissance du continu, donc le sens du mot continu dépend un peu du
contexte. Par contre, dans « discret vs continu », a priori on pense
plutôt à une topologie, ce qui n'a que peu à voir avec le cardinal de
l'ensemble.

On peut revenir au sujet ?



volontier ;-)



Avec plaisir aussi, mais j'y reviendrai sans hesiter des que je verrais des
enormes conneries. ;-)



Désolé d'avoir rajouté un message au HS, j'étais pas sûr que la
confusion sur le sens de continu soit bien dissipée.

--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Avatar
espie
In article ,
Manuel Pégourié-Gonnard <mpg+ wrote:
Bien d'accord, mais j'en profite pour préciser un source possible de
confusion : on dit parfois d'un ensemble ayant le cardinal de R qu'il a
la puissance du continu, donc le sens du mot continu dépend un peu du
contexte. Par contre, dans « discret vs continu », a priori on pense
plutôt à une topologie, ce qui n'a que peu à voir avec le cardinal de
l'ensemble.



C'est surtout qu'on ne sait pas s'il y a quelque chose strictement compris
entre N et R, cote denombrement.

Si j'ai bonne memoire, je crois meme que ca ne peut pas se demontrer
(mais ca fait longtemps)...

Cote topologie, pas sur qu'il y ait grand risque de confusion. Soit les gens
savent de quoi ils parlent (et la notion de cardinal/ordinal/topologie sera
claire pour eux), soit c'est de toutes facons tres flou. Et dans ce cas, on
peut laisser tomber d'avance... les problemes de denombrement sur ensemble
infini n'ont rien d'intuitif et demandent un minimum de rigueur...
Avatar
ld
On 15 juin, 17:50, (Marc Espie) wrote:
In article .com>,
ld   wrote:
>dénombrable veut dire qu'on peut les compter ou autrement dit, trouver
>le successeur d'un élément. Ca n'a rien à voir avec le nombre
>d'éléments de l'ensemble, mais avec la possibilité de les énum érer
>(discret vs continu).

Non, ce qui est dit est juste, tu l'as juste sorti de son contexte, et
forcement quand tu prends juste un fragment, ca ne veut plus rien dire.



Même en relisant, je la trouve ambiguë. Mais je comprends ce que tu
voulais dire.

La notion de denombrabilite n'a rien a voir avec l'idee de discret vs
continu.



C'était pour donner une image intuitive à Antoine. Ceci dit, si tu
peux démontrer qu'un ensemble indénombrable n'est pas continu...

 Je te fabrique quand je veux des ensembles non denombrables
en utilisant des nombres entiers (par exemple, l'ensemble des parties
de N, tiens...)



Je n'ai pas dit le contraire, mais j'attends la démonstration qu'il
n'est pas continu ;-)

>une suite infinie d'entiers est donc dénombrable.
>N, Z, D, Q sont dénombrables, R et C ne le sont pas.

>> On peut revenir au sujet ?

>volontier ;-)

Avec plaisir aussi, mais j'y reviendrai sans hesiter des que je verrais d es
enormes conneries. ;-)



a+, ld.
Avatar
ld
On 15 juin, 18:47, Gabriel Dos Reis wrote:
ld writes:

[...]

| >  Disons qu'il faut arriver à exprimer un infini non dénombrable avec
| > un nombre fini de symbole, et c'est pas évident à faire avec
| > une sémantique raisonnable.
|
| Sans aller chercher bien, loin, le lambda calcul le permet parce
| qu'une fonction peut se renvoyer elle-même. Par exemple x.xx ne peut
| pas être type parce qu'il ne peut pas être réduit (expansion infi nie).

Cela dépend de la version du lambda calcul.  Ce que tu dis est vrai d ans
la théroie du lambda calcul simplement typé.  Par contre,

    x . x x

est typeable dans la théorie des types avec intersection; le type est

      (S / (S -> T)) -> T

où S et T sont des variables de type arbitraites.
Vori page 46 de

   http://projecteuclid.org/DPubS?verb=Display&version=1.0&servic e=UI&ha...



Je n'en avais jamais entendu parler. Je lirais ça à tête reposée, m ais
a première vue ca à l'air dense et c'est pas sûr que je comprenne
tout... Il y a des applications concrètes?

Je sais que c'est anathème sur ce forum, mais je ne peux resister à
l'envie d'écrire

     struct S {
       S operator()(S s) const { return s; }
     };

     S apply_self(S s) { return s(s); }

     int main() {
       S s = apply_self(S());
     }

:-)



Joli tour de passe-passe. Mais

struct S {
S operator()() const { return (*this)(); }
};

int main() {
S s = s();
}

Montre bien que S et S::operator()() n'ont pas le même type ;-)

a+, ld.
Avatar
ld
On 15 juin, 19:48, Manuel Pégourié-Gonnard <mpg+
wrote:
Marc Espie scripsit:

> ld   wrote:
>>dénombrable veut dire qu'on peut les compter ou autrement dit, trouve r
>>le successeur d'un élément. Ca n'a rien à voir avec le nombre
>>d'éléments de l'ensemble, mais avec la possibilité de les énum érer
>>(discret vs continu).

Euh, si, être dénombrable ça a tout à voir avec le nombre d'él éments,
puisque ça veut dire avoir le même cardinal que N.



Je ne sais pas pourquoi je l'ai dit comme ca, mea-culpa. Je pensais a
infini de N (aleph-0) vs infini de R (aleph-1) pour exprimer
dénombrable vs indénombrable. Les deux sont infinis, et comme c'est
pas évident pour tout le monde qu'il y ait des infinis "plus grand"
que d'autres, je voulais l'exprimer par discret vs continu, au lieu du
"nombre" d'éléments.

> La notion de denombrabilite n'a rien a voir avec l'idee de discret vs
> continu.

Bien d'accord, mais j'en profite pour préciser un source possible de
confusion : on dit parfois d'un ensemble ayant le cardinal de R qu'il a
la puissance du continu, donc le sens du mot continu dépend un peu du
contexte. Par contre, dans « discret vs continu », a priori on pense
plutôt à une topologie, ce qui n'a que peu à voir avec le cardinal de
l'ensemble.



Je pensais à l'image qu'évoque "l'hypothèse du continu": discret
(aleph-0) vs continu (aleph-1), même si c'est toujours qu'une
hypothèse.

Désolé d'avoir rajouté un message au HS, j'étais pas sûr que la
confusion sur le sens de continu soit bien dissipée.



;-)

a+, ld.
Avatar
espie
In article ,
ld wrote:
On 15 juin, 17:50, (Marc Espie) wrote:
 Je te fabrique quand je veux des ensembles non denombrables
en utilisant des nombres entiers (par exemple, l'ensemble des parties
de N, tiens...)



Je n'ai pas dit le contraire, mais j'attends la démonstration qu'il
n'est pas continu ;-)



Tu appelles quoi continu ? parce que cote topologie, l'ensemble des parties
de N n'a rien qui se rapproche de R (meme s'ils sont de meme cardinal).

Faire des trucs plus gros, c'est fondamentalement trivial. Faire des
trucs de cardinal intermediaire entre aleph-0 et aleph-1, tu sais comme moi que
c'est axiomatique.... ;-)
Avatar
Gabriel Dos Reis
ld writes:

| On 15 juin, 18:47, Gabriel Dos Reis wrote:
| > ld writes:
| >
| > [...]
| >
| > | >  Disons qu'il faut arriver à exprimer un infini non dà ©nombrable avec
| > | > un nombre fini de symbole, et c'est pas évident à faire a vec
| > | > une sémantique raisonnable.
| > |
| > | Sans aller chercher bien, loin, le lambda calcul le permet parce
| > | qu'une fonction peut se renvoyer elle-même. Par exemple x.xx ne peut
| > | pas être type parce qu'il ne peut pas être réduit (exp ansion infinie).
| >
| > Cela dépend de la version du lambda calcul.  Ce que tu dis es t vrai dans
| > la théroie du lambda calcul simplement typé.  Par contre,
| >
| >     x . x x
| >
| > est typeable dans la théorie des types avec intersection; le type est
| >
| >       (S / (S -> T)) -> T
| >
| > où S et T sont des variables de type arbitraites.
| > Vori page 46 de
| >
| >    http://projecteuclid.org/DPubS?verb=Display&version=1. 0&service=UI&ha...
|
| Je n'en avais jamais entendu parler. Je lirais ça à tête r eposée, mais
| a première vue ca à l'air dense et c'est pas sûr que je co mprenne
| tout... Il y a des applications concrètes?

Oui : analyse statique de code, représentation intermédiaire dans les
compilateurs pour la génération avancée de code guidée par la sémantique
de type, etc. Il y a une vaste bibliographie sur le sujet

http://www.macs.hw.ac.uk/~jbw/itrs/
http://www.macs.hw.ac.uk/~jbw/itrs/bibliography.html

| > Je sais que c'est anathème sur ce forum, mais je ne peux resister à
| > l'envie d'écrire
| >
| >      struct S {
| >        S operator()(S s) const { return s; }
| >      };
| >
| >      S apply_self(S s) { return s(s); }
| >
| >      int main() {
| >        S s = apply_self(S());
| >      }
| >
| > :-)
|
| Joli tour de passe-passe. Mais
|
| struct S {
| S operator()() const { return (*this)(); }
| };
|
| int main() {
| S s = s();
| }
|
| Montre bien que S et S::operator()() n'ont pas le même type ;-)

Le point fondamental des types avec intersection, c'est justement que ces
différentes versions ne sont pas exclusives : elles peuvent coexister.
C'est pour cela que x . xx est typable :-)

-- Gaby
Avatar
Manuel Pégourié-Gonnard
ld scripsit:

Bien d'accord, mais j'en profite pour préciser un source possible de
confusion : on dit parfois d'un ensemble ayant le cardinal de R qu'il a
la puissance du continu, donc le sens du mot continu dépend un peu du
contexte. Par contre, dans « discret vs continu », a priori on pense
plutôt à une topologie, ce qui n'a que peu à voir avec le cardinal de
l'ensemble.



Je pensais à l'image qu'évoque "l'hypothèse du continu": discret
(aleph-0) vs continu (aleph-1), même si c'est toujours qu'une
hypothèse.



Cf ma réponse à Marc sur le statut de ce qu'on appelle encore une
hypothèse, mais qui est en fait une proposition indépendante de ZFC.

Par contre j'insiste, « (fini ou) dénombrable » et « discret » ça n'a
rien à voir (pas plus que « infini non dénombrable » et « continu »). Le
vocabulaire « puissance du continu » et « hypothèse du continu » est un
héritage historique àmha malheureux, provenant peut-être d'une confusion
qui a existé historiquement, mais qui n'a plus lieu d'être.

Désolé d'avoir rajouté un message au HS, j'étais pas sûr que la
confusion sur le sens de continu soit bien dissipée.



;-)



Ceci dit, si vous voulez en papoter plsu en détails, mon petit doigt me
dit qu'on pourrait se téléporter sur fr.sci.math :-)

--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Avatar
Marc Boyer
On 2009-06-15, ld wrote:
On 15 juin, 15:12, Marc Boyer
wrote:
On 2009-06-15, Marc Espie wrote:

> In article <h0qqis$,
> Antoine Leca   wrote:
>>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).

> N'importe quoi.



 Disons qu'il faut arriver à exprimer un infini non dénombrable avec
un nombre fini de symbole, et c'est pas évident à faire avec
une sémantique raisonnable.



Sans aller chercher bien, loin, le lambda calcul le permet parce
qu'une fonction peut se renvoyer elle-même. Par exemple x.xx ne peut
pas être type parce qu'il ne peut pas être réduit (expansion infinie).



Faut encore prouver que cet infini là est non dénombrable.
Est-ce qu'on arrive à le mettre en isomorphisme avec N^* ou N^N ?
Je ne m'avancerais pas.

> Oui, il y a des trucs marrants en theorie des types. Mais il faut du typage
> automatique pour sortir des trucs exprimables par le systeme de types... et
> c'est bien le souci, en general.

   Voui, avec des constructeurs universels et existentiels, et
un petit point fixe, on doit pouvoir jouer...
   M'enfin, on doit être loi du C...



Si c'est typé, ça devrait être dénombrable.



Parce que tu manques d'ambition ;-)
Non, c'est clair qu'on préfère un système de type qui soit
décidable (histoire de pouvoir faire de la vérif des types avec
un compilateur), où au moins pas trop indécidable (pour pouvoir
"en général" trouver le type), et qu'intutivement, ça va
nous rammener dans un truc pas trop compliqué à gérer avec
un ordinateur (machine discrete), donc dénombrable surement.

Mais bon... Ce devrait être un exercice d'info théo que
de définir un langage dont le système de types est continu.

Marc Boyer
--
Au XXIème siècle, notre projet de société s'est réduit
à un projet économique...
1 2 3 4 5