Skip to content

Effets de bord dans une expression booléenne

30 avril 2017

En parcourant un blog dont j’ai trouvé le lien dans Stack Overflow, je suis tombé sur un exemple de code en C intéressant (qui fonctionne de la même manière en C++ ou Java. Vous trouverez une version Pascal et une version Python de ce code plus bas) :

int x = 0;
int y = 0;
int z = 0;

while (x++ < 5 || y++ < 5) {
    z++;
}

Quelles seront les valeurs de x, y et z après l’exécution de ces instructions ? Ça a l’air simple ? Si vous répondez trop vite, vous tomberez (comme moi) dans le piège !

Pour ceux qui préfèrent le Pascal (il ne doit pas en rester beaucoup hélas…) voici une version équivalente dans ce langage (il n’y a pas d’opérateur de post-incrémentation en Pascal mais j’ai créé la fonction incr qui fait la même chose) :

program piege;

var x, y, z : integer;

function incr(var n : integer) : integer;
begin
    incr := n;
    inc(n);
end;

BEGIN
    x := 0;
    y := 0;
    z := 0;
    while ((incr(x)<5) or (incr(y)<5)) do
        incr(z);
    writeln('x=',x,' y=',y,' z=',z);
END.

Inc est une procédure (pas une fonction) de l’unité standard System du Pascal qui sert à incrémenter une variable passée en paramètre.

En Python, comme en Pascal, l’incrémentation (avec l’opérateur += par exemple) ne peut pas se faire dans une expression.
J’ai donc dû créer une fonction pour l’incrémentation mais il y a un obstacle supplémentaire : en Python les paramètres sont toujours passés par valeur (comme en C ou en Java) et même si la valeur qui est passée est la référence d’un objet, on ne peut pas modifier la valeur d’un objet de type int car il est immuable.
On peut cependant modifier les éléments d’une liste car les listes sont modifiables. Voici donc un programme Python équivalent :

def incr(t,i):
    t[i] += 1
    return t[i]-1

t = [0, 0, 0]
while incr(t,0)<5 or incr(t,1)<5 :
    incr(t,2)
print(t)
Publicités
Laisser un commentaire

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :