Utilisation du langage C en programmation de systèmes

Documents pareils
Arguments d un programme

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Utilisation d objets : String et ArrayList

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Introduction au langage C

Quelques éléments de compilation en C et makefiles

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

Java Licence Professionnelle CISII,

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

C++ Programmer. en langage. 8 e édition. Avec une intro aux design patterns et une annexe sur la norme C++11. Claude Delannoy

Bases de programmation. Cours 5. Structurer les données

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

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Premiers Pas en Programmation Objet : les Classes et les Objets

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

PROJET ALGORITHMIQUE ET PROGRAMMATION II

TP : Gestion d une image au format PGM

Le langage C. Séance n 4

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Les structures de données. Rajae El Ouazzani

Cours d initiation à la programmation en C++ Johann Cuenin

TD3: tableaux avancées, première classe et chaînes

Langage propre à Oracle basé sur ADA. Offre une extension procédurale à SQL

Travaux Dirigés n 1 : chaînes de caractères

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

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Le prototype de la fonction main()

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Claude Delannoy. 3 e édition C++


ACTIVITÉ DE PROGRAMMATION

Poker. A rendre pour le 25 avril

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Chapitre 1 : La gestion dynamique de la mémoire

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)

Le langage C. Introduction, guide de reference

Les arbres binaires de recherche

Les structures. Chapitre 3

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

Chapitre VI- La validation de la composition.

Algorithmique et Programmation, IMA

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

I. Introduction aux fonctions : les fonctions standards

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

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

Cours 1 : La compilation

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

Langage C. Patrick Corde. 22 juin Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin / 289

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

Chap III : Les tableaux

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

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

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

SUPPORT DE COURS. Langage C

INITIATION A LA PROGRAMMATION

Cours Programmation Système

Cours 14 Les fichiers

Exécutif temps réel Pierre-Yves Duval (cppm)

Programmation C. Apprendre à développer des programmes simples dans le langage C

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Programmation en C. École Nationale Supérieure de Techniques Avancées. Pierre-Alain Fouque et David Pointcheval

Algorithmique, Structures de données et langage C

TP1 : Initiation à Java et Eclipse

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Génie Logiciel avec Ada. 4 février 2013

OS Réseaux et Programmation Système - C5

Les chaînes de caractères

STAGE IREM 0- Premiers pas en Python

Derrière toi Une machine virtuelle!

STS SE. FreeRTOS. Programmation réseau WIFI. Programmation réseau. Socket Tcp. FlyPort smart Wi-Fi module

Programmation en langage C

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Programme Compte bancaire (code)

1. Structure d'un programme FORTRAN 95

Cours 1: Java et les objets

Principes des langages de programmation INF 321. Eric Goubault

Simulation d un système de paiement par carte bancaire

TP 1. Prise en main du langage Python

Conventions d écriture et outils de mise au point

Chap 4: Analyse syntaxique. Prof. M.D. RAHMANI Compilation SMI- S5 2013/14 1

OpenPaaS Le réseau social d'entreprise

REPUBLIQUE ALGERIENNE DEMOCRATIQUE ET POPULAIRE UNIVERSITE M HAMED BOGARA DE BOUMERDES

Programmation impérative

Analyse de sécurité de logiciels système par typage statique

Programmation par les Objets en Java

Introduction à l héritage en C++

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Outils pour la pratique

[APPLICATON REPARTIE DE VENTE AUX ENCHERES]

ECR_DESCRIPTION CHAR(80), ECR_MONTANT NUMBER(10,2) NOT NULL, ECR_SENS CHAR(1) NOT NULL) ;

Programmation Objet Java Correction

Chapitre I Notions de base et outils de travail

Programmation en Java IUT GEII (MC-II1) 1

PROJET 1 : BASE DE DONNÉES REPARTIES

Expression des contraintes. OCL : Object C o n t r a i n t L a n g u a g e

Rappels d architecture

Chapitre 4 : Édition de fichiers texte - Vi

UE C avancé cours 1: introduction et révisions

Transcription:

