IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Cours complet d’initiation à la programmation


précédentsommairesuivant

Introduction

[…] l'informatique est la discipline qui s'applique à étudier et à définir des opérations, et où l'on opère des transformations sur des combinaisons de symboles très généraux représentant diverses informations en de nouvelles combinaisons de symboles, elles-mêmes porteuses d'informations.
G. Ifrah, Histoire Universelle des Chiffres, coll. Bouquins, t. II, p. 725.

La programmation

Un algorithme est la description d'un enchaînement de calculs et de tâches élémentaires en vue de la réalisation d'un traitement automatique de données. Ces données doivent être représentées par des structures appropriées. L'algorithme peut ensuite être codé dans un langage de programmation pour donner un programme. La programmation regroupe ces activités : algorithmique, structuration de données et codage, les deux premières étant certainement les plus importantes.

Contrairement à ce que pourrait croire un novice, la tâche principale de la conception d'un programme n'est pas l'écriture de celui-ci dans un langage informatique donné.

La réalisation d'un programme se décompose en effet en plusieurs phases. De manière simplifiée, on présente ainsi la genèse d'un programme :

  • établissement d'un cahier des charges : le problème posé ;
  • analyse du problème et décomposition de celui-ci en sous-problèmes plus ou moins indépendants et plus simples à résoudre ;
  • choix de structures de données pour représenter les objets du problème ;
  • mise en œuvre des différents algorithmes à utiliser pour résoudre les sous-problèmes ;
  • codage des algorithmes et création du programme dans un langage de programmation donné ;
  • tests (et corrections) et validation auprès des utilisateurs.

Bien souvent, dans la pratique, ces étapes ne sont pas aussi nettement découpées. Les quatre premières sont certainement les plus importantes et on peut remarquer qu'elles sont indépendantes du langage de programmation choisi, qui n'intervient normalement qu'à la cinquième étape. La dernière étape est, elle aussi, très importante et ce serait une grave erreur de penser qu'elle ne fait pas partie du cycle de création d'un programme.

Pour un débutant en informatique, étudiant de surcroît, le cahier des charges consistera souvent en un énoncé d'exercice ou de problème proposé par un enseignant. Une première tâche, et elle est souvent plus difficile qu'on ne le croit, sera de comprendre cet énoncé ! Il faudra ensuite réfléchir à la résolution de ce problème et, ensuite seulement, le coder dans un langage. On peut donc le constater, une bonne partie du travail doit se faire avec un crayon et un papier ! Une erreur (méthodologique) des débutants est souvent, une fois l'énoncé lu (ou plus souvent simplement survolé), de se ruer sur leur clavier et de commencer à taper dessus (on ne sait d'ailleurs trop quoi) et seulement alors de commencer à réfléchir à la résolution du problème.

Objectif du cours

Il s'agit de poser les notions de base en programmation impérative :

  • expressions et instructions ;
  • constantes, variables et affectation. Variables locales ;
  • types de données simples : nombres entiers ou non entiers, booléens, caractères et chaînes de caractères ;
  • expressions et instructions conditionnelles ;
  • répétition conditionnelle d'instructions (boucle tant que). Répétition non conditionnelle d'instructions (boucle pour) ;
  • fonctions et procédures. Paramètres formels, paramètres effectifs.

Dans les deux cours qui suivent (API1 et API2) sont abordées les notions :

  • tableaux ;
  • enregistrements ;
  • fichiers ;
  • récursivité ;
  • structures de données dynamiques ;
  • programmation modulaire ;
  • algorithmes de recherche et de tri ;
  • complexité des algorithmes.

Le choix du langage

Il existe de très nombreux langages impératifs : C, Pascal, Ada, Python, Caml…

Pendant quelques années nous avons utilisé le langage Pascal. Mais l'expérience a montré que la lourdeur de la syntaxe de ce langage, ainsi que certaines de ses ambiguïtés, présentaient de réelles difficultés pour des étudiants débutant en programmation. Ce langage nécessitant une phase d'édition, puis une phase de compilation avant toute exécution, il devient très vite fastidieux de tester la moindre idée d'algorithme. Pour ces raisons nous avons décidé de changer de langage.

