exercices corriges sur - MIS

30 downloads 763 Views 676KB Size Report
Langage de programmation 1. Concepts ... Comporte des exercices dont les solutions sont publiées dans : “Exercices corrigés sur le langage C, solutions des  ...
Langage de programmation 1 Concepts avancés du développement en C sous Unix

[email protected]

2

K&R “Le langage C, norme ANSI” Brian W. Kernighan, Denis M. Ritchie 2ème édition, 1988, Prentice-Hall / Dunod

© Dominique Lazure

Comporte des exercices dont les solutions sont publiées dans : “Exercices corrigés sur le langage C, solutions des exercices du Kernighan et Ritchie” C. Tondo, S. Gimpel, 2000.

3

Hello world ! /* File: hello.c Author: Dominique Lazure Creation date : Oct 4 2002 Last modification : Feb 1 2005 */

© Dominique Lazure

#include int main(void) { printf("Hello world !\n"); }

4

Commentaires /* un commentaire façon classique */ Pas d'imbrication : fin sur la prochaine séquence de fermeture // un autre commentaire (à la C++)

© Dominique Lazure

Fin en fin de ligne Du bon usage des commentaires : Entête pour chaque fichier Spécification des fonctions avant le corps d'une fonction Eviter les commentaires insignifiants ( i=i+1; /* incrémentation */ ) Prendre l'habitude de commenter en anglais

5

#include Inclut un fichier d'entêtes (généralement .h) à partir : de la bibliothèque du compilateur (dans /usr/include) #include du répertoire courant (utilisateur) #include “monprojet.h”

© Dominique Lazure

Permet au compilateur certaines vérifications de type Par défaut : un paramètre de fonction est entier Différence entre C-K&R et C-ANSI Warnings du compilateur, pas d'erreur de compilation

6

Pré-processeur cpp Consomme les directives : #include #define

© Dominique Lazure

#undef #ifdef ... #else ... #endif

