Cours Langage C/C++ Programmation modulaire



Documents pareils
Quelques éléments de compilation en C et makefiles

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Systeme d'exploitation

Télécom Nancy Année

I. Introduction aux fonctions : les fonctions standards

TP1. Outils Java Eléments de correction

Chaîne de production d un programme

Année Universitaire 2009/2010 Session 2 de Printemps

Outils pour la pratique

Compte-rendu de projet de Système de gestion de base de données

Client Kiwi Backup : procédures d'installation et de mise à jour. Gilles Arnoult, Clément Varaldi

Introduction au langage C

TP 1 : 1 Calculs en binaire, octal et hexadécimal

INF2015 Développement de logiciels dans un environnement Agile. Examen intra 20 février :30 à 20:30

RapidMiner. Data Mining. 1 Introduction. 2 Prise en main. Master Maths Finances 2010/ Présentation. 1.2 Ressources

Perl Console. Votre compagnon pour développer en Perl. Les Journées du Perl , 17 novembre, Lyon. Alexis Sukrieh

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Algorithmique et Programmation, IMA

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Mon premier rpm. 7 juin Avant de commencer RPM URPMI RPMBUILD... 2

Chapitre 5 : Les procédures stockées PL/SQL

Programmation système I Les entrées/sorties

Conception de circuits numériques et architecture des ordinateurs

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

TP : Shell Scripts. 1 Remarque générale. 2 Mise en jambe. 3 Avec des si. Systèmes et scripts

DA MOTA Anthony - Comparaison de technologies : PhoneGap VS Cordova

Compression de Données - Algorithme de Huffman Document de Conception

Éléments d'architecture des ordinateurs

Installation et prise en main


Programmation C++ (débutant)/instructions for, while et do...while

UE Programmation Impérative Licence 2ème Année

SweetyPix, mode d'emploi

Raja Bases de données distribuées A Lire - Tutoriel

Date de diffusion : Rédigé par : Version : Mars 2008 APEM 1.4. Sig-Artisanat : Guide de l'utilisateur 2 / 24

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

3IS - Système d'exploitation linux - Programmation système

Archivage Messagerie Evolution pour usage HTML en utilisant Hypermail

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Dossier. Développer en Java sur téléphone mobile. Benjamin Damécourt UFR SITEC Master 2 EESC 11 janvier 2012

Notes de Cours - Programmation Pascal Ferraro

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

Table des matières. 10 Gimp et le Web. Option de traitement d'images Mémento pour la séance N o Création d'animation

TP2 - Conguration réseau et commandes utiles. 1 Généralités. 2 Conguration de la machine. 2.1 Commande hostname

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Atelier B. Atelier B. Manuel Utilisateur. Version 4.0

Environnements et Outils de Développement Cours 1 Introduction

Programmation impérative

Algorithmique & Langage C IUT GEII S1. Notes de cours (première partie) cours_algo_lgc1.17.odp. Licence

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Chapitre 10 : Logiciels

Titre: Version: Dernière modification: Auteur: Statut: Licence:

HP Data Protector Express Software - Tutoriel 3. Réalisation de votre première sauvegarde et restauration de disque

Initiation à html et à la création d'un site web

FinImportExport Documentation Utilisateur Gestion d'environnement dans Fininfo Market

Le langage C. Séance n 4

TP réseaux 4 : Installation et configuration d'un serveur Web Apache

Testez votre installation. Créer un répertoire vide

Gestion d utilisateurs et stratégie systèmes.

ACTIVITÉ DE PROGRAMMATION

Le prototype de la fonction main()

Programme awk------introduction rapide

Algorithmique avec Algobox

Initiation. àl algorithmique et à la programmation. en C

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

TP n 2 : Installation et administration du serveur ProFTP. Partie 1 : Fonctionnement du protocole FTP (pas plus de 15min)

Optimisation de logiciels de modélisation sur centre de calcul

Bernard HAMM, Évelyne LAVOISIER

Programmation système de commandes en C

Programmation système en C/C++

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Chapitre 1 : Introduction aux bases de données

1 Description générale de VISFIELD

Sage CRM. 7.2 Guide de Portail Client

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2

GESTION DE PROCESSUS WEB DESIGN ET CONCEPTION DES SITES WEB DYNAMIQUES A L'AIDE DE CMS. Viktoriia IVNYTSKA