Nous nous sommes alors tournés vers Caml. Même si à la base ce langage est avant tout un langage fonctionnel, il offre aussi la possibilité de programmer dans un style impératif. Il dispose de plusieurs modes d'exécution :

  • un mode interactif ;
  • un mode compilé(1) qui permet de produire des exécutables autonomes.

Dans ce cours, le mode interactif est le seul mode abordé. La compilation pour produire des programmes exécutables autonomes sera abordée dans un autre cours.

Caml est un langage fonctionnel dans lequel les fonctions sont des valeurs du même ordre que toute autre valeur. En particulier, une fonction peut produire une autre fonction. Par exemple, la fonction plus définie ci-dessous est une fonction qui permet d'additionner deux nombres entiers.

 
Sélectionnez
1.
2.
# let plus a b = a + b ;;
val plus : int -> int -> int = <fun>

On peut le vérifier en appliquant la fonction plus aux deux entiers 2 et 5.

 
Sélectionnez
1.
2.
# plus 2 5 ;;
- : int = 7

Mais on peut aussi appliquer cette fonction à un seul entier, et la valeur produite par cette application donne une fonction qui, comme le montre le type indiqué par l'interprète du langage est une fonction qui à un entier associe un autre entier.

 
Sélectionnez
1.
2.
# let plus2 = plus 2 ;;
val plus2 : int -> int = <fun>

L'application de la fonction plus2 à un entier donne cet entier augmenté de 2.

 
Sélectionnez
1.
2.
# plus2 5 ;;
- : int = 7

Mathématiquement parlant, la fonction plus est donc une fonction dont l'ensemble de départ est l'ensemble des entiers kitxmlcodeinlinelatexdvp\mathbb{Z}finkitxmlcodeinlinelatexdvp et celui d'arrivée est l'ensemble des fonctions de kitxmlcodeinlinelatexdvp\mathbb{Z}finkitxmlcodeinlinelatexdvp dans kitxmlcodeinlinelatexdvp\mathbb{Z}finkitxmlcodeinlinelatexdvp.

kitxmlcodelatexdvp\mathrm{\textbf{plus} :}\ \mathbb{Z} \longrightarrow (\mathbb{Z} \rightarrow \mathbb{Z})finkitxmlcodelatexdvp

Une autre façon de considérer la fonction qui à deux entiers associe la somme de ces deux entiers consiste à la définir comme une fonction dont l'ensemble de départ est l'ensemble des couples d'entiers kitxmlcodeinlinelatexdvp\mathbb{Z} \times \mathbb{Z}finkitxmlcodeinlinelatexdvp et celui d'arrivée est kitxmlcodeinlinelatexdvp\mathbb{Z}finkitxmlcodeinlinelatexdvp.

kitxmlcodelatexdvp\mathrm{\textbf{add} :}\ \mathbb{Z} \times \mathbb{Z} \longrightarrow \mathbb{Z}finkitxmlcodelatexdvp

Les deux fonctions plus et add sont d'une certaine manière deux facettes de la même fonction : on dit que la première en est la version curryfiée et la seconde la version décurryfiée.

En Caml, on peut écrire très simplement la forme décurryfiée.

 
Sélectionnez
1.
2.
# let add (a,b) = a + b ;;
val add : int * int -> int = <fun>

L'application de cette fonction à deux entiers donne le résultat attendu.

 
Sélectionnez
1.
2.
# add (2,5) ;;
- : int = 7

Mais l'application à un seul entier n'est plus possible

 
Sélectionnez
1.
2.
# add (2) ;;
This expression has type int but is here used with type int * int

puisque l'interprète du langage attend qu'un couple d'entiers soit fourni à la fonction add.