inclut un fichier header définit une macro annule une macro si une macro est définie ou non définie (ne compile pas l'alternative)

#ifndef

7

#define Constantes, Macros : #define #define #define #define

FAUX 0 VRAI (!FAUX) PI 3.141529 UNE_LONGUE_MACRO { printf(“Hello “);\ printf(“World !\n”); }

© Dominique Lazure

Macros avec paramètre(s) : #define abs(x) ((x)B?A:B)

Attention à la priorité des opérateurs !

8

#define n'est pas fonction ! #define mdeuxfois(c) (2*c)

© Dominique Lazure

int fdeuxfois(int c) { return (2*c) ; } main() { int x=3,resuMacro,resuFonc; resuMacro=mdeuxfois(x+1); resuFonc=fdeuxfois(x+1); }

9

© Dominique Lazure

Compilation directe % cc hello.c -o hello % ls -l hello* -rwxr-xr-x 1 dushmol -rw-r--r-1 dushmol % make hello make: 'hello' is up to % touch hello.c % make hello cc hello.c -o hello % ls -l hello* -rwxr-xr-x 1 dushmol -rw-r--r-1 dushmol

linfo linfo

3455 Oct 4 11:47 hello 123 Oct 4 11:46 hello.c

date.

linfo linfo

3455 Oct 4 11:49 hello 123 Oct 4 11:47 hello.c

10

Phases de compilation

Editeur de texte % emacs hello.c

hello.c

hello

Exécution % hello Hello World !

© Dominique Lazure

Compilation % cc hello.c -o hello

Préprocesseur % man cpp

.c

Compilateur C % man gcc

Hello.o

printf.o

Édition de liens % man ld libc.a

11

Édition de liens Créer un binaire exécutable à partir des différents objets binaires et des librairies.

© Dominique Lazure

Exécutables linkés statiques : % gcc -static Le code des fonctions est inclu dans l'exécutable Cas de certaines librairies non libres (Motif) Exécutables plus volumineux Temps d'exécution réduit Exécutables linkés dynamiques (défaut) : % ldd hello Le code des fonctions est chargé lors des premiers appels Pas de recompilation lors de changement de librairie Exécutables plus légers

12

Édition de liens Créer un binaire exécutable à partir des différents objets binaires et des librairies.

© Dominique Lazure

Exécutables linkés statiques : % gcc -static %man gcc … -static On systems that support dynamic linking, this prevents linking with the shared libraries. On other systems, this option has no effect. This option will not work on Mac OS X unless all libraries (including libgcc.a) have also been compiled with -static. Since neither a static version of libSystem.dylib nor crt0.o are provided, this option is not useful to most people.

13

Appel d'un programme A partir d'un shell Entrée standard : Par défaut :

le clavier

Redirection à partir d'un fichier :

< filename

© Dominique Lazure

Sortie standard : Par défaut :

la fenêtre shell

Redirection dans un fichier : Écrasement du contenu initial : Concaténation :

> filemane >> filename

Redirection vers une commande :

| commande

Sortie erreur : Par défaut : Redirection avec écrasement : Redirection avec concaténation :

la fenêtre shell 2> filename 2>> filemane

14

Compilation séparée

© Dominique Lazure

Un gros projet se doit d'être découpé en plusieurs modules. Exemple : développement d'un navigateur web Gestion des protocoles : http.c http.h ftp.c ftp.h Gestion des URL : url.c url.h Gestion de l'affichage : texte.c texte.h images.c images.h Gestion des favoris : bookmark.c bookmark.h ... Programme principal : minifox.c #include #include “book.h” #include “url.h” Conséquences sur les déclarations de variables (cf plus tard)

15

© Dominique Lazure

Compilation en objets binaires % ls http.c http.h minifox.c url.c url.h % cc -c url.c % ls http.c http.h minifox.c url.c url.h url.o % cc -c http.c % cc -c minifox.c % ls http.c http.h http.o minifox.c minifox.o url.c url.h url.o % cc http.o url.o minifox.o -o minifox % ls -l minifox -rwxr-xr-x 1 dushmol linfo 12345 Oct 4 11:45 minifox

16

Gestionnaire de projet Unix : Makefile (1) Makefile :

fichier comportant une suite d'entrées, lu par % make

Entrée :

cible: dépendances action

Exemple : http.o: http.c http.h url.h cc -c http.c

© Dominique Lazure

url.o: url.c url.h cc -c url.c texte.o: texte.c texte.h cc-c texte.c minifox.o: minifox.c http.h url.h texte.h cc -c minifox.c minifox : minifox.o http.o texte.o url.o cc minifox.o http.o texte.o url.o -o minifox

17

Makefile (2) Commentaires : lignes commençant par # Gestion de macros (comme les variables de bash) (% make -p) CC=/usr/bin/cc CFLAGS=” -O -systype bsd43” Macros spéciales : $@ cible de la règle courante $? liste des dépendances changées © Dominique Lazure

$< nom du fichier qui a causé le déclenchement de l'action $* prefix commun à la cible et aux dépendances pretty: pretty.c $(CC) $(CFLAGS) $? -o $@

18

Makefile (3) Cible par défaut : première entrée Cible(s) en argument(s) de l'appel à make Règles sans dépendances : clean: -rm *.o

© Dominique Lazure

Règles par défaut : .o.c: $(CC)

*~

$(CFLAGS)

core

-c $*.c

Arrêt de la compilation à la première erreur (sauf -action) Echo en sortie standard des commandes lancées (sauf @action) Exécution de make sans déclenchement des actions : % make -n

19

Makefile (4) Exemple de construction d'une librairie : MYLIB=libmy.a

© Dominique Lazure

OBJETS=x.o y.o z.o AR=ar $(MYLIB): $(OBJETS) $(AR) rvu $@ $(OBJETS) ; ranlib $@

20

Makefile (5) Les gros projets sont gérés avec des arborescences de sources Exemple :

© Dominique Lazure

MYTOOLDIR=../mesoutils MYLIB=$(MYTOOLDIR)/libmy.a $(MYLIB): cd $(MYTOOLDIR) make libmy.a

Erreur ! make forke un shell par ligne d'action(s) déclenchée. Continuation de ligne : \ Make and Makefiles, Reg Quinton, University of Ontario. http://ist.uwaterlo.ca/~reggers

21

Hello world ! /* File: hello.c Author: Dominique Lazure Creation date : Oct 4 2002 Last modification : Feb 1 2005 */

© Dominique Lazure

#include int main(void) { printf("Hello world !\n"); }

22

Fonctions Toute instruction C fait partie d'une fonction Toute fonction comporte : Une entête – header (de préférence commentée)

© Dominique Lazure

Un type pour la valeur de retour (éventuellement void) Un nom de fonction (identifiant) Une liste (vide) de paramètres formels

Un corps - body Liste d'instructions entre { } séparées par ;

23

Interaction shell / programme C

Fonction appelée au lancement du processus : int main()

© Dominique Lazure

Code de retour renvoyé à l'appelant : Entier $? de bash (par convention : 0 = succès) section 'RETURN VALUE' des pages man.

24

Appel d'une fonction nom ( paramètres_liste )

© Dominique Lazure

Liste des paramètres effectifs : Séparés par des , Eventuellement vide (void) Passage des paramètres par valeur Evaluation des paramètres dans un ordre quelconque

25

printf Affiche sur la sortie standard une chaine de caractères int printf( char * format,...);

Retour : nombre de caractères affichés (sauf \0)

© Dominique Lazure

Autres arguments : référencés (et typés) dans le premier argument %d %u %x %c %s %f

entier entier non signé entier en hexadécimal caractère chaine de caractères nombre réel

26

Représentation interne/externe

© Dominique Lazure

printf (“%c %d %x”,65,65,65); Aucune vérification effectuée (impossibilité) Segmentation faut, core dumped Possibilités diverses pour le format % man 3 printf Caractères spéciaux pour printf : \\ \n \f \r

\ newline form-feed carriage return \v

\a bell \b backspace \t tabulation H tabulation V

27

Mon second programme

© Dominique Lazure

#include main() { int i=1; while ( i < . ++ -- + * & (type) sizeof % >

>=

-=

*=

/=

%=

&=

^=

|=

=

56

© Dominique Lazure

Quelques expressions à éviter ! a+++b ; a+ ++b; a[i]=i++ a[i]=a[i++] a=+3 a=xy ; a=xy; a != a&1 ; a=1,2; a=(1,2); a=f(n,n++); x&&y; x&(&y); ...

57

Opérations bit à bit : masquage Déclaration de variable : un octet minimum. Idée : stocker 8 informations booléennes par octet.

© Dominique Lazure

Principe : déclarer un masque (puissance de 2) par booléen. #define m_read 4 #define m_write 2 #define m_exec 1 Affectation masquée : Positionnement à 1 : Inversion : Positionnement à 0 :

variable |= mask ; variable ^= mask ; variable &= ~mask ;

Isolement du masque :

(variable & mask ) ?...

58

Isolement d'une tranche (K&R) #define entier #define byte

unsigned int unsigned char

entier lirebits (entier x, byte p, byte n) { return ( (x>>(p-n+1)) & (~((~0) argum.c Longueur théorique non bornée Usage conventionnel : marqueur de fin de chaîne : Les bibliothèques simplifient l'usage.

'\0'

71

Les erreurs classiques Erreur d'allocation : dépassement Prévoir suffisamment de place, contrôler ! Erreur d'affectation : toto=Nom ;

Copie impérative élément par élément

© Dominique Lazure

Erreur de longueur : lg=sizeof(toto);

Parcours de la chaîne par une boucle jusqu'à '\0' Utilisation de strlen() Bibliothèques de fonctions : strlen, strcpy, strcat, strcmp, strncpy...

72

Pointeurs génériques : void* Certaines fonctions ne connaissent pas le type pointé Exemple : #include void bcopy (const void *src, void *dest, size_t n);

© Dominique Lazure

size_t est le type de retour de l'opérateur sizeof Utilisés comme des pointeurs de caractères : int SRC[10],DEST[10]; bcopy (SRC,DEST,10*sizeof(int)); Un pointeur sur void doit être converti avant tout déréférencement

73

Arithmétique des pointeurs Les opérateurs classiques s'appliquent naturellement aux pointeurs Addition ou soustraction d'un pointeur et d'un entier Incrémentation / décrémentation de pointeur Comparaison de deux pointeurs homogènes Affectation, comparaison à NULL

© Dominique Lazure

Unité de mesure : la taille (en octets) de l'élément pointé.

74

Arithmétique des pointeurs

© Dominique Lazure

int TAB[10]={1,2,3,4,5,6,7,8,9,10},i; int *PI=TAB; char *PC=TAB; for (i=0;i nécessite un pointeur non nul ! Segmentation fault. Core dumped

79

Union (types discriminés) Ensemble de champs non tous alloués Accès indépendants à tous les champs. sizeof (union) = Maxchamps (sizeof(champs))

© Dominique Lazure

Syntaxe identique à celle des structures : union info { struct judoka DD; struct pongiste SP; }; struct adherent { unsigned int carte; enum discipline sport; union info ref; };

/* discriminent */

struct adherent toto={1234,JUDO}; toto.ref.DD.ceinture=NOIRE; toto.ref.SP.classement=15;

80

Champs de bits (bitslice) Économiser sur le format de stockage des types entiers. Intervalle de valeurs possibles identifié, énuméré. Taille explicitement précisée pour un champ (en nombre de bits) struct droits { unsigned char owner:3; unsigned char group:3; unsigned char others:3; };

© Dominique Lazure

struct droits fic; fic.owner=REA|WRI|XEQ; fic.group=REA|XEQ; fic.others=0; Pas de vérification de débordement ! Interdiction d'utiliser l'opérateur & (ce ne sont pas des tableaux)

81

Synonyme de types : typedef Permet de raccourcir les écritures. Exemples : typedef struct toto titi; struct toto t1; titi t2; typedef union toto titi; union toto t1; titi t2;

© Dominique Lazure

typedef enum toto titi; enum toto t1; titi t2; typedef int titi[100]; int t1[100]; titi t2; typedef char * str; char *msg1; str msg2;

82

Types récursifs : la liste chaînée struct maillon { objet obj; struct maillon * suivant; };

© Dominique Lazure

typedef struct maillon maillon, * liste; liste l; maillon m1,m2; objet o; m1

l=&m1; m1.obj=o; (*l).obj=o; (*l).suivant=&m2; l->obj=o; l->suivant=&m2;

obj

suivant

m2 l

83

© Dominique Lazure

Questions / Remarques

Le passage de paramètres

[email protected]

85

Principe général

© Dominique Lazure

Passage par valeur : 1. 2. 3. 4. 5. 6. 7. 8.

Évaluation des paramètres effectifs Copie des résultats sur la pile Appel de la fonction Association des paramètres formels Exécution de la fonction Évaluation du résultat (return) et dépilement Retour à la fonction appelante Récupération du résultat en sommet de pile

86

Exemple int addition(int a, int b) { int c; c=a+b; return c; } foo() { int x=12,y=45,z; z=addition(x,y); © Dominique Lazure

}

87

''Contre''-exemple void incrementer(int a) { a=a+1; }

void incrementer(int *a) { *a=*a+1; }

foo() {

foo() { int x=12; incrementer(x);

© Dominique Lazure

}

int x=12; incrementer(&x); }

88

Tableau en paramètre Nom d'un tableau (sans crochet) : adresse de base.

© Dominique Lazure

void bar(int T[], int lg) { int i; for (i=0;i