Logo de kxs.frCours d'informatique pour le lycée et la prépa

Aspects impératifs

Références

En OCaml, même si nous n'avons pas insisté sur ce point, les variables ne sont pas mutables (modifiables). Nous n'avons pas vu d'opérateur permettant de modifier une variable !

# let a = 2;;
val a : int = 2
# a = 2;;
- : bool = true

Il est bien sûr possible de redéfinir une variable mais cela ne modifie pas vraiment sa valeur :

# let a = 2;;
val a : int = 2

Il est tout de même possible de créer des variables mutables en OCaml grâce aux références. Cela ressemble à un pointeur en C (mais avec moins de complications). Il faut utiliser le mot-clé ref :

# let a = ref 2;;
val a : int ref = {contents = 2}

On a alors créé une référence (un pointeur) vers un entier. On peut le déréférencer (comme en C avec *) avec le symbole ! :

# !a;;
- : int = 2

Et pour modifier sa valeur, on utilise le symbole := :

# a := 6;;
- : unit = ()
# !a;;
- : int = 6

1) Écrire une fonction incr qui prend comme argument la référence d'un entier et incrémente cet entier.

# let incr a =
a := !a + 1;;
val incr : int ref -> unit = <fun>

Il est possible de référencer n'importe quel type d'objet :

# let a = ref "abcd";;
val a : string ref = {contents = "abcd"}
# let l = ref [1;2;3];;
val l : int list ref = {contents = [1; 2; 3]}

Boucle for

La syntaxe de la boucle for est assez intuitive. Attention à ne pas oublier le do et le done :

# for i = 1 to 9 do
print_int i
done;;

On peut également utiliser une boucle for en faisant décroitre l'indice :

# for i = 9 downto 0 do
print_int i
done;;

2) Écrire une fonction fact qui n'est pas récursive et qui calcule la factorielle d'un entier en utilisant une boucle for.

# let fact n =
let r = ref 1 in
for i = 1 to n do
r := !r * i
done;
r;;
val fact : int -> int ref = <fun>

Boucle while

Voici un exemple de syntaxe pour la boucle while :

# let i = ref 0 in
while !i < 10 do
i := !i + 1;
print_int !i
done;;
12345678910- : unit = ()

3) Écrire une fonction fact qui n'est pas récursive et qui calcule la factorielle d'un entier en utilisant une boucle while.

# let fact n =
let r = ref 1 and i = ref 1 in
while !i <= n do
r := !r * !i;
i := !i + 1
done;
r;;
val fact : int -> int ref = <fun>

Tableaux

On peut également utiliser des tableaux en Ocaml même si ce n'est pas la vocation première du langage. Les tableaux sont mutables. Voici comment déclarer un tableau, comment accéder à un élément et comment modifier un élélment :

# let t = [|1;2;3;4|];;
val t : int array = [|1; 2; 3; 4|]
# t.(2);;
- : int = 3
# t.(2) <- 8;;
- : unit = ()
# t;;
- : int array = [|1; 2; 8; 4|]

4) Écrire une fonction add qui n'est pas récursive et qui ajoute 1 à tous les éléments d'un tableau.

# let ajoute table =
for i=0 to (Array.length table)-1 do
table.(i) <- table.(i) + 1
done;;
val ajoute : int array -> unit = <fun>

5) Écrire une fonction cherche qui n'est pas récursive et qui cherche un élément dans un tableau.

# let cherche elem table =
let i = ref 0
and trouve = ref false
in
   while (not !trouve && !i < Array.length table) do
      if elem = table.(!i) then
         trouve := true;
      i := !i +1
   done;
   if !trouve then
      !i
   else
      -1
;;
val cherche : 'a -> 'a array -> int = <fun>

Opérations sur les tableaux

Enregistrements mutables

Par défaut un enregistrement n'est pas mutable :

# type point = {x:float; y:float};;
type point = { x : float; y : float; }
# let a = {x=1.;y=2.};;
val a : point = {x = 1.; y = 2.}
# a.x <- 3.;;
Error: The record field x is not mutable

Pour rendre le champ d'un enregistrement mutable, il faut le faire précéder du mot clé mutable :

# type point = {mutable x:float; mutable y:float};;
type point = { mutable x : float; mutable y : float; }
# let a = {x=1.;y=2.};;
val a : point = {x = 1.; y = 2.}
# a.x <- 3.;;
- : unit = ()