et aux organisations apprendre à programmer avec c et python · apprendre à programmer avec c et...

20
Violeta Felea Victor Felea Jean-Pierre Steen Apprendre à programmer avec C et Python DUT ET LICENCE 1 INFORMATIQUE BTS SERVICES INFORMATIQUES AUX ORGANISATIONS Cours complet Algorithmes, codages, tests Problèmes intégralement résolus Exercices d’approfondissement

Upload: others

Post on 18-Aug-2020

17 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

Violeta FeleaVictor Felea

Jean-Pierre Steen

Violeta Felea, Victor Felea et Jean-Pierre Steen

Apprendre à programmer avec C et Python

Apprendre à programmer avec C et Python

dut et licence 1informatiquebts services informatiques aux organisationsd

ut e

t lic

ence

1 in

form

ati

qu

ebt

s ser

vic

es in

form

ati

qu

es

au

x o

rga

nis

ati

on

s

Appr

endr

e à

prog

ram

mer

ave

c C

et P

ytho

nCo

urs e

t exe

rcic

es c

orrig

és

Destiné aux étudiants des premiers cycles de l’enseignement supérieur qui débutent dans le développement des applications informatiques, cet ouvrage aborde la pratique de deux langages de programmation, C et Python. Il comprend une synthèse de leur présentation, de nombreux problèmes résolus et des exercices d’approfondissement.

La résolution des problèmes est traitée suivant le cycle de développement analyse – conception – codage. L’analyse du problème conduit à la conception d’un algorithme répondant aux exigences exprimées. Chaque solution algorithmique est proposée, dans chacun des deux langages.

Violeta Felea est maître de conférences en informatique à l’université de Franche-Comté. Ses travaux concernent les algorithmes et les systèmes parallèles et distribués.Victor Felea est professeur honoraire en informatique à l’université AI. I. Cuza de Iasi, en Roumanie, où il enseigne les algorithmes et les systèmes d’exploitation de bases de données. Il est auteur de plusieurs manuels d’informatique dans le domaine des bases de données. Jean-Pierre Steen est professeur honoraire en informatique à l’université de Lille 1 et mathématicien formé au calcul numérique.

ISBN 978-2-311-40199-8

9 782311 401998

www.VUIBERT.fr

Sommaire1. C et Python - fondements 2. Approche de programmation modulaire3. Problèmes corrigés4. Modélisation : exemples de jeux programmés

5. Exercices d’approfondissementIndex Bibliographie

• Cours complet• Algorithmes, codages, tests • Problèmes intégralement résolus

Python.indd 1 04/08/15 16:19

• Exercices d’approfondissement

Page 2: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles
Page 3: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page i — #1 ii

ii

ii

Table des matières

Retrouvez des compléments numériques en accès libresur le site www.Vuibert.fr à la page du livre.

Préface iii

1 C et Python – fondements 11.1 Cycle de développement informatique . . . . . . . . . . . . . . . . . . 11.2 Variables, types, expressions . . . . . . . . . . . . . . . . . . . . . . . . 41.3 Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261.4 Structure du programme principal . . . . . . . . . . . . . . . . . . . . 43

2 Approche de programmation modulaire 452.1 Fonctions : paramètres et appels . . . . . . . . . . . . . . . . . . . . . 452.2 Modularité en langage algorithmique . . . . . . . . . . . . . . . . . . . 462.3 Modularité en langage C . . . . . . . . . . . . . . . . . . . . . . . . . . 482.4 Modularité en langage Python . . . . . . . . . . . . . . . . . . . . . . 542.5 Optimisation des performances de la récursivité . . . . . . . . . . . . . 612.6 Fonctions de bibliothèque . . . . . . . . . . . . . . . . . . . . . . . . . 672.7 Compilation et exécution des programmes . . . . . . . . . . . . . . . . 73

3 Problèmes corrigés 773.1 Constantes, variables, expressions . . . . . . . . . . . . . . . . . . . . . 773.2 Primitives – Instruction simple – Bloc d’instructions . . . . . . . . . . 843.3 Instructions conditionnelles . . . . . . . . . . . . . . . . . . . . . . . . 933.4 Instructions répétitives . . . . . . . . . . . . . . . . . . . . . . . . . . . 1123.5 Modularité . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1523.6 Types composites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2013.7 Techniques algorithmiques . . . . . . . . . . . . . . . . . . . . . . . . . 253

4 Modélisation : exemples de jeux programmés 309

5 Exercices proposés 3435.1 Constantes, variables, expressions . . . . . . . . . . . . . . . . . . . . . 3435.2 Primitives – Instruction simple – Bloc d’instructions . . . . . . . . . . 3445.3 Instructions conditionnelles . . . . . . . . . . . . . . . . . . . . . . . . 3465.4 Instructions répétitives . . . . . . . . . . . . . . . . . . . . . . . . . . . 3485.5 Modularité . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

Page 4: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page ii — #2 ii

ii

ii

ii Table des matières