En programmation, il est fréquent d'avoir à définir des fonctions ou procédures à deux (ou plus) paramètres. Dans la plupart des langages de programmation (C, Ada, Pascal…), lorsqu'une telle fonction a été définie, il n'est pas possible de l'appliquer avec un nombre d'arguments inférieur au nombre de paramètres précisé dans sa définition. Nous avons donc choisi, pour ce cours d'InitProg, de programmer toutes les fonctions ou procédures à plusieurs paramètres que nous rencontrerons sous leur forme décurryfiée(2). Cela a le double avantage :

  • d'être syntaxiquement proche de ce qui se fait dans d'autres langages de programmation ;
  • de ne pas permettre l'application partielle d'une fonction qui fournirait des valeurs fonctionnelles qui pourrait désorienter le programmeur débutant.

Organisation du polycopié

Ce cours est découpé de manière assez classique en introduction (que vous lisez actuellement), chapitres, annexes, et diverses tables (des figures, des matières…).

Les chapitres recouvrent les objectifs du programme. Ils sont tous suivis de quelques exercices.

Une annexe importante est celle présentant les fonctions du module Cartes. Ce module définit un environnement de travail qui permet de déplacer des cartes situées sur quatre tas d'un tas vers un autre. Cet environnement est utilisé durant les premières semaines du cours pour introduire progressivement les différentes structures de contrôle en programmation impérative, ainsi que les notions de fonctions et procédures. Le report en annexe de la présentation de ce module est délibéré afin de distinguer les objectifs du cours (présentés dans les divers chapitres) des moyens pour les atteindre.

Ce cours ne contient pas les sujets de TP qui seront proposés au fur et à mesure par l'intermédiaire du semainier du portail des UE d'informatique (http://www.fil.univ-lille1.fr/portail/ls1/initprog/) ou du site du cours sur Moodle (http://moodle.univ-lille1.fr/). Bien entendu, les TP font partie intégrante du cours et sont indispensables à une bonne compréhension.

Conventions utilisées dans le polycopié

Les algorithmes de résolution de problème sont décrits en « pseudocode » sous la forme

Algorithme 0.1 Calcul de n!

Entrée : un entier n ≥ 0
Sortie : n!
  f ← 1
  pour i allant de 1 à n faire
      ff × i
  fin pour
  renvoyer f

La traduction d'un algorithme en Caml, ainsi que les programmes sont présentés sous la forme

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
let fact (n) =
  let f = ref 1
  in
    for i = 1 to n do
      f := !f * i
    done;
    !f

Enfin, les dialogues avec l'interprète du langage sont décrits sous la forme

 
Sélectionnez
1.
2.
3.
4.
# let a = 5 ;;
val a : int = 5
# fact (5) ;;
- : int = 120

Lorsqu'une nouvelle structure syntaxique du langage est présentée pour la première fois, elle l'est sous la forme

Syntaxe : Déclaration d'une variable
Sélectionnez
let < identificateur > = < expression >

Équipe pédagogique 2013-2014

Pierre Allegraud, Fabrice Aubert, Alexandre Bilger, Julien Bosman, François Dervaux, Alexandre Feugas, Michel Fryziel, Sophie Jacquin, Laetitia Jourdan, Céline Kuttler, Jean-Luc Levaire,

Didier Mailliet, Nour-Eddine Oussous, Yosra Rekik, Romain Rouvoy, Mikaël Salson, Alexandre

Sedoglavic, Bayrem Tounsi, Cristian Versari, Christophe Vroland, Éric Wegrzynowski, Léopold

Weinberg, Hassina Zeghlache.


précédentsommairesuivant
En réalité, il existe deux modes compilés : une compilation en code-octet qui doit ensuite être interprétée par une machine virtuelle : et une compilation en code natif pour une architecture donnée.
Les étudiants qui poursuivront leurs études en informatique découvriront dans un cours de 3e année consacré à la programmation fonctionnelle les avantages des fonctions curryfiées.

Licence Creative Commons
Le contenu de cet article est rédigé par Université Lille1 et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Pas de Modification 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2019 Developpez.com.