Guide d'installation. Release Management pour Visual Studio 2013

TD/TP 1 Introduction au SDK d Android

Préparer la synchronisation d'annuaires

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

1 TD 2 : Construction d'une chier Acrobat et envoi par

Leica Application Suite

OS Réseaux et Programmation Système - C5

Remise à niveau d un programme JAVA du domaine public

Documentation module hosting

1 / Introduction. 2 / Gestion des comptes cpanel. Guide débuter avec WHM. 2.1Créer un package. 2.2Créer un compte cpanel

Projet Personnalisé Encadré PPE 2

Concepts et définitions

Cours de C/C++ par la pratique. Hugues Talbot

Cours 1 : Qu est-ce que la programmation?

Un serveur web, difficile?

Construction de logiciel et packaging

Annexe : La Programmation Informatique

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

Transcription:

Cours Langage C/C++ Programmation modulaire Thierry Vaira BTS IRIS Avignon tvaira@free.fr «v0.1

Rappel Programmation modulaire (1/2) Le découpage d'un programme en sous-programmes est appelée programmation modulaire. La programmation modulaire se justie par de multiples raisons : un programme écrit d'un seul tenant devient très dicile à comprendre dès lors qu'il dépasse une page de texte la programmation modulaire permet d'éviter des séquences d'instructions répétitives la programmation modulaire permet le partage d'outils communs qu'il sut d'avoir écris et mis au point une seule fois des fonctions convenablement choisies permettent souvent de dissimuler les détails d'un calcul contenu dans certaines parties du programme qu'il n'est pas indispensable de connaître. D'une manière générale, la programmation modulaire clarie l'ensemble d'un programme et facilite les modications ultérieures. tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 2 / 19

Rappel Programmation modulaire (2/2) Pour conclure, il faut distinguer : la déclaration d'une fonction qui est une instruction fournissant au compilateur un certain nombre d'informations concernant une fonction. Il existe une forme recommandée dite prototype : int plus(int, int) ; chier en-tête (.h) sa dénition qui revient à écrire le corps de la fonction (qui dénit donc les traitements eectués dans le bloc {} de la fonction) int plus(int a, int b) { return a + b ; } chier source (.c ou.cpp) l'appel qui est son utilisation. Elle doit correspondre à la déclaration faite au compilateur qui vérie. int res = plus(2, 2) ; chier source (.c ou.cpp) Remarque : La dénition d'une fonction tient lieu de déclaration. Mais elle doit être "connue" avant son utilisation (un appel). Sinon, le compilateur génère un message d'avertissement (warning) qui indiquera qu'il a lui-même fait une déclaration implicite de cette fonction : "attention : implicit declaration of function 'multiplier'" tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 3 / 19

Rappel Passage d'argument à une fonction Voici les diérentes déclarations en fonction du contrôle d'accès désiré sur un paramètre reçu : passage par valeur accès en lecture seule à la variable passée en paramètre : void foo(int a) ; passage par adresse accès en lecture seule à la variable passée en paramètre : void foo(const int *a) ; passage par adresse accès en lecture et en écriture à la variable passée en paramètre : void foo(int *a) ; passage par adresse accès en lecture et en écriture à la variable passée en paramètre (sans modication de son adresse) : void foo(int * const a) ; passage par adresse accès en lecture seule à la variable passée en paramètre (sans modication de son adresse) : void foo(const int * const a) ; passage par référence accès en lecture et en écriture à la variable passée en paramètre : void foo(int &a) ; passage par référence accès en lecture seule à la variable passée en paramètre : void foo(const int &a) ; tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 4 / 19

Fichiers séparés La programmation modulaire entraîne la compilation séparée. Le programmeur exploitera la programmation modulaire en séparant ces fonctions dans des chiers distincts. Généralement, il regroupera des fonctions d'un même "thème" dans un chier séparé. C'est l'étape d'édition de liens (linker ) qui aura pour rôle de regrouper toutes les fonctions utilisées dans un même exécutable. Regroupons les dénitions des fonctions multiplier() et plus() dans un chier calcul.c : int multiplier(int a, int b) { return a * b; } int plus(int a, int b) { return a + b; } tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 5 / 19

