## Stocker et manipuler des données

Les programmes que nous avons écrit jusque là passent à coté d'un point fondamental en informatique. En effet, la science informatique est celle de traiter des données grâce à des instructions. Dans le monde des buggles, les principales données sont cachées derrière la représentation graphique, mais ce n'est pas une raison pour ne jamais manipuler explicitement des données.

### Les données en [!thelang]

Dans un programme, on peut utiliser différents types de données, tels que les entiers, les nombres à virgules ou les chaînes de caractères. Si on veut utiliser une donnée plusieurs fois, il faut la stocker dans une variable, qui est une sorte de case contenant une valeur: vous rangez votre donnée (disons '5') dans la variable (disons «longueur»), et vous pouvez la retrouver plus tard quand vous en avez besoin. C'est exactement comme prendre une boîte avec une étiquette (disons «cadeau») et d'y ranger quelque chose dedans (disons, un flacon de Channel Numéro 5).

### Déclaration de Variables

Il est très simple de déclarer (c'est-à-dire, créer) une variable en [!thelang]. Il suffit d'écrire [!java]son type, une espace et le nom de la variable.[/!] [!scala]le mot-clé `var`, le nom de la variable, deux points (:), le type de la variable, un signe égal (=) et une valeur initiale.[/!] [!python]le nom de la variable, un signe égal (=) et sa valeur initiale.[/!] Le nom de la variable est un label pour la retrouver plus tard[!python].[/!] [!java|scala] tandis que son type est le genre de données qu'on va pouvoir stocker dans cette variable.[/!] Il est interdit de mettre des espaces dans les noms de variable. On peut nommer une variable `dejaFait`, mais `deja fait` n'est pas un identificateur de variable valide.

[!c|java]

Ainsi, pour créer une variable nommée x contenant des entiers, on écrira :

    int x;

Si vous le souhaitez, vous pouvez donner une valeur initiale à votre variable en ajoutant le symbole égal (=) suivi d'une valeur après la déclaration.

    int x=5;

[/!] [!python]

Ainsi, pour une variable ayant la valeur initiale 5, il faut écrire :

    x = 5

[/!] [!scala]

Ainsi, pour créer une variable nommée x contenant des entiers avec 42 en valeur initiale, on écrira :

    var x:Int = 42

Dans la plupart des cas, le compilateur est capable de deviner le type de la variable d'après la valeur initiale. On peut alors omettre le type de la variable:

    var x = 42

Il est nécessaire de spécifier le type de la variable lorsque l'on initialise ses variables avec des valeurs génériques, telles que la valeur très particulière `null`, dont le type se trouve être ambigu. Même quand le type est clair, vous pouvez le spécifier si vous le souhaitez. Ainsi, pour une variable contenant 5 en valeur initiale, on peut écrire:

    var x: Int =  5 // je peux quand même donner le type si je veux
    var y = 10       // ou bien je peux l'omettre

[/!] [!java|scala|c]

Comme vous pouvez le voir, les variables sont typées en [!thelang]. Cela veut dire qu'elles sont en quelque sorte spécialisées: une variable donnée ne peut stocker qu'un type de données spécifique. N'essayez même pas de ranger des nombres dans une variable faite pour recevoir des lettres ! On dit que [!thelang] est un langage typé statiquement.

D'autres langages (comme le python) sont moins regardants, et on peut ranger n'importe quel type de données dans n'importe quelle variable sans restriction. À première vue, cela semble plus simple, mais ce genre de restriction permet au compilateur de détecter plus d'erreurs de logiques pour vous, ce qui n'est pas dommage. En quelque sorte, il est plus facile d'écrire du python, mais le typage empêche certaines erreurs de se glisser dans vos programmes.

Voici quelque uns des types de données existants en [!thelang] :

- [!java|c]int[/!][!scala]Int[/!], pour les entiers;
- [!java|c]double[/!][!scala]Double[/!], pour les nombres à virgule;
- [!c]int[/!][!java]boolean[/!][!scala]Boolean[/!], pour les booléens, c'est-à-dire les variables dont la valeur est soit "[!c]1[/!][!java|scala]vrai[/!]" soit "[!c]0[/!][!java|scala]faux[/!]";
- [!c]char*[/!][!java|scala]String[/!], pour les chaînes de caractères.

[/!] [!python]

Comme vous pouvez le voir, les variables ne sont pas typées en Python, ce qui veut dire qu'elles ne sont pas spécialisées sur un type de données particulier. Il est tout à fait envisageable de stocker des nombres dans une variable, puis d'y mettre des lettres un peu plus tard. Les valeurs elles-mêmes ont bien entendu un type, mais pas les variables. On dit alors que python est un langage dynamiquement typé.

D'autres langages (comme le Java, le Scala ou le C) sont plus restrictifs et imposent de spécialiser chaque variable pour un type donné (on dit que ce sont des langages statiquement typés). Cela semble bien plus contraignant à première vue, mais ce genre de restriction permet au compilateur de détecter plus d'erreurs de logique pour vous. D'une certaine manière, il est plus facile d'écrire du Python, mais le typage de ces langages empêche certaines erreurs de se glisser dans les programmes.

[/!]

Si vous savez que votre «variable» ne va jamais changer de valeur (par exemple parce qu'il s'agit de la taille de l'écran ou une autre constante du genre), alors vous devriez en faire une valeur plutôt qu'une variable. Utilisez simplement le mot-clé `val` au lieu de `var`. Le compilateur pourra alors faire plus de vérifications pour aider les étourdis cherchant à modifier les constantes. Plus intéressant, le compilateur parvient également à produire du code plus rapide dans certains cas.

C'est la même histoire pour les chaînes, nombres à virgule flottante et les booléens.

    char* nom = "Martin Quinson";
    double taille=1.77; // en mètres
    boolean marie=1; // Signifie vrai; le contraire (faux) s'écrirait 0

    String nom = "Martin Quinson";
    double taille=1.77; // en mètres
    boolean marie=true; // Signifie vrai; le contraire (faux) s'écrirait "false"

    val nom:String = "Martin Quinson"; // impossible de le modifier (c'est une valeur)
    var taille: Double = 1.77; // en metre
    var marie = true; // Signifie vrai; le contraire (faux) s'écrirait "false"
    // Scala sait que 'true' est une valeur de type Boolean, pas besoin de le répéter

    prenom = "Martin"
    nom = 'Quinson' # les simples et les doubles quotes fonctionnent ici
    devise = "Je ne finis jam' (mais je continue d'essayer)" # avoir des quotes simples dans des doubles quotes fonctionne
    taille=1.77 # en mètre
    marie=True # Signifie 'vrai'; le contraire (faux) serait marqué 'False'

### Affectations

Une fois que votre variable est déclarée, vous pouvez y affecter une nouvelle valeur plus tard dans votre programme. C'est vraiment très simple :

    x = 3[!java|c];[/!]

À droite du signe égal, on peut mettre une expression quelconque, qui peut contenir des constantes, des variables et des opérations :

    x = 3 + 2[!java|c];[/!]
    x = 3 * x[!java|c];[/!]
    [!java|scala|python]greeting = "Hello "+name[!java];[/!] [!python]#[/!][!scala|java]//[/!] + est (également) l'opérateur pour concaténer les chaînes (càd pour les fusionner)[/!]

### Objectif de cet exercice

Il est temps de faire un exercice un peu plus dur, n'est ce pas ? L'objectif cette fois est d'avancer jusqu'au biscuit qui se trouve devant la buggle, le ramasser, revenir à la position initiale, puis de poser le biscuit.

### Comment faire ?

Pour résoudre ce problème, il faut le décomposer en parties que vous savez résoudre. Par exemple, on peut vouloir faire les étapes suivantes :

1. Avancer jusqu'à se trouver sur un biscuit
2. Ramasser le biscuit au sol
3. Reculer du même nombre de cases que ce qu'on a avancé
4. Reposer le biscuit au sol

Bien entendu, il est impossible de reculer du bon nombre de case à l'étape 3 si l'on a pas compté le nombre de pas faits à la première étape. On va pour cela utiliser une variable, que l'on peut nommer `nbPas`.

On crée cette variable (de type `int`) avant l'étape 1, on l'initialise à 0, et chaque fois qu'on avance d'un pas, on l'incrémente de 1 (`nbPas = nbPas + 1;`[!java|c] ou `nbPas++;`, les deux écritures sont équivalentes[/!]).

[!python|scala]

Si vous connaissez le Java ou d'autres langages du genre, vous serez probablement tenté d'utiliser l'opérateur `++` pour incrémenter la variable. Malheureusement, cet opérateur n'existe pas en [!thelang]. C'est parce qu'il serait difficile de savoir quoi faire quand on l'applique à un nombre complexe ou à une chaîne de caractères. Le problème ne se pose pas en Java, où ++ est défini pour le type `int` qui n'est pas un type d'objet mais un type primitif (si vous ne connaissez pas l'opérateur ++, ignorez simplement ce paragraphe : cela n'existe pas en [!thelang]).

[/!]

Ensuite, l'étape 3 consiste simplement à créer une nouvelle variable entière `dejaFait` initialisée à zéro, et reculer d'un pas tant que `dejaFait` n'est pas égal à `nbPas`, en incrémentant `dejaFait` à chaque fois. Il faut utiliser l'opérateur `!=` pour tester l'inégalité entre deux valeurs.

À vous de jouer !