Chapitre 224 minDébutant
Variables, types et affectation
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- affecter une variable et échanger deux valeurs ;
- choisir le bon type : entier, réel, booléen ou chaîne ;
- utiliser les opérateurs numériques, dont
DIVetMOD, et traduire une formule ; - combiner des comparaisons avec les opérateurs booléens ;
- convertir une valeur d'un type à un autre, par exemple une saisie en nombre.
6 exercices corrigés1 schéma
Une variable est une case de la mémoire, désignée par un nom, qui contient une valeur d'un certain type ; l'affectation est l'instruction qui range une valeur dans cette case. Ce chapitre présente les types simples (entier, réel, booléen, chaîne), l'affectation, la saisie et l'affichage, puis les opérateurs et les conversions, en pseudo-code et en Python.
C'est quoi une variable ?
Un programme manipule des données : une note, un prix, un nom d'utilisateur. Pour s'en servir plusieurs fois, il faut les garder quelque part. Une variable est une boîte étiquetée : l'étiquette est son nom (on dit aussi identifiant), le contenu est sa valeur, et la forme de la boîte est son type, qui fixe ce qu'elle peut contenir et les opérations permises.
| Caractéristique | Exemple | Ce qu'il faut retenir |
|---|---|---|
| Nom | prix_ht | Il ne change jamais pendant l'exécution |
| Type | réel | Il fixe les valeurs possibles et les opérations permises |
| Valeur | 149.90 | Elle peut changer à chaque affectation ; l'ancienne valeur est perdue |
Une boîte ne contient qu'une valeur à la fois. Quand tu ranges une nouvelle valeur, l'ancienne est écrasée : c'est l'origine de la plupart des erreurs de débutant dans les échanges de valeurs et les boucles.
Nommer ses variables
Les règles sont presque les mêmes dans tous les langages : un nom commence par une lettre (ou _), continue avec des lettres, des chiffres et des _, sans espace ni tiret, et ne peut pas être un mot réservé du langage (if, for, while, def, return, class…). Python distingue les majuscules : Total et total sont deux variables différentes.
Au-delà des règles, un bon nom dit ce que contient la variable :
| À éviter | Mieux | Pourquoi |
|---|---|---|
x, a2, truc | nb_postes, prix_ht | On comprend sans relire tout le code |
l | ligne | l se confond avec 1 et I |
prix-ht | prix_ht | Le tiret est l'opérateur de soustraction |
2eme_note | note2 | Un nom ne commence pas par un chiffre |
moyenneDesNotesDeLaClasseDeSIO1 | moyenne_classe | Assez long pour être clair, pas plus |
En Python, la convention (le guide de style PEP 8) est le snake_case : minuscules et _ (nb_postes). En C# et en JavaScript, tu écriras plutôt nbPostes (camelCase). Les compteurs de boucle s'appellent traditionnellement i, j, k : c'est la seule exception admise aux noms d'une lettre.
Les types simples
Le programme de BTS cite quatre types simples, plus la chaîne de caractères.
| Pseudo-code | Python | Valeurs | Exemples |
|---|---|---|---|
| entier | int | Les entiers relatifs | 0, 42, -7 |
| réel | float | Les nombres à virgule, en valeur approchée | 3.14, -0.5, 1e6 |
| booléen | bool | Deux valeurs seulement | True, False |
| chaîne de caractères | str | Du texte, entre guillemets | "BTS SIO", '192.168.1.1', "" |
La fonction type donne le type d'une valeur :
print(type(7), type(7.0), type("7"), type(True))
print(type(7 / 7))
<class 'int'> <class 'float'> <class 'str'> <class 'bool'>
<class 'float'>
7, 7.0 et "7" sont trois valeurs différentes : un entier, un réel et un texte d'un seul caractère. La division / donne toujours un réel en Python, même quand elle tombe juste.
Données mathématiques et données informatiques
En maths, un entier peut être aussi grand que tu veux et un réel a une infinité de décimales. Une machine stocke tout sur un nombre fini de bits : le programme te demande de connaître ces différences, sans le détail de la représentation interne.
Les entiers. En Python, un int n'a pas de limite pratique : 2 ** 64 donne 18446744073709551616 sans broncher. En C# ou en Java, un int occupe 32 bits et va de −2 147 483 648 à 2 147 483 647 : au-delà, la valeur « déborde » et repart dans les négatifs, sans message. Tu le rencontreras en SLAM.
Les réels. Un float est stocké en binaire sur 64 bits, avec environ 15 à 17 chiffres significatifs. Beaucoup de décimales simples, comme 0,1, n'ont pas d'écriture binaire exacte (comme 1/3 n'a pas d'écriture décimale exacte). D'où ce résultat célèbre :
print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
0.30000000000000004
False
Les booléens. Une condition comme note >= 10 a pour valeur True ou False. On peut ranger ce résultat dans une variable : admis = note >= 10. Les booléens servent dans les conditions (chapitre 3) et les boucles.
Les chaînes. Une chaîne est une suite de caractères. Le programme recommande de la traiter comme un type à part entière, avec ses propres opérations (concaténation, extraction, recherche), plutôt que comme un tableau de caractères. Le chapitre 9 lui est consacré.
L'affectation
L'affectation range une valeur dans une variable. En pseudo-code, on l'écrit avec une flèche ← ; en Python, avec =.
nb_postes ← 25
prix ← 149,90
total ← nb_postes × prix
Elle se lit de droite à gauche : on calcule d'abord l'expression de droite avec les valeurs actuelles, puis on range le résultat dans la variable de gauche. D'où l'instruction qui choque les matheux :
compteur ← compteur + 1
En maths, c = c + 1 n'a pas de solution. En algorithmique, c'est une action : « la nouvelle valeur de compteur est l'ancienne plus 1 ». Le programme appelle cela une affectation récursive : la variable apparaît des deux côtés. C'est le cœur des compteurs et des accumulateurs (chapitre 4).
Pour suivre des affectations successives, on fait un tableau de trace : une colonne par variable, une ligne par instruction (chapitre 5).
a ← 5
b ← a + 2
a ← a × b
b ← b - a
| Instruction | a | b |
|---|---|---|
a ← 5 | 5 | ? |
b ← a + 2 | 5 | 7 |
a ← a × b | 35 | 7 |
b ← b - a | 35 | −28 |
Avant sa première affectation, b n'a pas de valeur connue (le ?). Utiliser une variable non initialisée est une erreur : Python lève NameError: name 'b' is not defined, d'autres langages prennent une valeur au hasard.
Échanger deux variables
Échanger le contenu de a et b est l'exercice classique de l'affectation. La tentative naïve échoue :
a ← b
b ← a
Avec a = 3 et b = 8, la première ligne écrase le 3 : a vaut 8, puis b ← a remet 8 dans b. Les deux variables valent 8. Il faut une troisième boîte pour garder la valeur qu'on va écraser :
temp ← a
a ← b
b ← temp
Python sait échanger en une ligne, grâce à l'affectation multiple : a, b = b, a. Python évalue d'abord tout le côté droit (le couple (8, 3)), puis l'affecte. Connais les deux : la version avec temp est celle qu'on attend dans un algorithme, et elle fonctionne dans tous les langages.
Saisir et afficher
Saisir(x) lit une valeur au clavier et la range dans x. Afficher(...) écrit à l'écran. En Python :
| Besoin | Python | Remarque |
|---|---|---|
| Lire un texte | nom = input("Nom ? ") | Le texte entre parenthèses s'affiche avant la saisie |
| Lire un entier | n = int(input("Nombre ? ")) | input renvoie toujours une chaîne : on la convertit |
| Lire un réel | x = float(input("Prix ? ")) | Avec un point décimal : 19.99, pas 19,99 |
| Afficher plusieurs valeurs | print("Total :", total, "€") | Séparées par une espace |
| Changer le séparateur | print(h, m, s, sep=":") | Avec h, m, s = 2, 15, 0, affiche 2:15:0 |
| Rester sur la ligne | print("Chargement", end="") | Pas de retour à la ligne |
| Mettre en forme | print(f"Total : {total:.2f} €") | Une f-string, détaillée au chapitre 9 |
Le programme limite la mise en forme exigible aux séparateurs et aux retours à la ligne : les f-strings sont un confort, pas une obligation.
Les opérateurs numériques
| Opération | Pseudo-code | Python | Exemple Python | Résultat |
|---|---|---|---|---|
| Addition, soustraction | +, - | +, - | 7 - 10 | -3 |
| Multiplication | × | * | 7 * 2 | 14 |
| Division | / | / | 7 / 2 | 3.5 |
| Quotient de la division entière | DIV | // | 17 // 5 | 3 |
| Reste de la division entière | MOD | % | 17 % 5 | 2 |
| Puissance | ^ | ** | 2 ** 10 | 1024 |
| Valeur absolue | abs(x) | abs(x) | abs(-4) | 4 |
DIV et MOD reviennent sans cesse : n MOD 2 = 0 teste si n est pair, n MOD 10 donne le chiffre des unités, n DIV 10 enlève ce chiffre, secondes DIV 60 donne des minutes. Le lien avec la division euclidienne (17 = 5 × 3 + 2) est fait dans le cours d'arithmétique, au chapitre division euclidienne.
Les priorités sont celles des maths : puissance, puis *, /, //, %, puis + et -. Les parenthèses lèvent le doute : 2 + 3 * 4 vaut 14, (2 + 3) * 4 vaut 20.
Traduire une formule
Une formule écrite « en deux dimensions » (fraction, racine, exposant) doit être mise en ligne. Le programme demande de savoir le faire dans les deux sens.
| Formule mathématique | En ligne (Python) |
|---|---|
| (a + b) / 2c | (a + b) / (2 * c) |
| a² + b² | a ** 2 + b ** 2 |
| √(x² + y²) | math.sqrt(x ** 2 + y ** 2) (après import math) |
| prix × (1 + t/100)ⁿ | prix * (1 + t / 100) ** n |
L'oubli le plus fréquent concerne le dénominateur : a + b / 2 * c calcule a + (b/2)·c. Mets des parenthèses autour de tout numérateur et de tout dénominateur qui contient une opération.
Les fonctions mathématiques usuelles
Le programme inclut les fonctions d'arrondi et un générateur de nombres pseudo-aléatoires. En Python, certaines sont disponibles directement, les autres sont dans les modules math et random.
import math
import random
print(round(3.14159, 2)) # arrondi à 2 décimales
print(int(3.9), int(-3.9)) # troncature : on coupe la partie décimale
print(math.floor(-3.7), math.ceil(3.2)) # partie entière inférieure, supérieure
print(math.sqrt(16))
de = random.randint(1, 6) # entier au hasard entre 1 et 6 inclus
print(1 <= de <= 6)
3.14
3 -3
-4 4
4.0
True
Comparer des valeurs
Les opérateurs de comparaison donnent un booléen. On compare des nombres entre eux ou des chaînes entre elles.
| Pseudo-code | Python | Exemple | Valeur |
|---|---|---|---|
= | == | 3 == 3.0 | True |
≠ | != | "oui" != "Oui" | True |
<, ≤ | <, <= | "abc" < "abd" | True |
>, ≥ | >, >= | "10" > "9" | False |
Les chaînes se comparent caractère par caractère, selon le code de chaque caractère : c'est l'ordre du dictionnaire pour des mots en minuscules sans accent, mais toutes les majuscules passent avant les minuscules ("Z" < "a" est vrai) et "10" est avant "9", car "1" est avant "9". Pour comparer des nombres saisis, convertis-les d'abord.
Python accepte aussi les comparaisons chaînées, comme en maths : 0 <= note <= 20.
Les opérateurs booléens
Ils combinent des conditions. Le programme cite non, et, ou et oux (ou exclusif).
| Pseudo-code | Python | Vrai quand… |
|---|---|---|
NON a | not a | a est faux |
a ET b | a and b | les deux sont vrais |
a OU b | a or b | au moins un est vrai |
a OUX b | a != b (sur des booléens) | exactement un est vrai |
Les tables de vérité, les lois de De Morgan et la simplification d'expressions sont au cours d'algèbre de Boole. Retiens ici les deux lois qui servent tous les jours : NON (a ET b) équivaut à (NON a) OU (NON b), et NON (a OU b) équivaut à (NON a) ET (NON b). Par exemple, « la note n'est pas entre 0 et 20 » s'écrit note < 0 or note > 20.
L'évaluation partielle. Python, comme la plupart des langages, s'arrête dès que le résultat est connu : dans a and b, si a est faux, b n'est pas évalué ; dans a or b, si a est vrai, b n'est pas évalué. C'est utile pour se protéger :
nb = 0
total = 50
if nb != 0 and total / nb > 10:
print("Moyenne supérieure à 10")
else:
print("Pas de moyenne calculable ou moyenne trop basse")
Si nb vaut 0, la division n'est jamais calculée : pas d'erreur ZeroDivisionError. Inverse les deux conditions et le programme plante. Le programme du BTS cite justement l'évaluation partielle parmi les effets à connaître.
Les opérateurs bit à bit
Un entier est stocké en binaire ; les opérateurs bit à bit travaillent sur chaque bit séparément. Le programme demande de les interpréter en termes de masque, de mise à un, de mise à zéro et de changement d'état.
| Opérateur | Python | Effet | Exemple sur 4 bits |
|---|---|---|---|
| ET bit à bit | & | 1 seulement si les deux bits valent 1 | 1100 & 1010 = 1000 |
| OU bit à bit | | | 1 si au moins un bit vaut 1 | 1100 | 1010 = 1110 |
| OU exclusif | ^ | 1 si les bits diffèrent | 1100 ^ 1010 = 0110 |
| Négation | ~ | Inverse chaque bit | |
| Décalages | <<, >> | Décale les bits à gauche ou à droite | 0011 << 1 = 0110 |
Une application de gestion des droits code les permissions sur des bits : lecture = 1 (001), écriture = 2 (010), suppression = 4 (100).
LECTURE, ECRITURE, SUPPRESSION = 1, 2, 4
droits = LECTURE | ECRITURE # mise à un de deux bits : 011, soit 3
print(droits)
print(droits & SUPPRESSION != 0) # masque : le bit suppression est-il à 1 ?
droits = droits | SUPPRESSION # mise à un : 111, soit 7
droits = droits & ~ECRITURE # mise à zéro : 101, soit 5
print(droits)
droits = droits ^ LECTURE # changement d'état : 100, soit 4
print(droits)
3
False
5
4
Le même calcul donne l'adresse d'un réseau : on fait un ET entre l'adresse IP et le masque de sous-réseau, octet par octet. Pour 192.168.1.200 avec le masque 255.255.255.192, le dernier octet donne 200 & 192 = 11001000 & 11000000 = 11000000 = 192 : le réseau est 192.168.1.192. Le cours de réseaux détaille le calcul, et le chapitre 11 montre comment convertir en binaire.
Convertir un type en un autre
Le transtypage (ou conversion) transforme une valeur d'un type en un autre. Il est indispensable après une saisie, et piégeux quand la conversion perd de l'information.
| Conversion | Exemple | Résultat | Attention |
|---|---|---|---|
| Chaîne → entier | int("42") | 42 | int("3.5") et int("abc") lèvent ValueError |
| Chaîne → réel | float("3.5") | 3.5 | float("3,5") lève ValueError : il faut un point |
| Réel → entier | int(3.9) | 3 | Troncature, pas arrondi |
| Nombre → chaîne | str(42) + " postes" | "42 postes" | Sans str, 42 + " postes" lève TypeError |
| Vers booléen | bool(""), bool("0"), bool(0) | False, True, False | Une chaîne non vide est vraie, même "0" |
Quand une saisie peut être invalide, il faut contrôler avant de convertir, par exemple avec texte.isdigit() (vrai si la chaîne ne contient que des chiffres), ou intercepter l'erreur avec try/except (chapitre 5).
Exercices
Exercice 1 sur 6 Trace d'affectations Réussi À revoir
Donne la valeur finale de x, y et z.
x ← 4
y ← x × 3
z ← y - x
x ← z + y
y ← y MOD 5
z ← z DIV 3
Voir la réponseMasquer la réponse de l'exercice 1
| Instruction | x | y | z |
|---|---|---|---|
x ← 4 | 4 | ? | ? |
y ← x × 3 | 4 | 12 | ? |
z ← y - x | 4 | 12 | 8 |
x ← z + y | 20 | 12 | 8 |
y ← y MOD 5 | 20 | 2 | 8 |
z ← z DIV 3 | 20 | 2 | 2 |
À la fin, x vaut 20, y vaut 2 et z vaut 2.
Tu avais trouvé ?
Exercice 2 sur 6 Rotation de trois variables Réussi À revoir
a, b et c valent 1, 2 et 3. Écris les affectations qui font tourner les valeurs : à la fin, a vaut 2, b vaut 3 et c vaut 1. Utilise une seule variable temporaire, puis donne la version Python en une ligne.
Voir la réponseMasquer la réponse de l'exercice 2
temp ← a // temp = 1
a ← b // a = 2
b ← c // b = 3
c ← temp // c = 1
En Python : a, b, c = b, c, a. Le côté droit est évalué en entier avant l'affectation, il vaut (2, 3, 1).
Tu avais trouvé ?
Exercice 3 sur 6 Heures, minutes, secondes Réussi À revoir
Écris l'algorithme puis le programme Python qui lit une durée en secondes et l'affiche en heures, minutes et secondes. Que donne 7385 secondes ?
Voir la réponseMasquer la réponse de l'exercice 3
Algorithme ConvertirDuree
// Entrée : total (entier), une durée en secondes
// Sortie : la durée en h, min, s, affichée
Variables
total, h, m, s : entier
Début
Saisir(total)
h ← total DIV 3600
m ← (total MOD 3600) DIV 60
s ← total MOD 60
Afficher(h, " h ", m, " min ", s, " s")
Fin
total = int(input("Durée en secondes ? "))
h = total // 3600
m = (total % 3600) // 60
s = total % 60
print(h, "h", m, "min", s, "s")
7385 = 2 × 3600 + 185, et 185 = 3 × 60 + 5 : l'affichage est 2 h 3 min 5 s.
Tu avais trouvé ?
Exercice 4 sur 6 Expressions en Python Réussi À revoir
Écris en Python : (1) la moyenne de a, b, c ; (2) le prix après une remise de r % ; (3) l'aire d'un disque de rayon r ; (4) « n est un multiple de 3 mais pas de 9 » ; (5) « l'âge est entre 18 et 25 ans inclus ».
Voir la réponseMasquer la réponse de l'exercice 4
(a + b + c) / 3: sans parenthèses, seulcserait divisé.prix * (1 - r / 100)math.pi * r ** 2, aprèsimport math.n % 3 == 0 and n % 9 != 018 <= age <= 25, ouage >= 18 and age <= 25.
Tu avais trouvé ?
Exercice 5 sur 6 Ce que Python affiche Réussi À revoir
Prévois l'affichage de chaque ligne, puis vérifie dans la console.
print(17 / 4, 17 // 4, 17 % 4)
print("3" + "4", 3 + 4)
print(int("12") * 2, "12" * 2)
print(10 / 5)
print(int(7.99), round(7.99))
print("Paris" < "lyon")
Voir la réponseMasquer la réponse de l'exercice 5
4.25 4 1
34 7
24 1212
2.0
7 8
True
"3" + "4" colle deux chaînes. "12" * 2 répète la chaîne. 10 / 5 donne un réel, 2.0. int tronque, round arrondit. "P" (majuscule) a un code plus petit que "l" (minuscule), donc "Paris" < "lyon" est vrai, alors que Lyon passe avant Paris dans un dictionnaire.
Tu avais trouvé ?
Exercice 6 sur 6 Droits d'accès Réussi À revoir
Avec LECTURE = 1, ECRITURE = 2, SUPPRESSION = 4 et ADMIN = 8, un utilisateur a droits = 13.
- Quels droits a-t-il ? (Écris 13 en binaire.)
- Quelle expression teste s'il a le droit d'écriture ?
- Quelle instruction lui retire le droit
ADMIN? Que vaut alorsdroits?
Voir la réponseMasquer la réponse de l'exercice 6
- 13 = 8 + 4 + 1 =
1101en binaire : lecture, suppression et administration, mais pas l'écriture. droits & ECRITURE != 0, qui vautFalseici, car1101 & 0010 = 0000.droits = droits & ~ADMIN(mise à zéro du bit de valeur 8).droitsvaut alors0101, soit 5.
Tu avais trouvé ?