5.6 Types composites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3555.7 Techniques algorithmiques . . . . . . . . . . . . . . . . . . . . . . . . . 3705.8 Modélisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378

Index 397Index des termes génériques . . . . . . . . . . . . . . . . . . . . . . . . . . . 397Index des notions algorithmiques . . . . . . . . . . . . . . . . . . . . . . . . 399Index des notions en langage C . . . . . . . . . . . . . . . . . . . . . . . . . 400Index des notions en langage Python . . . . . . . . . . . . . . . . . . . . . . 401

Bibliographie 403

Page 5: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 45 — #51 ii

ii

ii

CHAPITRE 2

Approche de programmation modulaire

La conception modulaire est une technique de conception de logiciel qui s’appuie surla composition du logiciel en parties séparées. Dans la phase d’analyse du problème,une analyse du découpage du problème en sous-problèmes s’impose. Cette analysedevrait déceler la fonctionnalité d’un algorithme, ses données d’entrée, ses données ensortie ou les données, en entrée, à modifier.

La section suivante présente les principes génériques de la modularité. Les troisautres sections abordent la mise en place de ces principes dans le langage algorithmique,ainsi que dans les langages C et Python.

2.1 Fonctions : paramètres et appels

La modularité fait partie des bonnes pratiques de la conception logicielle. Il s’agitde définir des parties de code, appelées génériquement fonctions, répondant à unefonctionnalité précise, pouvant à la fois apporter de la généricité 1 et de la réutilisation.Une conception modulaire facilite la lisibilité du code et sa maintenance.

Les fonctions doivent pouvoir être reliées les unes aux autres. Par conséquent,deux notions les caractérisent : le paramétrage (les fonctions peuvent prendre desparamètres, afin d’échanger des données entre elles) et l’appel (ces fonctions doiventpouvoir être appelées et peuvent en appeler d’autres). Afin que l’appel puisse êtreréalisé, une fonction doit être déclarée.

La définition d’une fonction précise, d’un point de vue syntaxique :– son entête (appelée aussi dans les langages de programmation signature ou proto-type), nécessaire pour la fonction qui l’appelle. Ceci constitue ainsi l’interfaçageentre la fonction appelante et la fonction appelée. L’entête précise : le nom de lafonction et les paramètres, notés par des identificateurs de paramètres séparéspar des virgules ;

– son corps, qui comprend la partie de déclaration de variables locales et lesinstructions liées au traitement.

1 La généricité (ou la programmation générique) consiste à définir des algorithmes/programmes iden-tiques opérant sur des données différentes.

Page 6: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 46 — #52 ii

ii

ii

46 Chapitre 2. Approche de programmation modulaire

L’appel d’une fonction doit être conforme à sa définition. Dans la définition d’unefonction, les paramètres sont formels (car ils ne désignent pas encore des donnéesconcrètes), mais lors de l’appel, les paramètres sont effectifs. Ces derniers sont aussiappelés arguments. La conformité lors de l’appel se traduit en trois règles, appeléesrègles de mise en correspondance, à respecter :

– le nombre de paramètres effectifs est égal au nombre de paramètres formels,– l’association d’un paramètre effectif à un paramètre formel dépend de la positiondans l’ensemble de paramètres (le premier paramètre effectif correspond aupremier paramètre formel, etc.),

– chaque paramètre effectif a un type compatible avec le type du paramètre formelcorrespondant.

Il faut noter que même si deux paramètres, actuel et formel, sont désignés parle même identificateur, ils désignent des entités différentes (présentes à des adressesdifférentes en mémoire).

Du point de vue du flux de contrôle, l’appel d’une fonction interrompt le fluxd’exécution de la fonction courante, pour que les instructions de la fonction appeléesoient exécutées. À la fin de cette exécution, le contrôle est rendu à la fonctionappelante, qui continue à exécuter ses instructions par la première qui suit l’appel dela fonction.

2.2 Modularité en langage algorithmique

Dans le langage algorithmique, les fonctions génériques sont matérialisés par desalgorithmes, ayant deux formes : des actions ou des fonctions. Le terme sous-algorithmeest parfois utilisé pour les distinguer de l’algorithme principal.

Définition Un algorithme est spécifié grâce à son entête. L’entête d’un algorithmeprécise le type de l’algorithme, action ou fonction, son nom et les paramètres.

La définition d’un algorithme prend les formes suivantes, selon qu’il soit :– une action

action identAct (liste-ident-paramètres )spéc-paramliste-déclarations-localesbloc-instr

finaction– une fonction

fonction identFct (liste-ident-paramètres ) : typespéc-paramliste-déclarations-localesbloc-instrretourner : expr

finfonctionoù

– identAct ou identFct sont des identificateurs désignant le nom de l’action,respectivement de la fonction ;

Page 7: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 47 — #53 ii

ii

ii

2.2 Modularité en langage algorithmique 47

– liste-ident-paramètres (optionnelle) est une succession d’identificateurs,séparés par des virgules, correspondant aux paramètres (cette liste peut êtrevide) ;

