Création et accès aux éléments

La fonction make-array permet de créer un tableau. Cette fonction prend un seul paramètre obligatoire : une liste dont la longueur détermine le rang du tableau créé et dont chaque élément est un entier qui détermine la taille de la dimension correspondante.

La fonction make-array prend aussi des paramètres mots-clés pour indiquer le type des éléments contenus (ce type est t par défaut, indiquant n'importe quel type), un élément initial ou le contenu initial du tableau sous la forme de séquences imbriquées.

Dans le cas où, ni l'élément initial, ni le contenu initial n'est précisé, la norme Common Lisp ne définit pas les conséquences d'un accès à un élément non initialisé. CMU Common Lisp initialise le contenu à 0, mais il est vivement déconseillé d'écrire du code dont le comportement dépende de ce fait.

Voici quelques exemples d'utilisation de make-array :

* (make-array '(2 3) :initial-element 'a)

#2A((A A A) (A A A))
* (make-array '(3 2) :initial-element 'b)

#2A((B B) (B B) (B B))
* (make-array (list 2 *read-base*) :initial-element 5)

#2A((5 5 5 5 5 5 5 5 5 5) (5 5 5 5 5 5 5 5 5 5))
* (make-array '(4 1) :initial-contents '((12) (13) (11) (4)))

#2A((12) (13) (11) (4))
*

write affiche un objet de type tableau avec #, suivi du rang du tableau, suivi des éléments. La fonction read de CMU Common Lisp est capable de reconnaître cette syntaxe, mais ce comportement n'est pas normalisé.

Pour accéder aux éléments d'un tableau, on utilise l'accesseur aref qui permet à la fois de récupérer la valeur d'un élément et (avec setf) de la modifier. Les arguments passés à aref sont un tableau et les indices en nombre égal au rang du tableau. Exemples :

* (defparameter *a* (make-array '(2 3) :initial-element '(a b)))

*A*
* *a*

#2A(((A B) (A B) (A B)) ((A B) (A B) (A B)))
* (aref *a* 1 1)

(A B)
* (setf (aref *a* 1 1) 234)

234
* *a*

#2A(((A B) (A B) (A B)) ((A B) 234 (A B)))
* (aref *a* 1 1)

234
* (eq (aref *a* 0 0) (aref *a* 1 2))

T
*

Le dernier exemple montre que l'expression qui suit le mot-clé :initial-element n'est évaluée qu'une seule fois. Si l'élément initial permet des effets de bord, alors les conséquences peuvent être surprenantes si l'on pense que l'expression est évaluée pour chaque élément :

* *a*

#2A(((A B) (A B) (A B)) ((A B) 234 (A B)))
* (setf (cadr (aref *a* 0 0)) 11)

11
* *a*

#2A(((A 11) (A 11) (A 11)) ((A 11) 234 (A 11)))
*

Irene DURAND
2011-10-14