Déclaration et dénitions des fonctions Si un programme main.c désire utiliser une (ou plusieurs) des fonctions disponibles dans calcul.c, il doit accéder à leurs déclarations pour pouvoir se compiler. L'utilisation recommandée est de lui fournir un chier contenant (seulement) les déclarations des fonctions. C'est le rôle des chiers en-tête (header ) qui portent l'extension.h. On aura donc un couple de chiers : un.h (pour les déclarations) et un.c (pour les dénitions) portant le même nom. Plaçons les déclarations des 2 fonctions précédentes dans un chier calcul.h : int multiplier(int a, int b); int plus(int a, int b); tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 6 / 19

La directive include Compilation séparée Maintenant, on peut écrire et compiler le programme main.c : #include <stdio.h> /* pour la déclaration de printf */ #include "calcul.h" /* pour la déclaration de multiplier */ int main() { printf("2*2 = %d\n", multiplier(2, 2)); return 0; } Remarque : #include est une directive de pré-compilation réalisée par le préprocesseur AVANT la compilation. Toutes les directives de pré-compilation commencent par un dièse '#'. La directive include a pour rôle d'inclure le chier indiqué. On peut indiquer le chier à inclure entre <> dans ce cas le chier sera cherché dans les répertoires standards connus du compilateur (/usr/include sons GNU/Linux). Pour ses propres chiers, on préfère indiquer son nom entre "". Dans ce cas, le chier sera cherché dans le répertoire courant. On peut indiquer un chemin particulier en utilisant l'option -Ichemin de gcc (cf. man gcc). tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 7 / 19

Fabrication Pour fabriquer un exécutable, il faut réaliser les étapes suivantes : compilation de calcul.c en utilisant l'option -c (compilation) et génèration d'un chier objet (calcul.o) compilation de main.c en utilisant l'option -c (compilation) et génèration d'un chier objet (main.o) édition de liens des chiers objets (.o) en utilisant l'option -o (output) pour fabriquer un exécutable Les étapes successives avec gcc : $ gcc -c calcul.c $ gcc -c main.c $ gcc calcul.o main.o -o main tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 8 / 19

Inclusion unique Important : le compilateur n'"aime" pas inclure plusieurs fois les mêmes chiers.h car cela peut entraîner des déclarations multiples. Pour se protéger des inclusions multiples, on utilise la structure suivante pour ses propres chiers header : #ifndef CALCUL_H // si CALCUL_H n'est pas défini #define CALCUL_H // alors on le définit int multiplier(int a, int b); int plus(int a, int b); #endif // fin si Lors de l'inclusion suivante, le contenu ne sera pas inclus car CALCUL_H a déjà été déni et donc ses déclarations sont déjà connues. Il est aussi possible d'utiliser la directive #pragma once. tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 9 / 19

Makele (1/2) Les étapes peuvent être automatisées en utilisant l'outil make et en écrivant les règles de fabrication dans un chier Makefile. Le chier Makefile contient la description des opérations nécessaires pour générer une application. Pour faire simple, il contient les règles à appliquer lorsque les dépendances ne sont plus respectées. Le chier Makefile sera lu et exécuté par la commande make. Une règle est une suite d'instructions qui seront exécutées pour construire une cible si la cible n'existe pas ou si des dépendances sont plus récentes. La syntaxe d'une règle est la suivante : cible : dépendance(s) <TAB>commande(s) tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 10 / 19

Makele (2/2) Pour notre exemple, la structure du chier Makefile sera : main: main.o calcul.o gcc main.o calcul.o -o main main.o: main.c gcc -c main.c calcul.o: calcul.c gcc -c calcul.c Pour fabriquer l'application, il sura de faire : make -f Makefile (on lui dit de lire le chier Makefile) ou plus simplement make (car par défaut il lit le chier Makefile dans le répertoire courant). tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 11 / 19

make (1/2) make est un logiciel traditionnel d'unix. C'est un "moteur de production" : il sert à appeler des commandes créant des chiers. À la diérence d'un simple script shell, make exécute les commandes seulement si elles sont nécessaires. Le but est d'arriver à un résultat (logiciel compilé ou installé, documentation créée, etc.) sans nécessairement refaire toutes les étapes. make fut à l'origine développé par le docteur Stuart Feldman, en 1977. Ce dernier travaillait alors pour Bell Labs. De nos jours, les chiers Makefile sont de plus en plus rarement générés à la main par le développeur mais construit à partir d'outils automatiques tels qu'autoconf, cmake ou qmake qui facilitent la génération de Makefile complexes et spéciquement adaptés à l'environnement dans lequel les actions de production sont censées se réaliser. tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 12 / 19