– spéc-param (optionnelle si aucun paramètre n’est présent) donne la spécificationde certains paramètres (voir ci-après) ;

– liste-déclarations-locales (optionnelle) est une succession de déclarationsde variables locales (cette succession peut être vide) ;

– bloc-instr (optionnel) est l’ensemble d’instructions du corps de l’algorithme ;– pour les fonctions, le mot clé retourner, suivi d’un deux-points et d’une expres-sion, précise la valeur – une seule possible – retournée par la fonction. Dans cecas, l’expression retournée doit être évaluée à un type compatible avec le typeprécisé dans l’entête de la fonction, par type.

La spécification d’un paramètre inclut la définition de sa catégorie (Données,Données/Résultats ou Résultats) et la déclaration de son type. Les trois catégoriessont identifiées en fonction de la relation entre l’algorithme appelant et l’algorithmeappelé :

– Données – l’algorithme appelé utilise le paramètre seulement en lecture,– Résultats – l’algorithme appelé utilise le paramètre seulement en écriture,– Données/Résultats – l’algorithme appelé utilise le paramètre en lecture etécriture.

Les paramètres ne peuvent appartenir qu’à une seule catégorie.

En fonction de la forme de l’algorithme, les paramètres peuvent être d’une certainecatégorie.

– Pour les actions, les paramètres peuvent appartenir à toutes des catégories citéesprécédemment.

Exemple. L’action affichant le nombre de jours d’un mois est définie ainsi :action afficherNbJours(mois, nbJours)

Données mois : entier { le numéro du mois }nbJours : entier { le nombre de jours du mois }

écrire "Nombre de jours du mois " © mois © " est " © nbJoursfinaction

Dans cet exemple, les deux paramètres appartiennent à la catégorie Données,c’est-à-dire que quand l’algorithme est appelé, il utilise les valeurs des paramètresen lecture, mais l’algorithme qui l’appelle n’attend pas une modification deces valeurs. Cependant, l’appartenance à la catégorie Données d’un paramètren’interdit pas sa modification dans le corps de l’algorithme quand il est appelé.Cette modification ne sera pas, par contre, répercutée sur le paramètre effectif.

– Pour les fonctions, les paramètres ne peuvent appartenir que seulement à lacatégorie Données.

Page 8: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 48 — #54 ii

ii

ii

48 Chapitre 2. Approche de programmation modulaire

Exemple. La fonction calculant le nombre de jours d’un mois est définie ainsi :fonction nbJoursMois(mois) : entier

Données mois : entier { le numéro du mois }Locales nbJ : entier { le nombre de jours du mois donné }{ instructions permettant de faire le calcul }retourner : nbJ

finfonction

Les variables locales définies dans les algorithmes ne peuvent pas être paramètressimultanément. Par conséquent, l’ensemble de variables locales et l’ensemble de para-mètres sont disjoints.

Appel L’appel d’une action est considéré comme une instruction. L’appel d’unefonction est une expression ; par conséquent, il doit apparaître dans le membre droitd’une affectation, ou dans une expression, ou il peut être imbriqué dans l’appel àune autre fonction ou action, ou être inclus dans une primitive d’écriture. Dans cesdeux derniers cas, il s’agit d’un appel imbriqué. Seul l’appel d’une fonction peut êtreimbriqué.

Etant donné les catégories de paramètres,– un paramètre Données doit être une expression : l’expression est évaluée et le

paramètre effectif prend comme valeur le résultat de l’évaluation, transférée auparamètre formel,

– un paramètre Résultats doit être une variable : l’algorithme appelé affecteraune valeur au paramètre formel, qui sera transférée au paramètre effectif,

– un paramètre Données/Résultats doit être une variable valuée (variable conte-nant une valeur) : la valeur du paramètre effectif est transférée au paramètreformel, qui sera modifiée par l’algorithme et la nouvelle valeur sera transférée auparamètre effectif.

Afin d’identifier les algorithmes nécessaires pour la résolution d’un problème, defaçon modulaire, une analyse du découpage du problème en sous-problèmes s’impose.Cette analyse devrait déceler la fonctionnalité d’un algorithme, ses données d’entrée(les paramètres Données), ses données en sortie (les paramètres Résultats) ou lesdonnées, en entrée, à modifier (les paramètres Données/Résultats). L’algorithmeprincipal aura le rôle d’appeler des algorithmes définis, afin de construire la structurede la solution à base des briques élémentaires données par les sous-algorithmes.

2.3 Modularité en langage C

Définition La modularité en C s’exprime par l’intermédiaire des fonctions, dont ladéfinition est la suivante :type identFct (liste-déclarations-paramètres ) {

liste-déclarations-localesbloc-instr

}où

Page 9: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 49 — #55 ii

ii

ii

2.3 Modularité en langage C 49

– type est le type de l’expression rendue par la fonction, ou void si la fonctionne rend pas de valeur ;

– identFct est le nom de la fonction ;– liste-déclarations-paramètres (optionnelle) est une liste de déclarations deparamètres formels, séparées par des virgules ; chaque déclaration contient letype du paramètre suivi par son identificateur ;