Utilisation du langage C en programmation de systèmes Jacques Mossière 21 septembre 2007 1 Introduction Cette note présente quelques particularités de l utilisation du langage C très utiles pour la programmation de systèmes. Nous ne présentons que les principes généraux et les éventuelles difficultés d emploi seront signalées sur des exemples. Pour un traitement complet, il faut se reporter à un ouvrage sur le langage C. Celui que nous utilisons est «Introduction au langage C» par Bernard Cassagne. Dans chaque paragraphe, nous indiquons les pages ou paragraphes où la notion présentée est traitée. Une lecture attentive de l annexe F (le bêtisier) permet d éviter pas mal d erreurs classiques. 2 Compilations séparées Tout logiciel un tant soit peu complexe doit être divisé en un certain nombre de composants que nous appellerons ici des modules. En plus de la complexité, un système d exploitation est presque toujours écrit dans plusieurs langages de programmation, par exemple en C et en assembleur. Quand on écrit un module, il est classique de distinguer son interface, c est à dire les éléments définis dans le module et utilisables de l extérieur et le corps du module. Par convention, l interface du module toto sera placée dans le fichier de nom toto.h et le corps du module dans le fichier de nom toto.c. L interface d un module peut contenir des déclarations de constantes, de types, de variables ou de référence de fonctions. Les règles de correspondance entre les éléments définis dans un module et utilisés dans d autres sont explicitées dans Cassagne, chapitre 9. En simplifiant, tout se passe bien si : pour une fonction, on fait figurer dans l interface l en-tête de la fonction, pour une constante ou un type, l interface contient la déclaration complète, pour une variable, on place la déclaration, précédée du mot clé extern sans initialisation. Pour inclure dans un module l interface d un autre module (ou du module lui-même), on utilise l instruction C #include (Cassagne p. 22). Cette instruction recopie dans le fichier en cours de compilation le texte contenu dans le fichier dont le nom figure en argument du #include. L interface d un module doit être introduite une fois et une seule dans chaque unité de compilation qui l utilise. Il est commode pour cela d utiliser la commande de compilation conditionnelle #ifndef (Cassagne p. 140). Le texte d un fichier d interface toto.h aura ainsi la structure ci-dessous. 1

#ifndef TOTO_H // ou n importe quel nom d utilisation peu probable #define TOTO_H // les définitions de l interface, par exemple #define NB 25 extern int t[nb] ; int max (int a, int b) ; #endif À la première inclusion du fichier toto.h, le nom TOTO_H, qui n est pas encore défini, sera défini et le contenu du fichier effectivement recopié. L utilisation de #ifndef évite de nouvelles inclusions puisque le nom TOTO_H a été défini au premier appel. Toutes les variables et fonctions qui apparaissent dans l interface d un module doivent bien sûr être définies dans le corps de ce module. 3 Définition de constantes Les définitions des paramètres de votre système (nombre max de processus, taille d une pile système, nombre max de files de messages ou de sémaphores, etc.) doivent être regroupées dans un même module. De même, les définitions des constantes utilisées dans un module doivent figurer au début du module et non pas réparties dans les instructions. Le respect de ces règles permet d effectuer sans risque d erreur des modifications des valeurs des paramètres. On utilise pour définir une constante l instruction C #define (Cassagne p. 15). Lorsque le compilateur a rencontré #define identificateur reste-de-la-ligne il remplacera toute occurrence d identificateur par reste-de-la-ligne Exemple 1 #define NBPROC 256 Exemple 2 Une définition de constante peut faire intervenir des expressions, par exemple : #define NB NBPROC + 1 Telle quelle, cette définition présente un piège : que calcule l expression NB * 2? Le remplacement introduit par la définition conduit à l expression NBPROC + 1 * 2 que la priorité des opérateurs ramène à NBPROC + 2, ce qui n était probablement pas la valeur attendue. Une façon d éviter le piège est d écrire #define NB (NBPROC + 1) 4 Définition de macros L instruction #define que nous venons d utiliser pour définir des constantes est en fait de portée beaucoup plus générale : le remplacement d un identificateur par un texte peut être paramétré. Les macros (diminutif de macro-instructions) et leurs avantages et pièges sont présentées en détail dans Cassagne paragraphe 8.1. Nous donnons ci-dessous quelques éléments, puis nous montrerons l utilisation que nous en avons faite pour le paquetage de gestion de files. 2

4.1 Principe Une macro sans paramètre correspond à l utilisation faite ci-dessus. La ligne #define identificateur reste-de-la-ligne conduit au remplacement de l identificateur par le reste de la ligne. Si une ligne est insuffisante, on peut passer à la ligne suivante en plaçant un caractère backslash (\). Une macro avec paramètre est définie par #define identificateur(liste-de-parametres-formels) reste-de-la-ligne. Elle peut être appelée à chaque utilisation d identificateur suivi d une liste de paramètres effectifs ayant la même longueur que la liste des paramètres formels. L identificateur est alors remplacé par le corps de la macro dans lequel chaque occurrence d un paramètre formel est remplacé par le paramètre effectif correspondant. 4.2 Exemple #define max(a,b) ((b > a)? b : a) Bien que cet exemple donne souvent le résultat attendu, il permet d illustrer un piège des appels de macros. Soit x = 2 ; Quel est l effet de l instruction y = max(1,x++) ; Cette instruction produit l instruction C y = ( (x++ > 1)? x++ : 1 ) et après son exécution, x == 4 ; y ==3 ; 5 Les pointeurs Les pointeurs sont décrits dans Cassagne, chap. 3 et 4. 5.1 Généralités p * p FIG. 1 Pointeur et structure pointée 3

