next up previous contents index
Next: Vecteurs et tableaux Up: Un exemple simple Previous: Phrases

Références

   

Les variables de Caml ne sont donc pas des variables au sens traditionnel des langages de programmation, puisqu'il est impossible de modifier leur valeur. Il est pourtant souvent nécessaire d'utiliser dans les programmes des variables modifiables au sens de Pascal ou de C. En Caml, on utilise pour cela une référence modifiable vers une valeur, c'est-à-dire une case mémoire dont on peut lire et écrire le contenu. Pour créer une référence, on applique le constructeur ref au contenu initial de la case mémoire. C'est le cas pour la variable i, définie par la ligne let i = ref (n - 1), dont la valeur est une référence qui contient n - 1 à la création. Pour lire le contenu d'une référence, on utilise l'opérateur !, qu'on lit ``contenu de'' (ou ``deref'' car on l'appelle aussi opérateur de déréférencement). Pour écrire le contenu d'une référence on utilise l'opérateur d'affectation :=. Par exemple, i := !i + 1 incrémente le contenu de la référence de la variable i, ce qui a finalement le même effet que l'affectation i := i + 1 de Pascal ou l'affectation i = i + 1 de C. Noter que les références ne contredisent pas le dogme ``une variable est toujours liée à la même valeur'': la variable i est liée à une unique référence et il est impossible de la changer. Plus précisément, la valeur de i est l'adresse de la case mémoire modifiable qui contient la valeur, et cette adresse est une constante. On ne peut que modifier le contenu de l'adresse.

Le connaisseur de Pascal ou de C est souvent troublé par cette distinction explicite entre une référence et son contenu qui oblige à appliquer systématiquement l'opérateur ! pour obtenir le contenu d'une référence, alors que ce déréférencement est implicite en Pascal et en C. En Caml, quand i a été défini comme une référence, la valeur de i est la référence elle-même et jamais son contenu: pour obtenir le contenu, il faut appliquer une opération de déréférencement explicite et l'on écrit !i. Sémantiquement, !i est à rapprocher de *i en C ou i^ en Pascal.

L'opérateur d'affectation := doit être rapproché aussi des opérateurs ordinaires dont il a le statut, e1 := e2 signifie que le résultat de l'évaluation de e1 est une référence dont le contenu va devenir la valeur de e2 (de même que e1 + e2 renvoie la somme des valeurs de e1 et e2). Évidemment, dans la grande majorité des cas, la partie gauche de l'affectation est réduite à un identificateur, et l'on affecte simplement la référence qui lui est liée. Ainsi, en écrivant i := !i - 1, on décrémente le contenu de la référence i en y mettant le prédécesseur de son contenu actuel. Cette opération de décrémentation est d'ailleurs prédéfinie sous la forme d'une procédure qui prend une référence en argument et la décrémente:

 

let decr x =
  x := !x - 1;;

Dans cet exemple, la distinction référence-contenu est évidente: l'argument de decr est la référence elle-même, pas son contenu. Cette distinction référence-contenu s'éclaire encore si l'on considère les références comme des vecteurs à une seule case: c'est alors un prolongement naturel de la nécessaire distinction entre un vecteur et le contenu de ses cases.

L'opérateur d'affectation en Caml pose une petite difficulté supplémentaire aux habitués des langages impératifs: comme nous venons de le voir, l'écriture e1 := e2 impose que le résultat de l'évaluation de e1 soit une référence. Pour des raisons de typage, il n'est donc pas question d'utiliser le symbole := pour affecter des cases de vecteurs, ni des caractères de chaînes, ni même des champs d'enregistrement. Chacune de ces opérations possède son propre opérateur (où intervient le symbole <-).

En Caml, l'opérateur := est réservé aux références.  

next up previous contents index
Next: Vecteurs et tableaux Up: Un exemple simple Previous: Phrases

1/11/1998