– liste-déclarations-locales (optionnelle) est une liste de déclarations devariables locales utilisées dans les instructions de la fonction ;

– bloc-instr (optionnel) définit l’ensemble des instructions à exécuter par lafonction. Si la fonction rend une valeur, l’instruction return expr; doit appa-raître parmi les instructions du bloc. Lors de l’exécution d’une telle instruction,l’expression expr est évaluée et le contrôle d’exécution est rendu à l’appelant dela fonction. Aucune autre instruction suivant l’instruction return n’est exécutée.La valeur rendue par la fonction est celle de l’expression.

Exemples. Un premier exemple de fonction est celui de la fonction principale dansun programme écrit en C (voir la page 43). Les paramètres formels définis servent àobtenir les valeurs des arguments de la ligne de commande.La fonction C affichant le nombre de jours d’un mois est définie ainsi :void afficherNbJours(int mois, int nbJours) {// mois : le numéro du mois// nbJours : le nombre de jours du mois

printf("Nombre de jours du mois %d est %d\n", mois, nbJours);}

La fonction C calculant le nombre de jours d’un mois est définie ainsi :int nbJoursMois(int mois) {// paramètre mois : le numéro du mois (entre 1 et 12)

int nbJ; // le nombre de jours du mois donné// instructions permettant de faire le calculreturn nbJ;

}

Si la dernière instruction exécutée par une fonction n’est pas une instructionreturn, la valeur rendue par la fonction est indéterminée. L’instruction return peutapparaître à plusieurs endroits, dans le corps d’une fonction qui rend une valeur,comme par exemple, si une instruction conditionnelle est utilisée.

La déclaration imbriquée de fonctions n’est pas autorisée dans le standard dulangage, mais certains compilateurs intègrent cette syntaxe 2.

Appel L’appel d’une fonction C est :– soit une expression, si la fonction rend une valeur :identVar = identFct(liste-expressions );

2 Le compilateur gcc est un exemple de compilateur acceptant les déclarations imbriquées de fonctions.

Page 10: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 50 — #56 ii

ii

ii

50 Chapitre 2. Approche de programmation modulaire

La sémantique est la suivante : les expressions de la liste d’expressions liste-expressions sont évaluées, puis passées en tant que paramètres effectifs à lafonction de nom identFct, qui est ensuite exécutée. La valeur rendue par lafonction est la valeur affectée à la variable identVar.

– soit une instruction, si la fonction ne rend aucune valeur :identAct(liste-expressions );

De même qu’en langage algorithmique, les appels peuvent être imbriqués : unefonction qui renvoie une valeur peut être imbriquée dans toute autre fonction, c’est-à-dire que des appels (imbriqués) de fonctions peuvent correspondre aux paramètreseffectifs de la fonction appelée. Une fonction qui ne renvoie rien ne peut pas êtreimbriquée.

Passage de paramètres En C, les paramètres sont passés par valeur, c’est-à-direque les paramètres formels sont considérés comme des variables locales à la fonction etsont initialisées automatiquement par les valeurs des paramètres effectifs. La fonction,le sous-programme travaille avec une copie. C’est le cas des paramètres de typescalaire (numérique, alphanumérique). Par conséquent, toute modification qui pourraits’effectuer dans la fonction n’a aucune incidence sur le contenu du paramètre effectif.

Quand un paramètre formel est de type pointeur, le passage de paramètre estappelé, en C, passage par référence : c’est la valeur du pointeur (une adresse dans lamémoire) qui est attribuée au paramètre formel. Ainsi, la fonction a la possibilité demodifier le contenu du paramètre effectif (celui qui est à l’adresse indiquée), donc savaleur, par une affectation effectuée sur le déréférencement du pointeur.

Exemple erroné.void lireEntiers(int a, int b) {// lire deux valeurs entières et les retourner

scanf("%d", &a);scanf("%d", &b);

}// appel dans une fonction (main ou autre)int x = 10, y = 15;lireEntiers(x, y);// x vaut 10 et y vaut 15 même si dans la fonction lireEntiers,// les paramètres ont été modifiés par une saisie au clavier

Le code précédent, correctement d’un point de vue syntaxique, définit une fonction quiprend en paramètres deux scalaires entiers, dont le passage est effectué par valeur. Lesparamètres effectifs x et y ont des valeurs définies à la déclaration, grâce à l’affectation.Les paramètres formels a et b reçoivent ces valeurs lors de l’appel de la fonctionlireEntiers. Les valeurs saisies au clavier sont effectivement mémorisées, mais auxadresses des variables a et b, paramètres formels, qui sont différentes des adresses desvariables x et y, paramètres effectifs. Cela explique le fait que le contenu des variablesx et y n’est pas modifié après le retour de l’appel de la fonction lireEntiers.

Page 11: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 51 — #57 ii

ii

ii

2.3 Modularité en langage C 51

