.. _prog-e3-comparaison-langages: ************************ Comparaison des langages ************************ Une différence majeure entre Python et C est la manière dont on exécute un programme dans chacun des deux langages : - Python utilise un interpréteur qui lit le code source et l'exécute directement sur toute cible matérielle sur laquelle l'interpréteur Python est installé ; - C nécessite une étape de compilation spécifique pour produire un exécutable sur chaque cible matérielle. Par exemple un même code doit être compilé une fois pour Windows et une autre fois pour Linux. .. quiz:: quizz-comp-intro :title: Python vs C : exécution - :quiz:`{"type":"TF","answer":"T"}` Python utilise un interpréteur pour exécuter directement le code source - :quiz:`{"type":"TF","answer":"F"}` Un programme C peut être exécuté sans étape de compilation préalable - Pour exécuter un programme C, la première étape nécessaire est la :quiz:`{"type":"SC","values":"compilation,interprétation,édition,simulation","answer":"compilation"}` - En C, un même code source doit être :quiz:`{"type":"FB","answer":"compilé","flags":"fuzzy"}` pour chaque cible matérielle différente Structuration du code ===================== Pour une première comparaison de la façon d'écrire et d'exécuter du code dans chacun des deux langages, considérons le calcul du `PGCD `_ de deux entiers selon l'algorithme d'Euclide :: pgcd(a, b) = pgcd( b, reste(a, b) ) pour b ≠ 0 pgcd(a, 0) = a PGCD : code Python ------------------ Le code Python correspondant au calcul du PGCD selon l'algorithme d'Euclide est donné ci dessous: .. code-block:: python :linenos: # gcd.py def gcd(a, b): if b == 0: return a else: return gcd(b, a % b) def main(): print("GCD: " + str(gcd(24, 40))) if __name__ == "__main__": main() En Python le code est organisé en quatre parties : #. l'importation de bibliothèques externes. Il n'y en a pas besoin ici, et cette partie est vide ; #. la définition des variables globales. Il n'y en a pas besoin ici, et cette partie est vide ; #. la définition des fonctions secondaires. Ici une seule fonction secondaire, :func:`gcd` qui prend en argument deux nombres, implémente l'algorithme d'Euclide, et retourne le PGCD (lignes 3-7) ; #. la définition de la fonction principale :func:`main` qui appelle les fonctions précédentes. Ici :func:`gcd` est appelée avec les arguments 24 et 40, puis le résultat est affiché (lignes 9-10) ; #. l'appel de la fonction :func:`main` déclenché lors de l'exécution du programme (lignes 12-13). .. exercice:: Calcul du PGCD avec Python (sans IA) Il est nécessaire que VS Code soit démarré sur la machine hôte, pointe vers le répertoire ``e3-programmation-labs-student`` et que le container Docker soit lancé. - Créer un fichier :file:`exercices/gcd.py` et copier le code ci dessus ; - Exécuter le programme avec la commande ``python3 gcd.py`` ; - Vérifier que le résultat affiché est correct. - Lorsque c'est le cas : - ``git add .`` - ``git commit -m "Calcul du PGCD avec Python"`` - ``git push`` PGCD : code C ------------- Voici le même programme écrit en C : .. code-block:: c :linenos: // gcd.c #include int gcd(int a, int b) { if (b == 0) { return a; } else { return gcd(b, a % b); } } int main() { printf("GCD: %d\n", gcd(24, 40)); return 0; } L'organisation du code est quasi identique : #. l'importation des bibliothèques externes (ligne 3) ; #. la définition des variables globales. Il n'y en a pas besoin ici, et cette partie est vide ; #. la définition des fonctions secondaires (lignes 5-15) ; #. la définition de la fonction principale :func:`main` (lignes 17-21) ; #. il n'y a pas d'appel explicite de :func:`main`, celui ci est déclenché par l'exécution du programme. Il y a cependant des différences dans le code proprement dit : - pour utiliser :func:`printf`, il faut "importer" une bibliothèque (ligne 3), alors que la fonction :func:`print` fait partie du langage en Python ; - les variables doivent être déclarées explicitement alors que Python pratique l'inférence de type. Ici ça concerne les paramètres de la fonction ainsi que sa valeur de retour (ligne 5) ; - la structuration du code est définie par une paire d'accolades alors qu'en Python elle est définie par l'indentation ; - toujours pour la structuration, chaque instruction C se termine par un ``;`` ; - le prédicat d'un test (ligne 7) doit être encapsulé dans une paire de parenthèses ``( )`` ; - il est courant que la fonction :func:`main` retourne 0 (ligne 20) pour signifier au système d'exploitation que tout s'est bien passé. .. exercice:: Calcul du PGCD avec C (sans IA) Il est nécessaire que VS Code soit démarré sur la machine hôte, pointe vers le répertoire ``e3-programmation-labs-student`` et que le container Docker soit lancé. - Créer le fichier :file:`exercices/gcd.c` et copier le code ci dessus ; - Compiler le programme avec la commande ``gcc -std=c99 -Wall -Wextra gcd.c -o gcd`` ; - Exécuter le programme avec la commande ``./gcd`` ; - Vérifier que le résultat affiché est correct. - Lorsque c'est le cas : - ``git add .`` - ``git commit -m "Calcul du PGCD avec C"`` - ``git push`` .. quiz:: quizz-comp-struct :title: Structuration du code - :quiz:`{"type":"TF","answer":"T"}` La structure d'un programme Python et d'un programme C sont similaires - :quiz:`{"type":"TF","answer":"F"}` En Python, la fonction main est appelée automatiquement au démarrage du programme - :quiz:`{"type":"TF","answer":"T"}` En C, il est nécessaire d'importer ``stdio.h`` pour pouvoir utiliser ``printf()`` - Le compilateur utilisé dans les exemples C de ce cours est :quiz:`{"type":"SC","values":"gcc,g++,javac,clang","answer":"gcc"}` On vient de constater qu'il y a une grande similitude entre la structuration des deux langages. Observons maintenant les différences de code mises en évidence ici de manière approfondie. Les variables ============= Les variables sont des zones de mémoire nommées qui permettent de stocker des valeurs. Elles sont utilisées pour mémoriser des informations et les réutiliser dans le programme. .. _prog-e3-variables-c: Les variables en C ------------------ Le langage C nécessite de déclarer explicitement le type des variables utilisées. Cette connaissance est utilisée par le compilateur et permet d'optimiser la mémoire et le temps d'exécution. Les principaux types sont : - ``int`` pour les entiers (32 bits) ; - ``double`` pour les nombres rééls (64 bits) ; - ``char`` pour les caractères (8 bits). .. note:: C dispose en fait de nombreux autres types de données qu'on n'abordera pas dans le cadre de ce cours. La table ci dessous en donne la liste, les bornes des valeurs qu'ils permettent de représenter sans erreur, et le spécificateur à utiliser avec ``printf()``. Les valeurs ci dessous sont dépendantes de la plateforme matérielle (CPU) et logicielle (compilateur). Elles sont données ici pour une architecture Intel(R) Core(TM) i7-6700 CPU, une distribution Linux Ubuntu 20.04 et le compilateur gcc 9.4.0. .. csv-table:: Types de données en C :file: files/c/c-03-programme-data-types.csv :header-rows: 1 :delim: ; :align: center Contrairement à Python : - C n'a pas de type booléen. La *vérité* est stockée dans un ``int`` (ce qui n'est pas très efficace d'un point de vue encombrement mémoire). Dans un prédicat, ``0`` est évalué à "False" et tout autre nombre entier est évalué à "True" ; - le typage en C est statique, c'est à dire qu'une même variable ne peut pas changer de type au cours de la vie d'un programme. Pour approfondir la notion de *vérité* en C, répondez aux questions suivantes. .. quiz:: quizz-01 :title: La vérité en C - Quel est le nombre d'octets utilisé pour stocker un entier ? :quiz:`{"type":"FB","answer":"4", "size":5}` - Quel est le nombre de bits utilisé pour stocker un entier ? :quiz:`{"type":"FB","answer":"32", "size":5}` - Quel est le nombre minimal théorique de bits nécessaire pour stocker un booléen ? :quiz:`{"type":"FB","answer":"1", "size":5}` Déclaration et affectation .......................... L'instruction ci dessous déclare une variable ``x`` de type ``int``: .. code-block:: c int x; Ceci réserve un espace nommé dans la mémoire, à une adresse définie par le compilateur, de taille définie par le type. La valeur est indéterminée. .. image:: images/c-03-programme-fig-01.png :width: 20% :align: center On lui affecte ensuite une valeur avec l'instruction : .. code-block:: c x = 37; On peut également effectuer les 2 opérations avec une seule instruction : .. code-block:: c int x = 37; .. image:: images/c-03-programme-fig-02.png :width: 20% :align: center On a une bijection entre la zone mémoire réservée et le nom qu'on lui attribue. C'est une différence majeure avec Python, on aura l'occasion de le voir plus loin. .. important:: Une variable doit être déclarée **une fois et une seule** dans le domaine dans lequel elle est utilisée, avec deux possibilités : - déclaration et initialisation à deux endroits distincts du code ; - déclaration et initialisation sur la même ligne. Si on tente de lui affecter un type différent, le compilateur effectue la conversion nécessaire si elle est possible/pertinente. Ci dessous, conversion d'un nombre décimal en entier : .. code-block:: c int x = 37.0; // x = 37 Déclarer une autre variable et lui affecter le contenu d'une autre réserve **un autre** espace mémoire. Ainsi le code : .. code-block:: c int x = 37; int y = x; va réserver un nouvel espace mémoire qui différera du premier : - par son adresse ; - et par le nom qui permet de le référencer. .. image:: images/c-03-programme-fig-03.png :width: 20% :align: center .. quiz:: quizz-comp-decl :title: L'encombrement mémoire - Les 4 derniers digits hexadécimaux de l'adresse de ``x`` sont :quiz:`{"type":"FB","answer":"ca00", "size":5}` - Les 4 derniers digits hexadécimaux de l'adresse de ``y`` sont :quiz:`{"type":"FB","answer":"ca04", "size":5}` - 4 digits hexadécimaux représentent :quiz:`{"type":"FB","answer":"2", "size":5}` octets - :quiz:`{"type":"TF","answer":"T"}` Sachant que ``x`` est un ``int``, le compilateur a réservé une adresse mémoire contigüe pour ``y`` .. quiz:: quizz-comp-c-vars :title: Les variables en C - :quiz:`{"type":"TF","answer":"T"}` En C, le type des variables doit être déclaré explicitement avant leur utilisation - :quiz:`{"type":"TF","answer":"F"}` C dispose d'un type booléen natif - :quiz:`{"type":"TF","answer":"F"}` En C, une même variable peut changer de type au cours de l'exécution d'un programme - Le type C pour stocker un entier sur 32 bits est :quiz:`{"type":"SC","values":"int,double,char,bool","answer":"int"}` - Le type C pour stocker un nombre réel sur 64 bits est :quiz:`{"type":"SC","values":"int,double,char,float","answer":"double"}` - Dans un prédicat C, la valeur ``0`` est évaluée à :quiz:`{"type":"FB","answer":"False","flags":"fuzzy"}` - Une variable C doit être déclarée :quiz:`{"type":"SC","values":"une seule fois,à chaque utilisation,deux fois,jamais","answer":"une seule fois"}` dans son domaine d'utilisation Les variables en Python ----------------------- C est un langage ancien et ne disposait pas des méthodes modernes de gestion automatique de la mémoire. Pour garantir une exécution rapide, il était **nécessaire** d'interagir directement avec la mémoire. Ce mécanisme est implémenté à très bas niveau dans le langage et perdure aujourd'hui, ce qui lui assure toujours une grande vitesse d'exécution, au détriment d'une certaine complexité de programmation. En revanche Python, dispose d'un mécanisme automatisé de gestion de mémoire qui permet : - de réserver automatiquement un emplacement en mémoire en fonction de l'objet manipulé ; - de faire croître dynamiquement la taille réservée tout au long de la vie de l'objet ; - de libérer automatiquement la mémoire lorsque l'objet n'est plus utilisé. Pour illustrer ce fonctionnement différent, observons l'affectation d'une variable en Python. .. code-block:: python >>> x = 37 >>> id(x) 1658682502576 Un objet est créé en mémoire, et **une référence** lui est affectée. La fonction :func:`id` peut être vue comme une fonction de localisation en mémoire mais, contrairement au C, ne véhicule pas d'information sur la position **physique** en mémoire. .. image:: images/c-03-programme-fig-04.png :width: 40% :align: center Contrairement à C, l'affectation de ``x`` à une nouvelle variable **ne créée pas de nouvel objet** en mémoire, comme le montre le code suivant .. code-block:: python >>> y = x >>> id(y) 1658682502576 >>> x is y True qui peut s'illustrer avec le schéma suivant : .. image:: images/c-03-programme-fig-05.png :width: 40% :align: center .. quiz:: quizz-comp-py-vars :title: Les variables en Python - :quiz:`{"type":"TF","answer":"F"}` En Python, l'affectation ``y = x`` crée un nouvel objet en mémoire - :quiz:`{"type":"TF","answer":"T"}` En Python, la gestion de la mémoire est automatique - :quiz:`{"type":"TF","answer":"F"}` La fonction ``id()`` en Python donne la position physique de l'objet en mémoire - Après ``x = 37`` puis ``y = x`` en Python, l'expression ``x is y`` renvoie :quiz:`{"type":"SC","values":"True,False,None,37","answer":"True"}` - En Python, une variable est une :quiz:`{"type":"FB","answer":"référence","flags":"fuzzy"}` vers un objet en mémoire Variables locales ----------------- En C, si des variables locales sont nécessaires, la déclaration de ces variables est placée au début de la fonction qui les utilise. L'algorithme d'Euclide utilisé précédemment n'avait pas besoin de variables additionnelles. Les seuls paramétres ``a`` et ``b`` suffisaient. Si l'on omet de déclarer une variable, le compilateur produit une erreur avec un message indicatif. La lecture approfondie de ce type de message est une étape nécessaire dans la conception d'un programme. En Python, les variables locales sont créées automatiquement lors de leur première affectation. .. quiz:: quizz-comp-local-vars :title: Variables locales - :quiz:`{"type":"TF","answer":"T"}` En C, les variables locales sont déclarées au début de la fonction qui les utilise - :quiz:`{"type":"TF","answer":"F"}` En C, omettre la déclaration d'une variable est ignoré silencieusement par le compilateur - :quiz:`{"type":"TF","answer":"F"}` En Python, les variables locales doivent être déclarées explicitement avant leur première utilisation - En C, l'oubli de la déclaration d'une variable provoque une :quiz:`{"type":"SC","values":"erreur de compilation,avertissement,exception,segfault","answer":"erreur de compilation"}` Délimitation des blocs ====================== Un bloc d'instructions est un ensemble d'instructions regroupées pour être exécutées ensemble. Il est souvent utilisé dans les structures de contrôle (conditions, boucles, fonctions, etc.) pour définir quelles instructions doivent être exécutées dans un certain contexte. En Python, les espaces et les tabulations sont utilisés pour délimiter les blocs. Une même information est utilisée pour améliorer la lisibilité du code (pour l'humain) et pour structurer le code (pour la machine). .. warning:: Un code mal structuré peut être valide syntaxiquement et s'exécuter correctement si l'indentation a un sens pour une autre structure de contrôle. Mais le comportement du programme sera alors différent de celui attendu. En C, les blocs sont délimités par des accolades ``{ }`` (pour la machine). Il faut ajouter des informations de lisibilité pour améliorer la compréhension du code. Les espaces et les tabulations sont utilisés pour cela. Ce qui signifie que le code ci dessous est parfaitement valide (pour la machine), quoique assez illisible (pour l'humain). .. code-block:: c :linenos: // gcd2.c #include int gcd(int a, int b){if (b == 0){return a;}else{return gcd(b, a % b);}}int main(){printf("GCD: %d\n", gcd(24, 40));return 0;} Python force le programmeur à écrire un programme lisible. Ce n'est pas le cas de C mais la plupart des environnements de développements modernes, `VS Code `_ par exemple, utilisent des formatteurs qui indentent le code de façon efficace. En C, les accolades ``{ }`` sont utilisées pour structurer le code. Elles sont optionnelles si le bloc ne contient qu'une seule instruction. Ainsi, la fonction ci dessous est du code C valide .. code-block:: c :linenos: int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); } que l'on peut, sans perte de lisibilité, également écrire : .. code-block:: c :linenos: int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); } .. quiz:: quizz-comp-blocs :title: Délimitation des blocs - :quiz:`{"type":"TF","answer":"T"}` En Python, l'indentation seule délimite les blocs d'instructions - :quiz:`{"type":"TF","answer":"F"}` En C, les accolades { } sont toujours obligatoires, même si un bloc ne contient qu'une seule instruction - :quiz:`{"type":"TF","answer":"V"}` Un code mal indenté peut quand même s'exécuter correctement - En C, les blocs de code sont délimités par des :quiz:`{"type":"FB","answer":"accolades","flags":"fuzzy"}` - En Python, l'indentation sert à la fois à la lisibilité et à :quiz:`{"type":"SC","values":"structurer le code,compiler le code,optimiser le code,documenter le code","answer":"structurer le code"}` Les commentaires ================ Le code source d'un programme contient des instructions écrites par un humain à destination d'une machine dans un langage déterminé (C ou Python par exemple). Il doit également contenir des informations facilitant la compréhension, la relecture et la maintenance, pour celui qui l'a écrit mais également pour ceux amenés à intervenir sur le code à un moment ou un autre de la vie du programme. On signale à la machine que ces instructions ne sont pas a exécuter avec une syntaxe particulière : - en Python, tous les caractères à droite du caractère ``#`` seront ignorés ; - en C : - tous les caractères à droite des caractères ``//`` seront ignorés (commentaires de ligne) ; - tous les caractères compris entre ``/*`` et ``*/`` seront ignorés (commentaires de bloc). Exemples de commentaires en Python: .. code-block:: python # gcd.py # Calcul du Greatest Common Divisor def gcd(a, b): # Algorithme d'Euclide Exemples de commentaires en C: .. code-block:: c /* gcd.c Calcul du Greatest Common Divisor */ int gcd(int a, int b) // Algorithme d'Euclide Une bonne pratique est de commenter son code en expliquant **pourquoi** on écrit une instruction et éventuellement **comment** si l'implémentation est complexe. .. quiz:: quizz-comp-comments :title: Les commentaires - :quiz:`{"type":"TF","answer":"T"}` En Python, le caractère ``#`` débute un commentaire de fin de ligne - :quiz:`{"type":"TF","answer":"F"}` En Python, les commentaires de bloc s'écrivent entre ``/*`` et ``*/`` - En C, un commentaire de ligne commence par les caractères :quiz:`{"type":"FB","answer":"//","size":3}` - En C, un commentaire de bloc se termine par les caractères :quiz:`{"type":"FB","answer":"*/","size":3}` - :quiz:`{"type":"TF","answer":"T"}` Il est recommandé de commenter en expliquant pourquoi une instruction est nécessaire plutôt que comment elle fonctionne L'affichage =========== :func:`printf` en C ------------------- En C, l'affichage est contrôlé par la fonction :func:`printf`. Cette fonction comporte ``n`` paramètres (au moins 1) : - le premier paramètre est une chaîne de formatage : - contenant un texte fixe ; - et éventuellement ``n-1`` places réservées pour l'affichage de ``n-1`` variables ; - les ``n-1`` variables éventuelles à afficher. Ainsi l'instruction .. code-block:: c printf("GCD: %d\n", gcd(24, 40)) se décompose en : - la chaîne de formatage : ``"GCD: %d\n"`` dans laquelle ``%d`` est un espace réservé pour la valeur à afficher. Les autres caractères sont imprimés tels quels ; - et la valeur à afficher : ``gcd(24, 40)`` qui sera insérée dans l'espace réservé. Dans la chaine de formatage, on utilise le caractère spécial ``\n`` qui insère un saut de ligne. Voici les caractères spéciaux les plus courants: - ``\n`` : saut de ligne ; - ``\t`` : tabulation ; - ``\\`` : le caractère ``\`` ; - ``\"`` : le caractère ``"``. Les espaces réservés suivants sont les plus courants : - ``%d`` : nombre entier. Par exemple 1000 ; - ``%f`` : nombre réél en notation décimale. Par exemple 1000.0 ; - ``%e`` : nombre réél en notation scientifique. Par exemple 1.000000e3 ; - ``%c`` : caractère alphanumérique ; - ``%s`` : chaîne de caractères. Il y a beaucoup d'autres paramètres permettant de contrôler l'affichage. Une référence complète `ici `_. .. quiz:: quizz-02 :title: La chaine de formatage On souhaite écrire un programme qui affiche le résultat de l'opération de multiplication de deux entiers, de telle sorte qu'un exemple d'affichage dans le terminal puisse être:: $ ./mult 3 x 5 = 15 $ - Quelle est le contenu de la chaine de formatage correspondante ? :quiz:`{"type":"FB","answer":"\"%d x %d = %d\\n\"", "size":20}` :func:`print` en Python ----------------------- La fonction :func:`print` en Python est plus simple à utiliser que :func:`printf` en C. Elle prend un nombre variable de paramètres, et affiche leur contenu dans le terminal. Par défaut, les paramètres sont séparés par un espace et un saut de ligne est inséré à la fin de l'affichage. On peut réaliser le même affichage que précédemment avec l'instruction : .. code-block:: python print(3, "x", 5, "=", 3*5) Pour un formattage plus évolué, on utilise des `f-strings `_. Il s'agit de chaînes de caractères précédées d'un ``f`` et dans lesquelles on peut insérer des expressions entre accolades ``{ }``. Ainsi, l'affichage précédent peut être réalisé avec l'instruction : .. code-block:: python x = 3 y = 5 print(f"{x} x {y} = {x*y}") Les fonctions ============= C'est une bonne pratique que d'encapsuler tout le code dans des fonctions mais ce n'est pas requis par le langage Python. Pour C au contraire, cette structuration est indispensable. Reprenons le programme permettant de calculer le PGCD utilisé en début de chapitre. En langage C ------------ La ligne 5 représente la signature de la fonction, que l'on peut décomposer en trois parties : - le type de la valeur de retour : ``int`` ; - le nom de la fonction : :func:`gcd` ; - la liste de ses paramètres formels typés placés entre parenthèses : ``int a, int b``. Le corps de la fonction est placé entre accolades ``{ }`` et doit retourner une valeur dont le type est cohérent avec la signature. Si une fonction ne retourne rien, le type ``void`` est utilisé. Dans un programme C découpé en fonctions, il doit exister une fonction principale :func:`main`. Elle est ici définie à la ligne 17 et ne prend aucun paramètre. Elle appelle la fonction :func:`gcd` avec les paramètres 24 et 40, puis affiche le résultat. La fonction :func:`main` est obligatoire dans un programme C. Elle peut prendre des paramètres, mais ce n'est pas le cas ici. Elle retourne un entier dont la valeur est utilisée par le système d'exploitation pour connaitre le statut du programme après son exécution. Par convention, la valeur 0 est retournée si tout s'est bien passé, et un entier différent de 0 en cas de problème dans l'exécution. .. note:: Rigoureusement on peut placer ces fonctions à la suite de la fonction :func:`main` mais il faut alors que le prototype des fonctions en question soit placé avant :func:`main`, le plus souvent dans un fichier ``.h``. A titre d'exemple, la fonction :func:`printf` est utilisable dans :func:`main` car elle est déclarée dans ``stdio.h``. En Python --------- Pour le langage Python, la signature des fonctions n'impose pas de préciser le type des arguments ni celui de la valeur de retour. C'est une caractéristique du typage dynamique de Python, qui permet d'écrire des fonctions plus génériques. Ceci ne s'applique pas pour cet exemple car la fonction :func:`gcd` ne peut être utilisée qu'avec des entiers. Une bonne pratique consiste cependant à utiliser le typing pour informer sur le type des paramètres et de la valeur de retour. Ainsi, la signature de la fonction :func:`gcd` pourrait être écrite comme suit : .. code-block:: python def gcd(a: int, b: int) -> int: if b == 0: return a else: return gcd(b, a % b) Cette information n'est pas utilisée par l'interpréteur Python mais peut être utilisée par des outils d'analyse statique du code pour détecter des incohérences dans le typage. En Python, l'appel de :func:`main` n'est pas automatique, il faut le déclencher. .. quiz:: quizz-comp-fonctions :title: Les fonctions - :quiz:`{"type":"TF","answer":"T"}` En C, la signature d'une fonction doit préciser le type des paramètres et de la valeur de retour - :quiz:`{"type":"TF","answer":"F"}` En Python, il est obligatoire de typer les paramètres dans la signature d'une fonction - :quiz:`{"type":"TF","answer":"T"}` En C, la fonction main est obligatoire dans tout programme - :quiz:`{"type":"TF","answer":"F"}` En Python, l'appel de la fonction main est automatique au démarrage du programme - Une fonction C qui ne retourne aucune valeur utilise le type :quiz:`{"type":"FB","answer":"void","size":5}` - Par convention, la fonction main retourne :quiz:`{"type":"FB","answer":"0","size":3}` si le programme s'est exécuté sans erreur Les opérateurs ============== La plupart des opérateurs sont communs à Python et C. Voici les principaux. Les opérateurs arithmétiques ---------------------------- Les opérateurs arithmétiques permettent le calcul mathématique. .. list-table:: Les opérateurs arithmétiques :widths: 25 25 25 25 :header-rows: 1 * - Opérateur C - Description - Example - Python * - ``+`` - Addition - a + b - ``+`` * - ``-`` - Soustraction - a - b - ``-`` * - ``*`` - Multiplication - a * b - ``*`` * - ``/`` - Division - a / b - ``/`` * - ``%`` - Reste de la division entière - a % b - ``%`` * - ``++`` - Incrémentation - a++ - * - ``--`` - Décrémentation - a\-\- - Les opérateurs relationnels --------------------------- Les opérateurs relationnels permettent de mettre en oeuvre les opérations de comparaison. .. list-table:: Les opérateurs relationnels :widths: 25 25 25 25 :header-rows: 1 * - Opérateur C - Description - Example - Python * - ``==`` - Egalité - (a == b) - ``==`` * - ``!=`` - Différence - (a != b) - ``!=`` * - ``>`` - Supérieur - (a > b) - ``>`` * - ``<`` - Inférieur - (a < b) - ``<`` * - ``>=`` - Supérieur ou égal - (a >= b) - ``>=`` * - ``<=`` - Inférieur ou égal - (a <= b) - ``<=`` Les opérateurs logiques ----------------------- Les opérateurs logiques permettent de construire des prédicats. .. list-table:: Les opérateurs logiques :widths: 25 25 25 25 :header-rows: 1 * - Opérateur C - Description - Example - Python * - ``&&`` - Et logique - (a && b) - ``and`` * - ``||`` - Ou logique - (a || b) - ``or`` * - ``!`` - Négation - ( !a ) - ``not`` Les opérateurs d'affectation ---------------------------- Les opérateurs d'affectation permettent d'affecter une valeur à une variable. .. list-table:: Les opérateurs d'affectation :widths: 25 25 25 25 :header-rows: 1 * - Opérateur C - Description - Example - Python * - ``=`` - Affectation - a = b - ``=`` * - ``+=`` - Addition et affectation - a += 1 - ``+=`` * - ``-=`` - Soustraction et affectation - a -= 1 - ``-=`` * - ``*=`` - Multiplication et affectation - a \*= 2 - ``*=`` * - ``/=`` - Division et affectation - a /= 2 - ``/=`` * - ``%=`` - Modulo et affectation - a %= 2 - ``%=`` Priorité des opérateurs ----------------------- Lors de l'évaluation d'expressions complexes, des règles de priorité s'appliquent. En cas de doute, il sera sage d'utiliser les parenthèses pour contrôler l'ordre d'application des opérateurs. Par exemple, l'expression ``x = 7 + 3 * 2`` est évaluée à ``13`` parce que l'opérateur ``*`` a une priorité supérieure à ``+``. Il sera cependant sage d'écrire ``x = 7 + (3 * 2)``. Voici la liste des opérateurs classés par ordre de priorités décroissantes. .. list-table:: La priorité des opérateurs :widths: 50 50 :header-rows: 1 * - Opérateurs C - Associativité * - ``()``, ``[]``, ``++``, ``--`` - gauche à droite * - ``+``, ``-``, ``!`` - droite à gauche * - ``*``, ``/``, ``%`` - gauche à droite * - ``+``, ``-`` - gauche à droite * - ``<``, ``<=``, ``>``, ``>=`` - gauche à droite * - ``==``, ``!=`` - gauche à droite * - ``&&`` - gauche à droite * - ``||`` - gauche à droite * - ``=``, ``+=``, ``-=``, ``*=``, ``/=``, ``%=`` - droite à gauche .. list-table:: La priorité des opérateurs Python :widths: 50 50 :header-rows: 1 * - Opérateurs Python - Associativité * - ``()`` - gauche à droite * - ``**`` - gauche à droite * - ``+x``, ``-x``, ``~x`` - gauche à droite * - ``*``, ``/``, ``//``, ``%`` - gauche à droite * - ``+``, ``-`` - gauche à droite * - ``<<``, ``>>`` - gauche à droite * - ``&`` - gauche à droite * - ``^`` - gauche à droite * - ``|`` - gauche à droite * - ``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``, ``is``, ``is not``, ``in``, ``not in`` - gauche à droite * - ``not`` - gauche à droite * - ``and`` - gauche à droite * - ``or`` - gauche à droite .. quiz:: quizz-comp-operateurs :title: Les opérateurs - L'équivalent Python de l'opérateur C ``&&`` est :quiz:`{"type":"FB","answer":"and","size":4}` - L'équivalent Python de l'opérateur C ``||`` est :quiz:`{"type":"FB","answer":"or","size":3}` - L'équivalent Python de l'opérateur C ``!`` est :quiz:`{"type":"FB","answer":"not","size":4}` - :quiz:`{"type":"TF","answer":"F"}` Python dispose d'un opérateur d'incrémentation ``++`` - La valeur de l'expression ``7 + 3 * 2`` est :quiz:`{"type":"FB","answer":"13","size":3}` - L'opérateur ``%`` calcule le :quiz:`{"type":"SC","values":"reste,quotient,puissance,produit","answer":"reste"}` de la division entière - :quiz:`{"type":"TF","answer":"T"}` Python dispose de l'opérateur ``**`` (puissance) que C ne possède pas nativement