Un algorithme est une suite d’actions exécutées en un temps fini. Ces actions s’appliquent à des données pour les transformer et/ou créer de nouvelles données.
Processus systématique de résolution d'un problème
C'est une suite finie et non-ambiguë d'opérations
Les données auxquelles s’appliquent un algorithme forment l'entrée de l’algorithme.
Les données produites par un algorithme forment la sortie de l’algorithme.
Un algorithme est là pour résoudre un problème.
Plus précisément, il va permettre à la machine de le résoudre !
Note : il peut y avoir plusieurs solutions pour atteindre le même résultat
En pratique, à la fin du semestre
Ajoutons un peu d'interactivité
Est ce que vous comprenez le principe ?
Est ce que vous avez déja reçu des enseignements d'informatique au cours de votre parcours ?
Etant donné un triangle de dimensions a, b, c. Ce triangle est-il rectangle sachant que c est le plus grand côté ?
L'algorithmique est un ensemble de concepts qui permettent de décrire un raisonnement de sorte à le rendre reproductible par tous et surtout par une machine
Le nombre de concepts à connaître n'est pas très important
Et pourtant en les combinant, on peut décrire des raisonnements très complexes.
C, C++, Java, Javascript, PHP, Python, Perl, C#, Processing... Tous les langages mettent en oeuvre les concepts de l'algorithmique.
L'algorithme permet de décrire des raisonnements. Les langages permettent de les programmer sur machine.
La conception d'un algorithme précède toujours sa programmation sur machine ! Ne jamais vouloir faire les deux à la fois !
Quels langages de programmation avez vous déjà utilisés ?
C'est différent de Scratch
C'est un langage typé base sur Java
Il permet d'interagir avec un ecran, clavier...
void setup()
{
int a = random(1,10);
int b = random(1,10);
int reponse;
println("Résultat de la multiplication ?");
reponse = askInteger();
if (a*b == reponse)
println("Gagné");
else
{
println("Perdu, la réponse était");
println(a*b);
}
}
Comment représenter (écrire ou lire) un nombre, une image, etc... sur un support qui est une succession de 0 et de 1 ?
Impossible de raisonner au niveau du support physique ! Il faut se placer à un niveau d'abstraction supérieur grâce à la notion de type.
Un type permet d'identifier la nature d'une donnée. Par exemple s'il s'agit d'un entier ou bien d'un caractère etc...
Vous préférez raisonner sur des entiers, des lettres... ou bien directement avec leur équivalent binaire ?
A partir du type d'une donnée, la machine sera capable de définir l'espace mémoire qui lui est nécessaire ainsi que son code binaire
int : le type entier (integer)
Il indique que la donnée manipulée est un chiffre ou un nombre entier. Par exemple 1, 123, -2, -44
float, double : le type nombre réel (floating number)
Il indique que la donnée manipulée est un nombre réel. Par exemple 2.6, -5.9, 1024.0
Note
: la différence entre float et double réside dans le nombre de chiffres
représentables après la virgule. Les nombres de type double sont plus
précis mais prennent aussi plus de place en mémoire (le double en
général)
boolean : le type booléen
Il désigne une donnée à 2 valeurs possibles : true ou false
char : le type caractère
Il indique que la donnée manipulée est une lettre ou un symbole. Par exemple 'a', 'A', 'b', 'B', ... 'y', 'Y', 'z', 'Z' sont des caractères. ':', '?', '$'... le sont aussi.
Un caractère s'écrit toujours en utilisant des guillemets simples. Attention à ne pas confondre le chiffre 9 par exemple, avec le caractère '9' !
String : le type chaîne de caractères
Il indique que la donnée manipulée est une suite de caractères. Donc un mot, une phrase ou un texte.
Par exemple "Algorithmique", "Info1" sont des chaînes de caractères. Mais aussi "" qui est la chaîne de caractères vide.
Une chaîne de caractères s'écrit toujours entre guillemets doubles. Attention à ne pas confondre la chaîne "123.4" avec le nombre réel 123.4 par exemple !
Un type permet d'identifier la nature d'une donnée. Pour autant il ne permet pas de désigner une donnée en elle même !
Par exemple les nombres 28 et 62 ne sont pas distingable par leur type : ce sont tous les deux des entiers.
Comment manipuler une donnée si on ne sait pas l'identifier ? C'est là qu'intervient la notion de variable...
Une variable peut être comparée à une boîte dans laquelle on range des affaires (des données)
Chaque boîte est étiquettée (le nom de la variable)
Chaque boîte possède une forme qui lui permet uniquement de recevoir des données de cette forme (même type)
Attention, en Scratch, les variables n'ont pas de type. En Processing, les types sont indispensables !
Dans un programme, un algorithme, on passe son temps à jongler avec des variables pour utiliser des données issues du disque, d'une saisie au clavier... ou stocker de nouvelles données que l'on aura calculées.
Ce n'est possible qu'en utilisant des variables
Et pour utiliser une variable, il faudra observer 2 étapes :
Déclarer une variable c'est lui donner un nom et indiquer son type.
C'est son "acte de naissance", vouloir utiliser une variable non déclarée c'est vouloir utiliser quelque chose qui n'existe pas !
En déclarant une variable, vous commandez à la machine de réserver un espace mémoire adéquat pour stocker une donnée du type choisi. Vous lui dites aussi que vous ferez référence à cette donnée par le nom de la variable.
// Déclaration d'une variable de type entier et nommée alpha
int alpha;
// Déclaration d'une variable de type caractère et nommée lettre
char lettre;
// Déclaration d'une variable de type réel et nommée nombre
float nombre;
// Déclaration d'une variable de type booléen et nommée ouinon
boolean ouinon;
Notons au passage :
En pratique, déclarer une variable revient à réserver de l'espace en mémoire
La machine "interprete" la variable en une adresse mémoire
Le type de la variable indique comment lire et dechiffrer les 0 et les 1
Après sa déclaration, une variable est une "boîte vide", elle ne contient pas de valeur.
Pire elle peut contenir n'importe quoi, selon ce qui se trouvait avant dans la zone mémoire réservée par la machine pour la variable.
Affecter une variable c'est y stocker une valeur, tout simplement. On parle d'initialisation pour la première valeur affectée à une variable. Toujours initialiser ses variables.
// Déclaration d'une variable de type entier et nommée alpha
int alpha;
// Initialisation de la variable alpha avec le nombre 18
alpha = 18;
// Déclaration d'une variable de type caractère et nommée lettre
char lettre;
// Initialisation de la variable lettre avec le caractère 'z'
lettre = 'z';
// Autre syntaxe possible, plus concise mais totalement équivalente
/* Déclaration d'une variable de type entier
et nommée alpha et initialisée à 18 */
int alpha = 18;
/* Déclaration d'une variable de type caractère
et nommée lettre et initialisée à 'z' */
char lettre = 'z';
Notons au passage :
Le contenu d'une variable peut être aussi recopié dans une autre.
// Déclaration des variables
int toto; // toto, variable de type entier et non initialisée
int tutu = 123;// tutu, variable de type entier initialisée à 123
// Corps du programme
toto = tutu; // recopie du contenu de tutu dans toto
println(toto) ;// affiche le contenu de toto sur la sortie standard
Notons au passage :
Une expression est le plus souvent un calcul dont le résultat peut être affecté à une variable. C'est même très souhaitable si on veut en garder la trace !
// Déclaration des variables
int toto; // toto, variable de type entier et non initialisée
// Instructions du programme
toto = 12 + 3; // toto est initialisé à 15
Notons au passage :
Par exemple
// Déclaration des variables
char toto; // toto, variable de type entier et non initialisée
// Instructions du programme
toto = 12 + 3;
1 - Que contient toto ?
Par exemple
// Déclaration des variables
int toto; // toto, variable de type entier et non initialisée
// Instructions du programme
toto = toto + 3;
2 - Que contient toto ?
Par exemple
// Déclaration des variables
int toto = 2; // toto, variable de type entier
// Instructions du programme
toto = toto + 3 + toto;
3 - Que contient toto ?
...
{
....// Un bloc d'instructions
}
{
....// Un autre bloc d'instructions
}
...
Une variable existe uniquement à l'intérieur de son bloc d'intructions
...
{
int toto;
toto = 3;
println(toto); // La variable toto existe , tout va bien
}
println(toto); // La variable toto n'existe plus, une erreur apparaitra
int toto = 3;
...
{
int a = toto;// La variable toto existe encore
println(a);
...
{
int b = a + toto; // les variables a et toto existent encore
println(b);
} // fin du bloc, b n'existe plus
} // fin du bloc, a n'eiste plus
...
println(toto); // La variable toto existe encore
Noter l'importance de l'indentation
// Déclaration des variables
char o; // o, variable de type caractère et non initialisée
String mot; // mot, variable de type chaîne et non initialisée
// Instructions du programme
o = 'o';// la variable o est initialisée avec le caractère 'o'
mot = "mot";// la variable mot est initalisée avec la chaîne "mot"
Moralité :
// Déclaration des variables
int a; // a, variable de type entier et non initialisée
float b; // b, variable de type réel et non initialisée
// Instructions du programme
a = 3.25;// la variable o est initialisée avec l'entier 3
b = 4;// la variable mot est initalisée avec le réel 4.0
Moralité :
// Déclaration des variables
int a = 12; // a, variable de type entier initialisée a 12
println(a); // Affiche vers la sortie le contenu de la variable a et revient à la ligne
Notes :
// Déclaration des variables
String message = "Hello World"; // Une chaine de caractère contenant le message a afficher
text(message, width/2, height/2); // Affiche sur l'écran le texte aux coordonnées choisies
Notes :
// Déclaration des variables
int a ; // a, variable de type entier non initialisée
println("Entrez la valeur de a "); // Affiche vers la sortie le message
a = askInteger(); // Attends que l'utilisateur entre une valeur et l'affecte à a
Notes :
// Déclaration des variables
int a ; // a, variable de type entier non initialisée
a = askInteger("Entrez la valeur de a "); // Afficher le message choisi, attends que l'utilisateur entre une valeur et l'affecte à a
Notes :
Un opérateur permet de faire... une opération ! Ceci étant, on ne peut pas faire n'importe quelle opération avec n'importe quelle donnée. On distinguera :
Ils s'appliquent à des nombres de type int, float ou double :
+ : addition
- : soustraction
* : multiplication
/ : division
% : modulo. 12%5 signifie le reste de la division (entière) de 12 par 5. Soit ici 2.
L'opérateur + s'applique aussi à des chaînes mais la signification est autre. Il s'agît alors de l'opérateur de concaténation : ajouter les chaînes l'une à la suite de l'autre.
// Déclaration des variables
string mot1 = "Hello ";
string mot2 = "World ! ";
// Instructions du programme
string phrase1 = mot1+mot2;
La division n'est pas tout à fait la même selon si on l'applique à des entiers ou des réels.
Avec des réels : division "normale"
Avec des entiers : division entière ou euclidienne.
// Déclaration des variables
int toto;
// Instructions du programme
toto = 10 / 3;
4 - Que contient toto ?
La division n'est pas tout à fait la même selon si on l'applique à des entiers ou des réels.
Avec des réels : division "normale"
Avec des entiers : division entière ou euclidienne.
// Déclaration des variables
float toto;
// Instructions du programme
toto = 10 / 3;
5 - Que contient toto ?
La division n'est pas tout à fait la même selon si on l'applique à des entiers ou des réels.
Avec des réels : division "normale"
Avec des entiers : division entière ou euclidienne.
// Déclaration des variables
int toto;
// Instructions du programme
toto = 10.0 / 3.0;
6 - Que contient toto ?
La division n'est pas tout à fait la même selon si on l'applique à des entiers ou des réels.
Avec des réels : division "normale"
Avec des entiers : division entière ou euclidienne.
// Déclaration des variables
float toto;
// Instructions du programme
toto = 10.0 / 3.0;
7 - Que contient toto ?
Ecrire un algorithme qui demande à l'utilisateur de saisir un nombre de semaines au clavier et affiche en retour à l'écran le nombre de secondes équivalent
// Déclaration des variables
int nb_semaines, nb_jours, nb_secondes;
// Instructions du programme
nb_semaines = askInteger("Saisir un nombre de semaines") ;
nb_jours = nb_semaines * 7;
nb_secondes = nb_jours * 24 * 60 * 60;
println("Le nombre équivalent de secondes est : " + nb_secondes );
Ils permettent de comparer des données de même type.
Le résultat d'une comparaison est un booléen (true ou false).
Teste si une valeur est strictement inférieure à une autre
// Déclaration des variables
boolean comp1, comp2;
// Instructions du programme
comp1 = 4 < 3;// comp1 contiendra false
comp2 = 'e' < 'z';
// comp2 contiendra true
Notons au passage :
Teste si une valeur est strictement supérieure à une autre
// Déclaration des variables
boolean comp1, comp2;
// Instructions du programme
comp1 = 4 > 3;// comp1 contiendra true
comp2 = 'e' > 'z';
// comp2 contiendra false
Teste si une valeur est inférieure ou égale à une autre
// Déclaration des variables
boolean comp1, comp2;
// Instructions du programme
comp1 = 3 <= 3;// comp1 contiendra true
comp2 = 'e' <= 'z';
// comp2 contiendra true
Teste si une valeur est supérieure ou égale à une autre
// Déclaration des variables
boolean comp1, comp2;
// Instructions du programme
comp1 = 3 >= 3;// comp1 contiendra true
comp2 = 'e' >= 'z';
// comp2 contiendra false
Teste si deux valeurs sont identiques
// Déclaration des variables
boolean comp1, comp2;
// Instructions du programme
comp1 = 3 == 3;// comp1 contiendra true
comp2 = 'e' == 'z';
// comp2 contiendra false
// Attention à ne pas confondre avec = (affectation)
Teste si deux valeurs sont différentes
// Déclaration des variables
boolean comp1, comp2;
// Instructions du programme
comp1 = 3 != 3;// comp1 contiendra false
comp2 = 'e' != 'z';
// comp2 contiendra true
Les opérateurs logiques sont issus de l'algèbre de Boole. Un monde où vivent des variables qui ne peuvent posséder que deux états : 0 ou 1.
Les opérateurs logiques s'appliquent uniquement à :
A | B | A && B |
true | true | true |
true | false | false |
false | true | false |
false | false | false |
Le résultat est true ssi les deux opérandes A et B valent true.
Cet opérateur sert à tester si 2 conditions sont simultanément vérifiées (ou pas).
Exemple :
Ecrire une expression booléenne qui est vrai si la valeur de la variable entière toto est strictement comprise entre 0 et 12
// Déclaration des variables
boolean exp;
int toto;
// Instructions du programme
toto = askInteger() ; // saisie clavier d'un entier dans toto
exp = (toto > 0) && (toto < 12);// vrai si toto est entre 0 et 12, faux sinon
A | B | A || B |
true | true | true |
true | false | true |
false | true | true |
false | false | false |
Le résultat est true ssi au moins l'une des deux opérandes A ou B vaut true.
Cet opérateur sert à tester si au moins 1 condition sur 2 est vérifiée (ou pas).
Exemple :
Ecrire une expression booléenne valant vrai si la valeur de la variable entière toto n'est pas comprise entre 0 et 12.
// Déclaration des variables
boolean exp;
int toto;
// Instructions du programme
toto = askInteger() ; // saisie clavier d'un entier dans toto
exp = (toto < 0) || (toto > 12);// vrai si toto n'est pas entre 0 et 12, faux sinon
Dans une expression impliquant l'opérateur AND et l'opérateur OR, AND est prioritaire sur OR.
A && B || C est équivalent à (A && B) || CNotons au passage :
A | !A |
true | false |
false | true |
C'est un opérateur "unaire" (il s'applique à une valeur booléenne et non deux comme AND et OR).
Il exprime la négation, l'opposé de l'expression logique.
Exemple :
Ecrire une expression booléenne
valant vrai si la valeur de la variable entière toto n'est pas comprise
entre 0 et 12. Cette fois, proposez une solution qui fait bon usage de
l'opérateur NOT.
// Déclaration des variables
boolean exp;
int toto;
// Instructions du programme
toto = askInteger() ; // saisie clavier d'un entier dans toto
exp = !( (toto > 0) && (toto < 12) );// vrai si toto n'est pas entre 0 et 12, faux sinon
Les opérateurs logiques permettent de combiner différents tests
simples afin de construire des expressions plus élaborées.
Ecrire une expression booléenne qui vaut true si la valeur entière contenue dans une variable toto est paire et strictement supérieur à 100.
// Déclaration des variables
boolean exp;
int toto;
// Instructions du programme
toto = askInteger() ; // saisie clavier d'un entier dans toto
exp = (toto%2 == 0) && (toto > 100);// vrai si toto est pair et plus grand que 100
A | B | A NAND B |
true | true | false |
true | false | true |
false | true | true |
false | false | true |
NAND est la contraction de NOT AND. Autrement dit :
A | B | A NOR B |
true | true | false |
true | false | false |
false | true | false |
false | false | true |
De même, NOR est la contraction de NOT OR. Autrement dit :
Ces opérateurs soint moins courants puisqu'ils ne permettent pas d'exprimer plus que la combinaison de NOT, AND et OR.
Mais leurs tables de vérité permettent de déduire deux relations intéressantes :
Notons au passage :
Une expression comporte souvent plusieurs types d'opérateur. La priorité entre ces opérateurs est importante pour comprendre comment la machine évalue une expression :
// Déclaration des variables
boolean exp;
int toto;
// Instructions du programme
toto = askInteger() ; // saisie clavier d'un entier dans toto
exp = toto + 4 < 12 && toto - 4 > 0;
// ou : exp = ( (toto+4) < 12 ) && ( (toto-4) > 0 )
// Déclaration des variables
int A = 3;
int B = 12 ;
boolean C = (A >= 3) && (A < 3);
8 - Quelle est la valeur de C ?
// Déclaration des variables
int A = 3;
int B = 12 ;
boolean C = ! ((A==3) && (B<10));
9 - Quelle est la valeur de C ?
// Déclaration des variables
int A = 3;
int B = 12 ;
boolean C = ! ((A==3) || (B<10)) || ! (false);
10 - Quelle est la valeur de C ?
// Déclaration des variables
int A = 3;
int B = 12 ;
boolean C = !( ( B!=A && B<10) || ( A==B || B > 10));
11 - Quelle est la valeur de C ?
// Déclaration des variables
boolean C = !( ( B!=10 || !(A>20)) && ( !(B>=10) && A <= 20));
12 - Que peut on dire si la valeur de A est 30 ?
// Déclaration des variables
boolean C = !( ( B!=10 || !(A>20)) && ( !(B>=10) && A <= 20));
13 - Que peut on dire si la valeur de B est 10 ?
Qu'est ce qu'une fonction ?
Pourquoi utiliser une fonction ?
Utiliser une fonction
Fonction f(x) calcule un entier : la valeur au carré de l'entier x
D'un point de vue de l'éxecution,l'expression f(x) est évaluée et remplacée par la valeur calculée
int y = f(3);
14 - Quelle est la valeur de y ?
int x = 4;
int y = f(x);
15 - Quelle est la valeur de y ?
int x = 2;
int y = f;
16 - Quelle est la valeur de y ?
int y = 2;
y = f(y+3);
17 - Quelle est la valeur de y ?
int x = 2;
int y = f()+x;
18 - Quelle est la valeur de y ?
int x = 2;
int y = f(f(x+1));
19 - Quelle est la valeur de y ?
int y = 2;
y = f(y)+y;
20 - Quelle est la valeur de y ?
Du point de vue de la machine
type nom(typeParametre1 nomParametre1, typeParametre2 nomParametre2,...)
{
// bloc d'instructions
}
int f(int x)
{
int r = x * x;
return r;
}
int f (int x)
{
int r = x * x;
return r;
}
int f(int x )
{
int r = x * x;
return r;
}
Les paramètres
int f(int x)
{
int r = x * x;
return r;
}
En processing : on commence par executer la fonction setup()
int f(int x)
{
int r = x * x;
return r;
}
void setup()
{
int r = 3;
int x = f(r) + r;
println(x);
}
int f(int x)
{
int r = x * x;
return r;
}
void setup()
{
int r = 3;
int x = f(r) + r;
println(x);
}
int f(int x)
{
int r = x * x;
return r;
}
void setup()
{
int r = 3;
int x = f(r) + r ;
println(x);
}
Evaluation de f(r)
int f(int x)
{
int r = x * x;
return r;
}
void setup()
{
int r = 3;
int x = f(r) + r;
println(x);
}
On évalue r
int f(int x)
{
int r = x * x;
return r;
}
void setup()
{
int r = 3;
int x = f(3 ) + r;
println(x);
}
Execution du bloc d'instructions de f avec x=3
int f(int x = 3)
{
int r = x * x;
return r;
}
void setup()
{
int r = 3;
int x = f(3) + r;
println(x);
}
int f(int x)
{
int r = 3 * 3 ;
return r;
}
void setup()
{
int r = 3;
int x = f(3) + r;
println(x);
}
On retourne la valeur 9 à la fonction appelante
int f(int x)
{
int r = x * x;
return 9 ;
}
void setup()
{
int r = 3;
int x = f(3) + r;
println(x);
}
On reprends l'execution du code de la fonction setup()
int f(int x)
{
int r = x * x;
return r;
}
void setup()
{
int r = 3;
int x = 9 + r;
println(x);
}
On évalue la variable r de la fonction setup()
int f(int x)
{
int r = x * x;
return r;
}
void setup()
{
int r = 3;
int x = 9 + 3 ;
println(x);
}
float monCalcul(float x,float y)
{
float z = x/y;
return z;
}
void setup()
{
float x = 6;
float y = 3;
float z = monCalcul(x,y)+2.0;
}
21 - Quelle est la valeur de z ?
float monCalcul(float x,float y)
{
float z = x/y;
return z;
}
void setup()
{
float x = 6;
float y = 3;
float z = monCalcul(y,x)+2.0;
}
22 - Quelle est la valeur de z ?
void afficheMonCalcul(float x,float y,String message)
{
float z = x/y;
print(message + z);
}
void setup()
{
float x = 6;
float y = 3;
afficheMonCalcul("Le résultat est : ",x,2.0);
}
23 - Que voit on à l'écran ?
void afficheMonCalcul(float x,float y,String message)
{
float z = x/y;
print(message + z);
}
void setup()
{
float x = 6;
float y = 3;
float z = afficheMonCalcul(x,2.0,"Le résultat est : ");
print(". z = " + z);
}
24 - Que voit on à l'écran ?
Qu'avons nous appris ?
Le tout s'effectue séquentiellement. Les instructions structurées vont nous permettre :
Elles permettent d'exécuter un bloc d'instructions si et seulement si une condition choisie est satisfaite.
Supposons par exemple devoir diviser un nombre a par un nombre b. La division par zéro étant impossible, ce calcul ne peut être réalisé que si b est différent de 0.
Bloc Conditionnel :
"Si (expression booléenne) alors" ?
if ( /* expression booléenne */ ) // l'expression se place entre parenthèses
{ // l'accolade ouvrante indique le début du bloc d'instructions
/* bloc d'instructions */
} // l'accolade fermante indique la fin du bloc d'instructions
Revenons à la problématique suivante : Comment dire à la machine "Si b est différent de 0, alors calcule a/b" ?
// Déclaration des variables
int a, b, division;
// Instructions du programme
println("Saisir les valeurs de a et de b ");
a = askInteger() ;
b = askInteger() ;
if ( b != 0 )
{
division = a / b;
println("La division de a par b est "+ division );
}
if ( /* expression booléenne */ )
{ // l'accolade ouvrante
/* bloc d'instructions à exécuter
si l'expression booléenne vaut true */
} // l'accolade fermante
else
{
/* autre bloc d'instructions à exécuter
si l'expression booléenne vaut false */
}
Principe :
Même exercice que le précédent mais on vous demande de faire afficher "division par zéro interdite" si le cas se produit.
// Déclaration des variables
int a, b, division;
// Instructions du programme
println("Saisir les valeurs de a et de b ");
a = askInteger() ;
b = askInteger() ;
if ( b != 0 )
{
division = a / b;
println("La division de " + a + " par " + b + " est égale à " + division );
}
else
{
println("La division par zéro est interdite");
}
Un bloc d'instructions peut contenir d'autres instructions conditionnelles.
if ( ... )
{
if (...)
{
...
}
else
{
...
}
}
else
{
if (...)
{
...
}
else
{
...
}
}
Ecrire un algorithme qui demande à l'utilisateur de saisir un nombre entre 1 et 7
On ne demande pas de vérifier que le nombre entier saisi est bien compris entre 1 et 7, on supposera que c'est toujours le cas.
Puis en fonction
du nombre saisi, le programme affiche le nom du jour de la semaine correspondant. Par exemple "lundi" pour 1, "mardi" pour 2 etc...
// Déclaration des variables
int jour;
// Instructions du programme
jour = askInteger("Saisir un nombre entier entre 1 et 7");
if ( jour == 1 )
println("lundi");
else
{
if ( jour==2 )
println("mardi");
else
{
if ( jour==3 )
println("mercredi");
else
{
if ( jour==4 )
println("jeudi");
else
{
if ( jour==5 )
println("vendredi";)
else
{
if ( jour==6 )
println("samedi");
else
println("dimanche");
}
}
}
}
}
Notons au passage :
/* Même solution mais non indenté...
Notez que je ne corrigerai pas vos programmes s'ils sont mal indentés. */
// Déclaration des variables
int jour;
// Instructions du programme
jour = askInteger("Saisir un nombre entier entre 1 et 7") ;
if ( jour == 1 )
println("lundi");
else
{
if ( jour==2 )
println("mardi");
else
{
if ( jour==3 )
println("mercredi");
else
{
if ( jour==4 )
println("jeudi");
else
{
if ( jour==5 )
println("vendredi");
else
{
if ( jour==6 )
println("samedi");
else
println("dimanche");
}
}
}
}
}
void setup()
{
int ecrit1 = 12;
int ecrit2 = 15;
int tp = 8;
if (0.25*ecrit1 + 0.25*tp + 0.5*ecrit2 >= 10)
println("vous avez validé info1");
}
25 - Que voit on à l'écran ?
float calculDeMoyenne(int ecrit1,int ecrit2,int tp)
{
return(0.25*ecrit1 + 0.25*tp + 0.5*ecrit2);
}
void setup()
{
if (calculDeMoyenne(4,5,6) >= 10);
println("vous avez validé info1");
}
26 - Que voit on à l'écran ?
float calculDeMoyenne(int ecrit1,int ecrit2,int tp)
{
return(0.25*ecrit1 + 0.25*tp + 0.5*ecrit2);
}
void setup()
{
float z = calculDeMoyenne(12,15,8);
if z > 10
println("vous avez validé info1");
else
println("vous n'avez pas validé");
}
27 - Que voit on à l'écran ?
Dans le cas d'un "if, else if, else if, .... else", et seulement dans ce cas, on peut utiliser la syntaxe équivalente suivante pour une meilleure lisibilité :
if (...)
{
...
}
else if (...)
{
...
}
else if (...)
{
...
}
...
else
{
...
}
float calculDeMoyenne(int ecrit1,int ecrit2,int tp)
{
return(0.25*ecrit1 + 0.25*tp + 0.5*ecrit2);
}
void setup()
{
float z = calculDeMoyenne(4,4,5);
if (z > 10)
println("vous avez validé info1");
else if (z <= 8 )
println("vous avez moins de 8");
else
println("vous n'avez pas validé");
}
28 - Que voit on à l'écran ?
float calculDeMoyenne(int ecrit1,int ecrit2,int tp)
{
return(0.25*ecrit1 + 0.25*tp + 0.5*ecrit2);
}
void setup()
{
float z = calculDeMoyenne(18,18,15);
if (z > 10)
println("vous avez validé info1");
else if (z >= 12 )
println("vous avez plus de 12");
else
println("vous n'avez pas validé");
}
29 - Que voit on à l'écran ?
L'exercice précédent peut s'écrire d'une manière plus efficace
En utilisant l'instruction switch
Syntaxe :
switch (variable)
{
case valeur1 :
instruction1;
break;
case valeur2:
case valeur3 :
instruction2;
instruction2bis;
break;
.
.
.
default:
instructionDefaut;
break;
}
if (variable == valeur1)
instruction1;
else if (variable == valeur2 || variable == valeur3)
{
instruction2;
instruction2bis;
}
.
.
.
else
{
instructionDefaut;
}
L'exercice précédent peut s'écrire :
// Déclaration des variables
int jour;
// Instructions du programme
jour = askInteger("Saisir un nombre entier entre 1 et 7");
switch (jour)
{
case 1:
println("Lundi");
break;
case 2:
println("Mardi");
break;
case 3:
println("Mercredi");
break;
case 4:
println("Jeudi");
break;
case 5:
println("Vendredi");
break;
case 6:
println("Samedi");
break;
case 7:
println("Dimanche");
break;
default:
println("Erreur");
break;
}
Précisions sur l'instruction switch
Par exemple, pouvez-vous écrire un programme qui affiche 6 fois la chaîne "Bonjour" ?
On ne vous fera pas l'offense de penser le contraire ! Mais pouvez vous en écrire un qui affiche 1 million de fois la chaîne "Bonjour" ? Surtout en avez vous le temps (et l'envie !) ?
Il faut utiliser l' instruction :
int i; // déclaration d'une variable entière qui sera l'indice de la boucle
for ( i=n; i<=m; i++ ) // n et m sont deux entiers
{
/* bloc d'instructions à répéter */
}
Principe :
Ecrire un algorithme qui affiche 1 million de fois "Bonjour".
int i;
for ( i=1; i<=1000000; i++ )
{
println("Bonjour");
}
Principe :
Variante : Ecrire un algorithme qui affiche "Bonjour" Autant de fois qu'un nombre entier préalablement saisi par l'utilisateur.
int i, nb;
nb = askInteger("Saisir le nombre de bonjour ") ;
for ( i=1; i<=nb; i++ )
println("Bonjour");
nb = askInteger("Saisir le nombre de bonjour ") ;
for ( i=0; i<nb; i++ )
println("Bonjour");
Notes :
Ecrire un algorithme qui demande la saisie d'un nombre entier n et qui affiche ensuite tous les nombres de 1 à n.
int i, n;
n = askInteger("Saisir un entier positif ");
for ( i=1; i<=n; i++ )
print(i + " " );
Note :
Ecrire une fonction qui affiche la table de multiplication par 7 et une autre fonction qui affiche la table de 5. Faites un programme qui affiche ces 2 tables.
void tableDe5()
{
int i;
for(i=0; i<=10; i++)
{
println("5 x " + i + " = "+ 5*i );
}
}
void tableDe7()
{
int i;
for(i=0; i<=10; i++)
{
println("7 x " + i + " = "+ 7*i );
}
}
void setup()
{
tableDe5();
tableDe7();
}
Ecrire une fonction pour chaque table de multiplication est pénible. A la place, écrire plutôt une fonction qui affiche la table de multiplication de l'entier fourni en paramètre.
void tableDe( int n )
{
int i;
for(i=0; i<=10; i++)
println(n +" x " + i + " = " + n*i );
}
void setup()
{
int nb = askInteger("Quelle table voulez vous ?") ;
tableDe(nb);
}
Utiliser une boucle for suppose de connaître par avance le nombre de tours à effectuer.
On peut avoir besoin de répéter des instructions sans pour autant savoir combien de fois par avance !
Un programme doit poser une question à l'utilisateur qui doit y répondre par oui ou par non en frappant sur le caractère 'o' ou 'n'. Dans le cas contraire la question doit lui être posée à nouveau.
Ici on ne peut pas prédire le nombre de tentatives dont l'utilisateur aura besoin. Par conséquent une boucle for est inutilisable. Mais ce n'est pas le seule type de boucle qui existe :
Attention, l'instruction scratch est "inversée" par rapport au Processing !
while ( /* expression booléenne */ )
{
/* bloc d'instructions à répéter */
}
Principe :
Poser la question "Avez-vous compris ?" jusqu'à ce que l'utilisateur réponde oui en frappant sur la lettre 'o'.
char reponse='n';
while ( reponse!='o' )
{
reponse = askChar("Avez-vous compris ?") ;
}
Notes :
do
{
/* bloc d'instructions à répéter */
}
while ( /* expression booléenne */ );
Principe : Poser à l'utilisateur la question "Avez-vous compris ?" jusqu'à ce qu'il réponde oui en frappant sur la lettre 'o'.
char reponse;
do
{
reponse = askChar("Avez-vous compris ?") ;
}
while ( reponse!='o' );
Notes :
Le but est de faire deviner à l'utilisateur un nombre entier choisi aléatoirement entre 0 et 99. A chaque proposition du joueur, la machine indique si le nombre proposé est plus petit ou plus grand que le nombre à deviner. Lorsque
le bon nombre est trouvé, la machine affiche un message de félicitations.
On utilisera l'instruction random(0.0,10.0)
qui génère aléatoirement (ou presque) un nombre compris entre 0 (inclus) et 10(exclu).
Par exemple float nb_alea = random(0.0,1.0);
initalisera nb_alea
avec une valeur entre 0 et 1.0.
Aussi int adeviner = int(random(0,100));
initialisera adeviner
avec une valeur entre 0 et 99.
L'écriture (int)(...)
commande à la machine de convertir l'expression entre parenthèse en nombre entier. Dans le cas d'un nombre réel, seule la partie entière sera conservée. Par exemple (int)( 73.234 )
donnera 73
.
int proposition;
int adeviner = int(random(0,100));
do
{
proposition = askInteger("Proposer un nombre entre 0 et 99 :");
if ( proposition < adeviner )
println("Trop petit !");
else if ( proposition > adeviner )
println("Trop grand !");
else
println("Félicitations ! C'était bien " + adeviner);
}
while ( proposition != adeviner );
Notons au passage :
Le bloc d'instructions d'une boucle peut contenir d'autres boucles bien sûr ! On parle alors de boucles imbriquées
Des boucles imbriquées ne sont pas indépendantes les unes des autres. De fait, il faudra faire attention à utiliser un indice de boucle différent pour chacune !
Afficher à l'écran les tables de multiplication de 1 à 10. Au besoin, afficher d'abord la table de 1, puis modifier votre code pour afficher les tables de 1 à 10.
for(int i=1; i<= 10; i++)
{
println("Table de multiplication de " + i );
for(int j=1; j<=10; j++)
{
println(i+" x "+j+" = "+i*j);
}
}
int x = 5;
int i = 0;
for(i = 3; i < 6;i++)
{
x += 1;
}
30 - Quelle est la valeur de x à la fin de la boucle ?
int x = 1;
for(int i = 1; i <= 5;i++)
{
x += 1;
i+=1;
}
31 - Quelle est la valeur de x à la fin de la boucle ?
int x = 1;
for(int i = 1; i <= 5;i++);
{
x += 1;
}
32 - Quelle est la valeur de x à la fin de la boucle ?
int x = 0;
char reponse;
while (reponse == 'o' || reponse == "O")
{
println("Hello");
x = x + 1;
reponse = askChar("Voulez vous continuer ? (O/N)");
}
33 - Que fait cet algorithme ?
int x = 0;
int i = 1;
do
{
x = x + 1;
}
while( i<10 );
34 - Quelle est la valeur de x à la fin de la boucle ?
int x = 0;
int i = 1;
while (i < 10 && x < 4 )
{
x = x + 1;
i += 1;
}
35 - Quelle est la valeur de x à la fin de la boucle ?
int x = 0;
int i = 1;
while (i < 10 || x < 4 )
{
x = x + 1;
i += 1;
}
36 - Quelle est la valeur de x à la fin de la boucle ?
int x = 0;
int i = 1;
while (i < 10 && x > 0)
{
x = x + 1;
i += 1;
}
37 - Quelle est la valeur de x à la fin de la boucle ?
Supposons devoir saisir les noms d'une promotion d'étudiants. En l'état de nos connaissance, il faut :
string
par étudiantDe la sorte, on ne matérialise pas du tout l'appartenance à un même ensemble (la promotion)
On souhaite saisir 6 notes et les afficher de la plus petite à la plus grande
... ce n'est pas extensible. Avec 16 notes il faudra 10 variables de plus et le code pour les ordonner va très vite devenir illisible. De plus si on ne connait pas par avance le nombre de notes à saisir, on ne sait pas faire.
L'origine de ces problèmes, c'est notre incapacité à définir un ensemble de données homogènes
Regrouper des éléments de même type au sein d'une collection d'éléments. Pouvoir parcourir cette collection et si besoin accéder facilement à chaque élément.
Un tableau regroupe un nombre n
d'éléments de même type. Chaque case du tableau est identifiée par un indice allant de 0
jusqu'à n-1
. n
est aussi appelé la taille du tableau
// déclaration d'une variable de type tableau d'entiers
int[] monTableaudEntiers ;
// déclaration d'une variable de type tableau de caractères
char[] monTableaudeChar;
// déclaration d'une variable de type tableau de booléens
boolean[] monTableaudeBool ;
// déclaration d'une variable de typetableau de chaînes
String[] malistedeChaine ;
// Création d'un tableau d'entiers de taille 8
monTableaudEntiers = new int[8];
// Création d'un tableau de caractères de taille 1024
monTableaudeChar = new char[1024] ;
// Création d'un tableau de booléens de taille 256
monTableaudeBool = new boolean[256] ;
// Création d'un tableau de 25 chaînes
malistedeChaine = new String[25] ;
taille
lui permet de réserver taille
places/cases consécutives en mémoire pour y ranger des valeurs du type indiqué
// déclaration d'un tableau d'entiers de taille 8
int[] int_tab = new int[8];
// déclaration d'un tableau de caractères de taille 1024
char[] car_tab = new char[1024] ;
// déclaration d'un tableau de booléens de taille 256
boolean[] b_tab = new boolean[256] ;
// déclaration d'un tableau de 25 chaînes
String[] chaine_tab = new String[25] ;
Pour accéder (en lecture ou écriture) à un élément dans un tableau, on utilise l'indice de la case qui le contient. Syntaxe
: nom_du_tableau[ indice_de_la case ]
int sum;
int[] tab = new int[4]; // tableau de taille 4
tab[0] = 10; // affecte 10 à la case d'indice 0
tab[1] = 2; // affecte 2 à la case d'indice 1
tab[2] = 23; // affecte 23 à la case d'indice 2
tab[3] = 99; // affecte 99 à la case d'indice 3
sum = tab[0] + tab[3]; // sum vaut 109
0
(inclus) et la taille du tableau (exclue)0
Ecrire un algorithme qui initialise toutes les cases d'un tableau de 1024 entiers à -1
int i;
int[] tab = new int[1024];
for(i=0; i<1024; i++)
tab[i] = -1;
Même question mais en remplissant chaque case avec les entiers de 1 à 1024
int i;
int[] tab = new int[1024];
for(i=0; i<1024; i++)
tab[i] = i+1;
for
pour parcourir les indices d'un tableau est incontournable
int[] tx = new int[10];
for (int i = 0;i < 10;i++)
tx[i] = i+1;
tx[0] = tx[4] + tx[9];
38 - Que contient la première case du tableau ?
int[] tx = new int[10];
int a = 5;
for (int i = 0;i < 10;i++)
tx[i] = i;
a = a * tx[10];
39 - Que contient la variable a?
int[] tx = new int[11];
int a = 5;
for (int i = 0;i < 10;i++)
tx[i] = i;
a = a * tx[10];
40 - Que contient la variable a?
Ecrire un algorithme pour saisir 28 notes dans un tableau.
int nb_notes = 28;
double[] notes = new double[nb_notes]; // le tableau
int i; // indice de boucle pour le parcours du tableau
println("Saisir les " + nb_notes + " notes");
// saisie des notes dans le tableau
for(i=0; i<nb_notes; i++)
notes[i]=askDouble() ;
Modifier le programme précédent pour en plus calculer la moyenne des 28 notes
int nb_notes = 28;
float[] notes = new float[nb_notes]; // le tableau
int i; // indice de boucle pour le parcours du tableau
float avg = 0.0; // pour calculer la moyenne
println("Saisir les " + nb_notes + " notes");
// saisie des notes dans le tableau
for(i=0; i<nb_notes; i++)
notes[i] = askFloat() ;
// calcul de la somme de toutes les notes
for(i=0; i<nb_notes; i++)
avg = avg + notes[i];
println(" La moyenne est : " + avg/(float)nb_notes);
avg
une note de plusPour finir, faites en sorte de demander à l'utilisateur le nombre de notes à saisir pour ne plus être restreint à 28 notes
float[] notes; // le tableau non dimensionné
int i; // indice de boucle pour le parcours du tableau
int nb_notes; // nombre de notes à saisir
float avg = 0.0; // pour calculer la moyenne
nb_notes = askInteger("Combien de notre à saisir ?");
notes = new float[ nb_notes ];
println("Saisir les " + nb_notes + " notes");
// saisie des notes dans le tableau
for(i=0; i<nb_notes; i++)
notes[i] = askFloat() ;
// calcul de la somme de toutes les notes
for(i=0; i<nb_notes; i++)
avg = avg + notes[i];
println(" La moyenne est : " + avg/(float)nb_notes);
Les données sont souvent structurées. Par exemple un chevalet de scrabble possède une structure qui correspond à un tableau 1D. Mais le plateau de jeu du scrabble possède une structure difficile à représenter avec un tableau 1D.
Autre exemple : une image bitmap possède une structure 2D. Nous aurons du mal à la représenter avec un tableau 1D. Car la dimension de la structure des données ne correspond pas !
Pour bien représenter des données, pouvoir les manipuler efficacement, il faut utiliser des structures capables de reproduirent l'organisation intrinsèque de ces données.
Un tableau 2D est une structure de grille caractérisée par son nombre l
de lignes et sont nombre c
de colonnes, respectivement numérotées de 0
à l-1
et de 0
à c-1
.
Un tableau 2D stocke l x c
éléments de même type. L'emplacement d'un élément est identifié par les indices de ligne et de colonne à l'intersection desquelles il se trouve.
// déclaration d'un tableau 2D d'entiers
int[][] int_tab = new int[10][10];
// déclaration d'un tableau 2D de caractères
char[][] char_tab = new char[10][10];
// déclaration d'un tableau 2D de booléens
boolean[][] b_tab = new boolean[10][10];
// déclaration d'un tableau 2D de chaînes
String[][] chaine_tab = new String[10][10];
// type entier
int value;
// type tableau 1D de valeurs de type entier
int[] tab1D ;
// type tableau 2D de valeurs de type entier
int[][] tab2D;
// valable quelque soit le type de départ bien sûr
// type tableau 3D de valeurs de type entier !
int[][][] tab3D;
// et ainsi de suite... mais on s'arrêtera à la 2D.
Pour accéder à un élément dans un tableau 2D, on utilise l'indice de la ligne et de la colonne qui identifient la case qui le contient. Syntaxe :
nom_du_tableau[ indice_de_la_ligne ][indice_de_la_colonne]
int sum;
int[][] tab = new int[4][8]; // tableau 2D de 4 lignes et 8 colonnes
tab[0][7] = 10; // affecte 10 à la case de coordonnées (0, 7)
tab[1][0] = 2; // affecte 2 à la case de coordonnées (1, 0)
tab[3][3] = 99; // affecte 99 à la case de coordonnées (3, 3)
sum = tab[0][7] + tab[3][3]; // sum vaut 109
0
(inclus) et respectivement le nombre de lignes (exclu) et le nombre de colonnes (exclu)Ecrire un programme qui permet de saisir case par case le contenu d'un tableau 2D représentant les notes dans 12 modules obtenu par 28 étudiants
int l, c;
double[][] notes = new double[28][12];
for( l=0; l<28; l++)
{
for( c=0; c<12; c++)
{
notes[l][c] = askDouble("Note de l'étudiant" + l + " pour le module " + c );
}
}
L'analyse globale est une approche qui consiste à appréhender un problème dans sa totalité pour écrire un programme qui va le résoudre
Si le problème devient complexe, il devient aussi difficile de l'appréhender dans sa globalité :
Un problème trop complexe doit être décomposé en sous problèmes moins complexes.