Exemple correct.Définition de la fonction (utilisant les pointeurs – voir la page 13) :void lireEntiers(int* pa, int* pb) {// lire deux valeurs entières et les retourner// pa et pb sont des adresses

scanf("%d", pa);scanf("%d", pb);

}

Utilisation de la fonction (l’appel) :// appel dans une fonction (main ou autre)int x, y;lireEntiers(&x, &y);

Dans le code de l’exemple précédent, il s’agit d’un passage par référence, pour lesdeux paramètres. Cela traduit le fait que la valeur du paramètre, donc l’adresse dela variable, est affectée au paramètre formel. Il est à noter que la même sémantiqueque précédemment est utilisée : les paramètres formels et les paramètres effectifscorrespondent à des variables différentes (ici, elles contiennent les adresses mémoire dex et y). Les instructions de saisie au clavier utilisent directement la valeur du paramètreformel, qui, justement, représente l’adresse en mémoire où doit être mémorisée la valeursaisie. Et, comme cette adresse correspond aussi à l’adresse du paramètre effectif, cecipermet d’obtenir, après le retour de l’appel de fonction, les valeurs saisies dans lesvariables x et y.

Par conséquent, l’utilisation d’un paramètre de la catégorie Données dans le langagealgorithmique devrait se traduire par un passage par valeur en C, tandis que l’utilisationd’un paramètre des catégories Données/Résultats ou Résultats devrait se traduirepar un passage par référence en C.

Définition et appel Lorsqu’une fonction est appelée, sa définition doit être connuepar l’appelant. Si cette définition est présente dans le même fichier que la fonctionappelante, généralement elle précède l’endroit où l’appel est réalisé.

L’exception est faite pour les fonctions récursives 3 qui n’exigent pas que cet ordresoit respecté car il n’est pas réalisable. Aussi, comme pour les fonctions réciproquementrécursives (c’est-à-dire la fonction fct1 appelle la fonction fct2 et inversement), laprécédence dans le fichier ne peut pas être appliquée, on place un prototype de lafonction appelée avant l’endroit où l’appel est réalisé. Sa définition peut le succéder.

Exemple.// prototype fonction fct1/* définition fonction fct2 - avec appel de fct1 *//* définition fonction fct1 */

3 Une fonction récursive est une fonction qui s’appelle elle-même, directement ou par l’intermédiaired’autres fonctions.

Page 12: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 52 — #58 ii

ii

ii

52 Chapitre 2. Approche de programmation modulaire

Référence à une fonction externe Dans certains cas, des fonctions définiesen dehors du fichier courant peuvent être appelées. C’est le cas des fonctions debibliothèque standard, comme celles nécessaires pour les opérations d’affichage oude saisie. Il y a une méthode permettant de faire cela de manière automatique grâceau mécanisme d’inclusion de fichiers d’entête, utilisant la directive de compilationinclude qui doit apparaître en début du fichier contenant le code source. Grâce à cemot clé et aux indications que l’accompagnent, est précisé le fichier (avec l’extension.h) contenant les entêtes de toutes les fonctions pouvant être appelées par le codecourant.

Exemple. #include <stdio.h>permet l’utilisation des fonctions de la bibliothèque standard d’entrée/sortie.

Le fichier d’entête à inclure, permettant l’accès à la fonction de bibliothèque, estprécisé dans la documentation de chaque fonction.

Pointeur de fonction Un pointeur peut contenir une adresse d’une fonction. Ellereprésente l’adresse de la première instruction exécutable du code machine de cettefonction. La conséquence directe est la possibilité de passer en paramètres des fonctions,par la notion de pointeur de fonction.

Déclaration : Un pointeur vers une fonction se déclare de la manière suivante :typeRet (*identPtrFct)(liste-types );déclare un pointeur ayant le nom identPtrFct vers une fonction, ayant des paramètresde types donnés par liste-types et qui renvoie un résultat de type typeRet .

Manipulation : Un pointeur de fonction est initialisé par l’adresse de la fonctiongrâce à l’opérateur de référencement : identPtrFct = &nomFct ;où nomFct est le nom de la fonction référencée.

Exemple. Soit cmpInf une fonction de comparaison d’infériorité entre deux entiers :bool cmpInf(int a, int b) { return a <= b; }

Cette fonction peut être appelée, par l’intermédiaire d’un pointeur vers elle, de lamanière suivante :bool (*ptrCmp)(int, int); // déclaration de pointeurptrCmp = &cmpInf; // initialisation de pointeur de fonctionprintf(ptrCmp(a,b)); // appel de la fonction par l’intermédiaire

// du pointeur de fonction

L’exemple précédent n’apporte pas une fonctionnalité supplémentaire, car l’appeld’une fonction peut être réalisé directement, grâce au nom de la fonction. Cependant,il sert d’étape intermédiaire pour comprendre comment les fonctions peuvent êtrepassées en paramètre pour d’autres fonctions.

Page 13: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 53 — #59 ii

ii

ii

2.3 Modularité en langage C 53

