next up previous contents index
suivant: 2.3 Branchements et aiguillages monter: 2. Variables et instructions précédent: 2.1 Variables et affectation   Table des matières   Index


2.2 Instructions

Les instructions (en anglais statement) ont pour rôle d'opérer sur la mémoire et de contrôler l'exécution du programme. Celles-ci ne peuvent figurer que dans le corps d'une fonction (ou dans un bloc statique). Une instruction est soit une instruction simple, soit une instruction composée. Voici des instructions simples (d'autres catégories seront présentées ultérieurement) :

Voici des instructions composées :


2.2.0.0.1 Affectations

Réaliser une affectation de la forme var = exp consiste à évaluer l'expression exp, ce qui produit une valeur, puis à écrire cette valeur dans la variable var.

Il arrive souvent que l'on affecte à une variable le résultat d'une opération binaire entre celle-ci et une autre expression : $\mathtt{a=a}\ op\ \mathtt{exp}$. Il est alors possible d'avoir recours à la notation abrégée: $\mathtt{a}\ op\mathtt{=exp}$. On écrira ainsi : x+=y au lieu de x=x+y et x/=2 au lieu de x=x/2. Outre la simplification d'écriture, l'utilisation de cette syntaxe peut avoir des effets importants sur le comportement et l'efficacité du programme.

2.2.0.0.2 Blocs

Un bloc d'instructions est formé d'une suite de déclarations et d'instructions (simples ou composées), encadrée par « { » et « } ». Par exemple, le bloc suivant est formé de la déclaration de la variable locale t et de deux affectations :

    {
      int t = x%y;
      x = y;
      y = t;
    }

Notons que le corps d'une fonction est un bloc et qu'un bloc peut être vide, ce qu'on écrit simplement {}.


2.2.0.0.3 Portée

La portée d'un nom de variable locale s'étend à tout le bloc où ce nom est déclaré :

  {
    {               
      int n = 2;
    }
    p = n;      // hors de la portée de la déclaration précédente
  }

Notons qu'il est illégal de déclarer une variable locale de même nom qu'un paramètre, de déclarer plusieurs fois la même variable locale dans un même bloc ou dans un bloc imbriqué, et cela même si les types sont distincts :

  static void f(int x) {
    char x;           // ILLÉGAL : x est déjà un paramètre
    int n = 3;
    int n;            // ILLÉGAL : n est déjà une variable locale
    {
      double n = 4;   // ILLÉGAL : n est déjà une variable locale
    }
  }

Un même nom peut apparaître à plusieurs endroits dans un programme : on parle des occurrences de ce nom. Il y a une et une seule occurrence de déclaration, dans sa portée, et des occurrences d'utilisation. Quand on voit une occurrence d'utilisation d'un nom, il faut pouvoir remonter à sa déclaration :

    int n = 2;          // occurrence de déclaration de n
    // ...
    p = n;              // occurrence d'utilisation de n


2.2.0.0.4 Passage par valeur

La description des opérations réalisées lors de l'invocation d'une fonction spécifie la relation entre l'argument, qui figure dans l'expression d'invocation, et le paramètre correspondant, qui figure dans la définition de la fonction : pour chaque paramètre d'une fonction, et pour chaque invocation, il y a création d'une variable dans son cadre d'invocation et initialisation de cette variable par la valeur de l'argument correspondant. Les affectations à un paramètre ne peuvent donc pas modifier la valeur de l'argument correspondant quand cet argument est une variable. Par exemple, la procédure PassageParValeur.test suivante, après avoir initialisé le paramètre x à la valeur de l'argument n, lui affecte 0 (et n'en fait rien d'utilisable), mais ne modifie évidemment pas n, variable locale de PassageParValeur.main :

package exemples;

class PassageParValeur {
  static void test(int x) {
    x = 0;
  }
  public static void main(String[] args) {
    int n = 4;
    test(n);                               // n n'est pas modifiée
    System.out.println("n = " + n);        // --> n = 4
  }
}

2.2.0.0.5 Les fonctions des informaticiens (suite)

Désormais, la valeur retournée par une fonction dépend non seulement des valeurs des arguments, mais aussi de l'état courant de la mémoire, qui est représenté dans l'exemple suivant par la valeur de la variable de classe état :

package exemples;

class FonctionImperative {
  static int état = 0;
  static int f(int x) {
    état++;
    return x + état;
  }
  public static void main(String[] args) {
    System.out.println("f(0) = " + f(0));        // --> f(0) = 1
    System.out.println("f(0) = " + f(0));        // --> f(0) = 2
    System.out.println("f(0) = " + f(0));        // --> f(0) = 3 
  }
}

La propriété caractéristique du style applicatif (la valeur d'une expression ne dépend que des valeurs des sous-expressions et de l'opération qui les combine) n'est donc plus valable.


next up previous contents index
suivant: 2.3 Branchements et aiguillages monter: 2. Variables et instructions précédent: 2.1 Variables et affectation   Table des matières   Index
Rene' LALEMENT 2001-11-07