Comme dans beaucoup de langages de programmation, un pointeur C est une variable qui permet de «désigner» une autre variable ; la valeur d un pointeur est l adresse de la variable pointée. Lorsqu un pointeur p pointe vers un élément e, l élément e est désigné par *p. Si l élément e est une structure comportant un champ c, on peut accéder à ce champ soit par (*p).c soit par p->c. En C, un pointeur ne peut désigner qu une variable d un type donné, celui précisé lors de la déclaration du pointeur. Si l élément qu on veut désigner ne possède pas le bon type, il faut recourir à une conversion (cf.??). 5.2 Affectation de valeur à un pointeur On peut affecter une valeur à un pointeur de trois façons différentes : 1. si p et q sont deux pointeurs vers un même type et si q a déjà reçu une valeur, alors cette valeur peut être recopiée dans p par une simple affectation p = q ; 2. si une variable v de type t existe, et si p est un pointeur vers le type t, on peut placer dans p une valeur de pointeur vers v par l instruction p = &v ; 3. on peut aussi créer dynamiquement une structure (appel à la fonction malloc) et récupérer un pointeur vers l élément créé. Le pointeur récupéré est du type void * qu il faut transformer pour lui donner le type voulu. 5.3 Pointeurs et tableaux Les relations entre tableaux et pointeurs sont étudiées dans Cassagne chapitre 4. Schématiquement, la déclaration toto t[10] est équivalente, en plus de la réservation de 10 éléments, à la déclaration de t comme pointeur non modifiable vers toto et de donner comme valeur à t l adresse du premier élémént. Il y a de même équivalence entre t[i] et *(t+i) ; cette règle permet de comprendre l arithmétique sur les pointeurs : lorsqu on ajoute un entier n à un pointeur, la valeur résultante doit pointer vers le nème élément d un tableau fictif dont l élément d indice 0 est pointé par t. En bref, si q pointe vers un caractère, q+1 augmente la valeur de q de 1, de 4 si q pointe sur un entier long, etc. 5.4 Conversion de type : cast Dans certains langages de programmation, le type associé à un pointeur est fixe et ne peut être converti (conversion de type ou coertion) que dans un petit nombre de cas bien définis. Au contraire, on peut en C transformer pratiquement n importe quelle expression exp vers une valeur de pointeur de n importe quel type toto grâce à l opérateur de conversion (appelé cast en C) (toto) exp Cet opérateur transforme l expression expr en une expression «équivalente» de type toto. 5.5 Pointeur et adresse, transformation d un entier en pointeur Pour transformer un entier en un pointeur, il suffit d utiliser l opérateur de conversion que l on vient de présenter. 4

En programmation de systèmes, on est souvent amené à accéder à des structures par l intermédiaire de leur adresse (pensez au descripteur d une zone de mémoire libre comme dans la programmation de l allocateur du TP1). Le type dans lequel on doit convertir l adresse dépend de la valeur qu on veut y ranger : si c est un caractère ou un tableau de caractères, on utilisera le type char *, si c est un entier ou un tableau d entiers, le type int *, etc. Remarque En toute rigueur, la transformation d un entier en pointeur et inversement dépend de l architecture de la machine dont on dispose. Ce qui est énoncé dans ce paragraphe est correct sur la plupart des machines disponibles, et en particulier sur les machines sur lesquelles nous réalisons le projet (Intel IA 32). 5.6 Exemple Le programme ci dessous contient la définition d un élément de liste composé d un doublet (valeur, pointeur vers l élément suivant) et une procédure permettant de créer un doublet et de l insérer en tête d une liste. A noter le pointeur de pointeur **l qui permet de passer à la procédure l adresse du pointeur de tête de liste. #define NULL (0) struct elem { int valeur ; struct elem *suivant ; } ; struct elem *Maliste ; int a ; void inserer (int x, struct elem **l) { struct elem *prec, *cour, *aux ; aux = malloc (sizeof (struct elem)) ; if (aux == NULL) erreur(...) ; /* on admet qu erreur stoppe l exécution */ aux->valeur = x ; aux->suivant = *l ; *l = aux ; } 5