Exemple. Prenons, à titre d’exemple, une fonction qui permet d’ordonner deuxentiers, soit en ordre croissant, soit en ordre décroissant, l’ordre étant induit par unparamètre qui est une fonction.bool cmpSup(int a, int b) { return a >= b; } // nouvelle fonction,

// en complément de la précédentevoid ordo(int* pa, int* pb, bool(*pFctCmp)(int,int)) {// ordonner le contenu aux adresses pa et pb// selon les indications d’une fonction dont l’adresse est pFctCmp

if (!pFctCmp(*pa,*pb)) { // permuterint tmp;tmp = *pa, *pa = *pb; *pb = tmp;

}}

// appel pour deux entiers x, yordo(&x, &y, &cmpInf); // après l’appel : x <= yordo(&x, &y, &cmpSup); // après l’appel : x >= y

Si une fonction peut être passée en paramètre, elle peut également apparaître en retourd’une fonction ou encore en paramètre passé par référence. Il est à noter que cet usageest moins répandu.

Exemple. Considérant une fonction carre qui renvoie le carré d’un entier et unefonction doubler qui renvoie le double de l’entier en paramètre, il s’agit de définirune fonction qui renvoie soit la fonction carre, si l’entier est strictement négatif, soitla fonction doubler au cas contraire.int carre(int x) { int doubler(int x) { int (* fctGen(int a))(int) {

return x*x; return 2*x; // retour d’un pointeur sur fct} } if (a < 0) return carre;

return doubler;}

// appels de fctGenint (*ptrFct)(int);ptrFct = fctGen(-2); // ptrFct est la fonction carreint res1 = ptrFct(-3); // appel de carre(-3) -> 9, même résultat que fctGen(-2)(-3)int res2 = ptrFct(4); // appel de carre(4) -> 16, même résultat que fctGen(-2)(4)ptrFct = fctGen(3); // ptrFct est la fonction doublerres1 = ptrFct(-1); // appel de doubler(-1) -> -2, même résultat que fctGen(3)(-1)res2 = ptrFct(5); // appel de doubler(5) -> 10, même résultat que fctGen(3)(5)

La fonction fctGen précise un paramètre entier, selon lequel le choix de la fonction àretourner est réalisé. À son tour, la fonction retournée prend un entier en paramètrepour réaliser le calcul.

La définition de la fonction retournée peut utiliser la redéfinition de type pour unpointeur de fonction. La définition suivante :typedef typeRet (* TypePtrFct) (liste-types )définit un type TypePtrFct comme pointeur sur toute fonction ayant les paramètresde types donnés par liste-types et qui renvoie une valeur de type typeRet .

Page 14: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles
Page 15: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 77 — #83 ii

ii

ii

CHAPITRE 3

Problèmes corrigés

3.1 Constantes, variables, expressionsEx. 1 — Opérateurs et expressions arithmétiquesÉcrire les expressions mathématiques suivantes en langages algorithmique, C et Py-thon :

1. a2 − c+ a

bc+ c

d+ e

f

2.1a

+ 1b

c+ d

Solution (Ex. 1) —Dans les trois langages, les expressions mathématiques se traduisent de la mêmemanière :

1. a ∗ a - c + a / (b ∗ c + c /(d + e / f))2. (1 / a + 1 / b) / (c + d)

Ex. 2 — ExpressionsEn fonction des déclarations des variables suivantes, en langage algorithmique :i, j, k : entierx, y, z : réelc : caractèreb : booléen

donner l’expression équivalente, en C et en Python, pour chacune des expressionsalgorithmiques ci-dessous :

c-i i=j x+2.0 x+ix/2.0 i/2 i/2.0 i div 2 x<yi mod j+y i/j+y i et b i>j et k>j x+y*i

Solution (Ex. 2) —

Page 16: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 78 — #84 ii

ii

ii

78 Chapitre 3. Problèmes corrigés

expression type explicationalgorithmique C Pythonc-i c-i entier conversion implicite

Rem1 Rem2 (algorithmique et C) entre letype entier et le type caractère

i=j i==j i==j booléen opérateur de comparaisond’égalité

x+2.0 x+2.0 x+2.0 réel un des opérandes est réelx+i x+i x+i réel un des opérandes est réelx/2.0 x/2.0 x/2.0 réel division réellei/2 i/2.0 i/2 réel division réellei/2.0 i/2.0 i/2.0 réel division réellei div 2 i/2 i//2 entier division entièrex<y x<y x<y booléen opérateur de comparaisoni mod j+y i%j+y i%j+y réel mod prioritairei/j+y i/(j*1.0)+y i/(j*1.0)+y réel la division est prioritaire

(l’expression évaluée est un réel)i et b - - - évaluation impossible

(l’opérande i n’est pas booléen)i>j et k>j i>j && k>j i>j and k>j booléen expression booléenne

dont les opérandes sont desexpressions de comparaison

x+y*i x+y*i x+y*i réel la multiplication est prioritaire

Remarques. Dans le tableau précédent, une remarque s’impose pour l’expressionc-i.Rem1. En C, le type de l’expression c-i dépend du type de la variable à laquellel’expression est affectée. Ainsi, l’expression pourrait être évaluée à un type char ouun type int (correspondant au code ASCII du caractère).Rem2. En Python, l’expression c-i ne se traduit pas de la même manière carl’opérateur de soustraction ne peut pas être appliqué sur une chaîne de caractères et unentier. Deux expressions équivalentes peuvent être écrites : chr(ord(c)-i) pour obtenirle caractère et ord(c)-i pour obtenir le code ASCII du caractère correspondant.

Ex. 3 — Théorèmes de MorganFormulés par le mathématicien britannique, Augustus de Morgan, ces théorèmesénoncent des équivalences entre des expressions booléennes et permettent de lessimplifier.

Question 1. Compléter les tableaux suivants :

a b non a non b a ou b non(a ou b) non a et non bfaux fauxfaux vraivrai fauxvrai vrai

Page 17: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 79 — #85 ii

ii

ii

3.1 Constantes, variables, expressions 79

a b non a non b a et b non(a et b) non a ou non bfaux fauxfaux vraivrai fauxvrai vrai

Question 2. Déduire les relations entre :– l’expression non(a ou b) et l’expression non a et non b,– l’expression non(a et b) et l’expression non a ou non b.

Solution (Ex. 3) —

a b non a non b a ou b non(a ou b) non a et non bfaux faux vrai vrai faux vrai vraifaux vrai vrai faux vrai faux fauxvrai faux faux vrai vrai faux fauxvrai vrai faux faux vrai faux faux

⇑ ⇑

En conséquence, on déduit que les expressions non(a ou b) et non a et non b sontéquivalentes.

a b non a non b a et b non(a et b) non a ou non bfaux faux vrai vrai faux vrai vraifaux vrai vrai faux faux vrai vraivrai faux faux vrai faux vrai vraivrai vrai faux faux vrai faux faux

⇑ ⇑

En conséquence, on déduit que les expressions non(a et b) et non a ou non b sontéquivalentes.

Ex. 4 — Expressions booléennesFormer les expressions booléennes (en langage algorithmique et en langages C etPython) correspondant aux énoncés suivants :

1. u = 1 ou 2 ou 3 ou 4 ;2. u 6= v ;3. u ∈ [5,10] ;4. u ∈ ]-2,0] ∪ [10, +∞) ;5. u ∈ [a,b] ∩ ]c, d] ;6. u ∈ IR\ ]-a, a[ (IR désignant l’ensemble des réels).

Solution (Ex. 4) —Les expressions dans le langage algorithmique sont les suivantes :

1. u=1 ou u=2 ou u=3 ou u=4 ;2. u 6= v soit non(u = v) ;3. u > 5 et u 6 10 ;

Page 18: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 80 — #86 ii

ii

ii

80 Chapitre 3. Problèmes corrigés

4. u > -2 et u 6 0 ou u > 10 ;5. u > a et u 6 b et u > c et u 6 d ;6. non (u > -a et u < a).

Leurs traductions en langage C, respectivement en Python, sont données dans letableau ci-après :

C Pythonu==1 || u==2 || u==3 || u==4 u==1 or u==2 or u==3 or u==4u != v u != v!(u == v) not(u == v)u >= 5 && u <= 10 u >= 5 and u <= 10u > -2 && u <= 0 || u >= 10 u > -2 and u <= 0 or u >= 10u >= a && u <= b && u > c u >= a and u <= b and u > c

&& u <= d and u <= d!(u > -a && u < a) not (u > -a and u < a)

Ex. 5 — Expression booléenne composéeEn considérant que les deux variables booléennes pluie et froid, correspondentrespectivement aux deux situations de la météo : "il pleut" et "il fait froid", établir latable de vérité de l’expression algorithmique suivante :

pluie et non froid

Solution (Ex. 5) —

pluie froid non froid pluie et non froidfaux faux vrai fauxfaux vrai faux fauxvrai faux vrai vraivrai vrai faux faux

Conclusion : il pleut et il ne fait pas froid uniquement si la variable pluie est évaluée àvrai et la variable froid est évaluée à faux , c’est-à-dire quand pluie et non froidsont vrai en même temps.

Ex. 6 — Identité entre valeursConsidérons trois valeurs numériques mémorisées par l’intermédiaire des variablesdifférentes. Exprimer en langage algorithmique, par une expression booléenne, lessituations suivantes :

1. au moins deux valeurs parmi les trois sont identiques,2. deux valeurs et seulement deux valeurs parmi les trois sont identiques,3. au plus deux valeurs parmi les trois sont identiques.

Solution (Ex. 6) —Considérons les identificateurs x, y, z pour les trois variables numériques. Les expres-sions booléennes, correspondant aux situations de l’énoncé, sont les suivantes :

1. x = y ou y = z ou x = z ou (x = y et y = z),2. (x = y et y 6= z) ou (y = z et x 6= y) ou (x = z et y 6= x),

Page 19: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

ii

“ProgrammationExos” — 2015/8/12 — 14:37 — page 81 — #87 ii

ii

ii

3.1 Constantes, variables, expressions 81

3. (x = y et y 6= z) ou (y = z et x 6= y) ou (x = z et y 6= x) ou(x 6= y et y 6= z).

Ex. 7 — Conditions d’accès au muséeLes conditions d’accès demi-tarif à un musée sont les suivantes :

– toute personne, non étudiante, de plus de 60 ans, ne faisant pas partie del’association des amis du musée,

– tout étudiant non membre de l’association,– toute personne de moins de 60 ans et membre de l’association,– toute personne de plus de 60 ans, ne faisant pas partie de l’association, mais auchômage,

– tout étudiant de moins de 60 ans et qui n’est pas au chômage,– toute personne membre de l’association, au chômage,– toute personne de plus de 60 ans, membre de l’association, non au chômage.

Quelle est l’expression booléenne traduisant les conditions pour se voir autorisé undemi-tarif pour l’accès au musée ?Remarque. Exprimons, par les variables booléennes, les situations : une personne estétudiant, une personne a plus de 60 ans, une personne est membre de l’association,une personne au chômage.

Solution (Ex. 7) —Considérons les variables booléennes suivantes :

– e : la personne est un étudiant,– a : la personne a plus de 60 ans,– m : la personne est membre de l’association des amis du musée,– c : la personne est au chômage.

En suivant les règles de l’énoncé, l’expression suivante est évaluée à vrai quand lapersonne a droit à une entrée demi-tarif au musée :(non e et a et non m) ou (e et non m) ou (non a et m) ou (a et non m etc) ou (e et non a et non c) ou (m et c) ou (a et m et non c).Il s’agit de la disjonction de chacune des règles ; chaque règle est une expressionbooléenne exprimée par une conjonction de variables, en fonction de la contrainteexprimée. Par exemple, pour la première règle, qui stipule que toute personne, nonétudiante, de plus de 60 ans, ne faisant pas partie de l’association des amis du muséea droit à un demi-tarif, il s’agit de l’expression non e et a et non m.Remarque. Cette expression peut être simplifiée. La simplification peut être réalisée,de manière générale, soit en utilisant les théorèmes fondamentaux (voir l’exercice2 à la page 343), soit en construisant les diagrammes de Karnaugh [9]. Plusieursexpressions simplifiées différentes peuvent être obtenues, mais elles seront équivalentes.La simplification est importante afin que l’expression booléenne obtenue, utiliséecomme condition dans une structure de contrôle conditionnelle ou itérative, soit laplus compacte possible, réduisant ainsi le nombre d’opérations effectuées.En construisant les diagrammes de Karnaugh pour quatre variables, nous obtenonsl’expression simplifiée :m ou (non m et a) ou (non m et non a et e) ou encoree ou a ou m

Page 20: et aux organisations Apprendre à programmer avec C et Python · Apprendre à programmer avec C et Python Cours et exercices corrigés Destiné aux étudiants des premiers cycles

Violeta FeleaVictor Felea

Jean-Pierre Steen

Violeta Felea, Victor Felea et Jean-Pierre Steen

Apprendre à programmer avec C et Python

Apprendre à programmer avec C et Python

dut et licence 1informatiquebts services informatiques aux organisationsd

ut e

t lic

ence

1 in

form

ati

qu

ebt

s ser

vic

es in

form

ati

qu

es

au

x o

rga

nis

ati

on

s

Appr

endr

e à

prog

ram

mer

ave

c C

et P

ytho

nCo

urs e

t exe

rcic

es c

orrig

és

Destiné aux étudiants des premiers cycles de l’enseignement supérieur qui débutent dans le développement des applications informatiques, cet ouvrage aborde la pratique de deux langages de programmation, C et Python. Il comprend une synthèse de leur présentation, de nombreux problèmes résolus et des exercices d’approfondissement.

La résolution des problèmes est traitée suivant le cycle de développement analyse – conception – codage. L’analyse du problème conduit à la conception d’un algorithme répondant aux exigences exprimées. Chaque solution algorithmique est proposée, dans chacun des deux langages.

Violeta Felea est maître de conférences en informatique à l’université de Franche-Comté. Ses travaux concernent les algorithmes et les systèmes parallèles et distribués.Victor Felea est professeur honoraire en informatique à l’université AI. I. Cuza de Iasi, en Roumanie, où il enseigne les algorithmes et les systèmes d’exploitation de bases de données. Il est auteur de plusieurs manuels d’informatique dans le domaine des bases de données. Jean-Pierre Steen est professeur honoraire en informatique à l’université de Lille 1 et mathématicien formé au calcul numérique.

ISBN 978-2-311-40199-8

9 782311 401998

www.VUIBERT.fr

Sommaire1. C et Python - fondements 2. Approche de programmation modulaire3. Problèmes corrigés4. Modélisation : exemples de jeux programmés

5. Exercices d’approfondissementIndex Bibliographie

• Cours complet• Algorithmes, codages, tests • Problèmes intégralement résolus

Python.indd 1 04/08/15 16:19

• Exercices d’approfondissement