make (2/2) make est un outil indispensable aux développeurs car : make assure la compilation séparée automatisée plus besoin de taper une série de commandes make permet de ne recompiler que le code modié optimisation du temps et des ressources make utilise un chier distinct contenant les règles de fabrication (Makele) mémorisation de règles spéciques longues et complexes à retaper make permet d'utiliser des commandes (ce qui permet d'assurer des tâches de nettoyage, d'installation, d'archivage, etc...) une seule commande pour diérentes tâches make utilise des variables, des directives,... facilite la souplesse, le portage et la réutilisation tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 13 / 19

Makele : les variables Compilation séparée La première amélioration du chier Makele est d'utiliser des variables. On déclare une variable de la manière suivante : NOM = VALEUR Et on l'utilise comme ceci : $(NOM) # le nom de l'exécutable : TARGET=main # l'espace n'est pas obligatoire MODULE = calcul # le reste est "générique" CC = gcc -c # la commande de compilation LD = gcc -o # la commande pour l'édition de liens CFLAGS = -Wall # les options de compilation LDFLAGS = # les options pour l'édition de liens all: $(TARGET) # la cible par défaut est la cible de la première règle trouvée par make (ici all) $(TARGET): $(TARGET).o $(MODULE).o $(LD) $(TARGET) $(LDFLAGS) $(TARGET).o $(TARGET).o: $(TARGET).c $(CC) $(CFLAGS) $(TARGET).c $(MODULE).o: $(MODULE).c $(CC) $(CFLAGS) $(MODULE).c tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 14 / 19

Makele : les variables automatiques (1/2) Les variables automatiques sont des variables qui sont actualisées au moment de l'exécution de chaque règle, en fonction de la cible et des dépendances : $@ : nom complet de la cible $< : la première dépendance $? : les dépendances plus récentes que la cible $^ : toutes les dépendances $* : correspond au nom de base (sans extension) de la cible courante $$ : le caractère $... (consulter la doc de make) Elles sont très utilisées dans les chiers Makele pour éviter d'écrire en "dur" les noms de chiers dans les commandes. tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 15 / 19

Makele : les variables automatiques (2/2) La deuxième amélioration du chier Makele est d'utiliser les variables automatiques. Cela permet d'ajouter notamment une dépendance sur un chier header sans qu'il soit compiler :... $(TARGET): $(TARGET).o $(MODULE).o $(LD) $@ $(LDFLAGS) $^ $(TARGET).o: $(TARGET).c $(MODULE).h $(CC) $(CFLAGS) $< $(MODULE).o: $(MODULE).c $(MODULE).h $(CC) $(CFLAGS) $< tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 16 / 19

Makele : les règles génériques Certaines règles sont systématique : tous les chiers.c sont compilés avec gcc -c par exemple. On peut alors utiliser une règle générique de la manière suivante :... %.o: %.c $(CC) $(CFLAGS) -o $@ $< # ou pour des anciennes versions :.c.o: $(CC) $(CFLAGS) -o $@ $< tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 17 / 19

Makele : divers Compilation séparée Quelques utilisations pratiques : # Génération de liste de fichiers objets à partir de SRC : SRC = main.c calcul.c OBJ = $(SRC:.c=.o) # Ou de manière plus "robuste" : OBJ = $(strip $(patsubst %.c, %.o, $(wildcard *.c))) # Génération de la liste des fichiers sources : SRC = $(wildcard *.c) OBJ = $(SRC:.c=.o) tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 18 / 19

Makele : la cible.phony, clean et cleanall Dans un Makele basique, la cible clean est la cible d'une règle ne présentant aucune dépendance et qui permet d'eacer tous les chiers objets (.o ou.obj) Problème : si un chier porte le nom d'une cible, il serait alors forcément plus récent que ses dépendances et la règle ne serait alors jamais exécutée. Solution : il existe une cible particulière nommée.phony dont les dépendances seront systématiquement reconstruites..phony: clean cleanall clean: rm -f *.o cleanall: rm -f *.o $(TARGET) tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr «v0.1 19 / 19