• Aucun résultat trouvé

Pensez à vous inscrire... si ce n est pas encore fait

N/A
N/A
Protected

Academic year: 2022

Partager "Pensez à vous inscrire... si ce n est pas encore fait"

Copied!
76
0
0

Texte intégral

(1)

UE C avanc´e cours 1: introduction

Jean-Lou Desbarbieux et St´ephane Doncieux LI215

Licence Informatique UMPC 2013/2014

Sommaire

Introduction Pr´esentation

´Evaluation Calendrier Biblio Intro au C Types

Types simples Op´erateurs

Structures de contrˆole Fonctions

Pr´esentation du module

I Module avanc´e (niveau 200)

I Objectifs principaux :

I Gestion explicite de la m´emoire

I Structure de donn´ees autor´ef´erentielles : liste, pile, arbres

I Itin´eraire :

I Notions d’algorithmique

I Manipulation de fichiers

Pensez `a vous inscrire...

... si ce n’est pas encore fait

´Evaluation

I 60% pour l’examen final

I 40% pour le contrˆole continu

I 20% partiel

I 20% pour l’appr´eciation en TD/TME (corrections automatiques, mini-projets, appr´eciation g´en´erale)

(2)

Calendrier

I 11 semaines de cours, 11 semaines de TD/TME

I Les TD/TME commencent les jeudi et vendredi de la semaine du 9 septembre 2013

I Le dernier TD a lieu la semaine du 9 d´ecembre 2013

I Le partiel aura lieu entre le 4 novembre 2013

I L’examem aura lieu la semaine du 6 janvier 2014

Calendrier

Semaine 1.R´evisions ( ?)

I Introduction

I Types

I Expressions

I printf

I Fonctions

I Fonctions r´ecursives

I Passages de param`etres

Calendrier

Semaine 2.

I D´ecoupage d’un programme

I Compilation

I Environnement (Makefile, gcc, ddd)

I Chaˆınes de caract`eres Semaine 3.

I pointeurs

I manipulations et utilisations des pointeurs

I allocation dynamique

Calendrier

Semaines 4.

I structures

I fichiers Semaines 5.

I entr´ees/sorties

I retour sur les chaˆınes de caract`eres

(3)

Calendrier

Semaines 6.Respiration Semaine 7.Listes chaˆın´ees Semaine 8.Arbres

Semaine 9.Arbres bis

Semaine 10.Tables de hachage

Semaine 11.Ouverture et/ou r´evisions et conclusion du cours

Bibliographie et outils

I Le langage C : norme ANSI. Brian W. Kernighan & Denis M. Ritchie, Dunod

I Programmer en langage C. Claude Delannoy, Eyrolles

I C : a reference manual. Samuel P. Harbison & Guy L.

Steele Jr., Prentice Hall

I C : a software engineering approach. Peter A. Darnell &

Philip E. Margolis, Springer

I ...

Environnement : Linux.

Outils informatiques utilis´es :

I ´editeurs : emacs/vi/gvim/gedit

I compilateur : gcc

I d´ebogueur : gdb, ddd

Le Langage C : historique

I Le langage C a ´et´e invent´e en 1972 par Dennis Ritchie et Ken Thompson (AT&T Bell Laboratories) pour r´e´ecrire Unix et d´evelopper des programmes sous Unix.

I En 1978, Brian Kernighan et Dennis Ritchie publient la d´efinition classique du C dans le livre The C Programming language .

I C est une norme ANSI (ANSI-C) depuis 1989 et un

standard ISO depuis 1990, standard ´etendu en 1999 (C99) et en 2011 (C11).

I Toutes les distributions Linux fournissent des compilateurs C.

Introduction au langage C

Caract´eristiques du langage :

I imp´eratif

I bas-niveau

I (peu) typ´e

(4)

´Ecrire un message `a l’´ecran

Utiliser la fonctionint printf(const char *format, ...):

p r i n t f ( ” Bonjour , bienvenue a l ’UE LI215 annee 2009/2010!\n ” ) ; i n t n=215;

i n t an1=2010 ,an2=2011;

p r i n t f ( ” Bonjour , bienvenue a l ’UE LI%d !\n annee %d/%d ” , n , an1 , an2 ) ;

Quelques codes de format utiles : I %d: entier

I %c: caract`ere

I %s: chaˆıne de caract`eres I %f: nombre r´eel

ATTENTION : pour utiliserprintf, il faut ajouter la ligne suivante au tout d´ebut du fichier source :

#include <stdio.h>

Nous y reviendrons plus tard...

Introduction au langage C

Exemple de programme : fichier ”welcome.c”

#include<s t d i o . h>

i n t main (void){ i n t annee=2010;

i n t nUE=215;

p r i n t f ( ” Bonjour , bienvenue a l ’UE LI%d annee %d/%d !\n ” , nUE, annee , annee + 1 ) ;

return 0;

}

Compilation

gcc -o welcome welcome.c Ex´ecution

./welcome

Types

Types entiers

Type Signification Taille (o) Plage de valeurs

char Caract`ere 1 -128 `a 127

unsigned char Caract`ere 1 0 `a 255

short int Entier court 2 -32768 `a 32767

uns. short int Entier court non s. 2 0 `a 65535

int Entier 2(16 b) -32768 `a 32767

4(32 et 64 b) -2 147 483 648

`a 2 147 483 647 unsigned int Entier non sign´e 2(16 b) 0 `a 65 535

4(32 et 64 b) 0 `a 4 294 967 295

long int Entier long 4 -2 147 483 648

`a 2 147 483 647 8(64 b) -9 223 372 036 854 775 080

`a9 223 372 036 854 775 807 uns. long int Entier long non s. 4 0 `a 4 294 967 295

(5)

Types `a virgule flottante

Repr´esentation :signe×mantisse×baseexposant Plage de valeurs donn´ee pour un syst`eme Linux (non normalis´e).

Type Signification Taille (o) Plage de valeurs float Simple pr´ecision 4 +/-1.175494e-38 `a 3.402823e+38

double Double pr´ecision 8 +/-2.225074e-308 `a 1.797693e+308

long double Double pr´ec. long 12 +/-3.362103e-4932 `a 1.189731e+4932

Types `a virgule flottante

ATTENTION :les flottants sont repr´esent´es de mani`ere approch´ee. Cons´equences :

I L’associativit´e n’est plus assur´ee :a+ (b+c) = (a+b) +c

I Valeur approch´ee d’une somme et somme de valeurs approch´ees

I Tests :

f l o a t x =0.1 , y = 0 . 1 ;

i f ( x+y == 0 . 2 ) /∗ peut e t r e v r a i ou faux ∗/ . . .

Caract`eres

I il n’y a pas vraiment de type “Caract`eres”

I le type char est type entier (on peut l’utiliser pour les calculs) prenant un octet.

I un caract`ere est repr´esent´e par un entier, la

correspondance (code/caract`ere) est ´etablie par la table ASCII.Exemple :

char c= ’ a ’ ;

p r i n t f ( ” c= %c %d\n ” , c , c ) ; Donne :

c= a 97

Chaˆınes de caract`eres

Pas de type string en C mais on utilise la notation ””. Exemple : p r i n t f ( ” bonjour ” ) ;

correspond `a la d´eclaration d’un tableau de char initialis´e avec les codes ASCII (dans la section rodata).

En cas de besoin d’une variable de type chaˆıne de caract`eres, on d´eclare un tableau de char :

char message1 [ 8 ] = ” bonjour ” ; /∗ 7 l e t t r e s et ’\0 ’ a l a f i n ∗/ char message2 [ ] = ” bonjour ” ;

p r i n t f ( ”%s\n ” , message1 ) ; p r i n t f ( ”%s\n ” , message2 ) ;

(6)

Type enum´er´e

Permet de d´efinir une constante ´enum´er´ee.

Exemple :

enum mois {JAN = 1 , FEV, MAR, . . .}; enum mois m=3;

enum mois n=JAN ; i f ( m == MAR ) {

p r i n t f ( ”m=MAR\n ” ) ; }

Tableaux

Permet de stocker dans un espace m´emoire contigu¨e des

´el´ements de mˆeme type.

i n t T1 [ 3 ] ={2 , 1 , 5}; i n t T2 [ ] ={4 , 1 , 5}; i n t T2 [ ] ; impossible ! char message1 [ ] = ” bonjour ” ; char message2 [ 8 ] = ” bonjour ” ;

/∗ tableau a p l u s i e u r s dimensions ∗/

char TC[ 3 ] [ 2 ] ={ { ’ a ’ , ’ b ’},{ ’ c ’ , ’ d ’},{ ’ e ’ , ’ f ’} };

Op´erateurs

Par ordre de pr´ec´edence :

-. r´ef´erence: () [] -> .

-. unaire: ! ˜ ++ -- + - * & (type) sizeof -. arithm´etique: * / %

-. arithm´etique: + - -. d´ecalage: << >>

-. relationnels: < <= > >=

-. relationnels: == !=

-. manipulation de bits: &

-. manipulation de bits: ˆ -. manipulation de bits: | -. logique: &&

-. logique: ||

-. conditionnel: ?:

-. affectation: = += -= *= /= %= &= ˆ= |= <<= >>=

Structures de contrˆole

(7)

if

i f ( expression ) { i n s t r u c t i o n s ; }else

{ i n s t r u c t i o n s ; }

switch

switch ( expression )

{case expression−constante : i n s t r u c t i o n s ; case expression−constante : i n s t r u c t i o n s ; default : i n s t r u c t i o n s

}

ATTENTIONau break...

while

while ( expression ) {i n s t r u c t i o n s ; }

for

for ( expression1 ; expression2 ; expression3 ) {i n s t r u c t i o n s ;

} equivaut `a :

expression1 ;

while ( expression2 ) {i n s t r u c t i o n s ; expression3 ; }

(8)

do while

tr`es proche du while avec test `a la fin : do

{i n s t r u c t i o n s ; while} ( expression ) ;

perturbation du d´eroulement des boucles

I break : interrompt une boucle

I continue : passe `a l’it´eration suivante

I goto : existe, mais

INTERDIT ! !

Fonctions

Sert `a regrouper des instructions dans un mˆeme bloc.

Int´erˆet :

I Simplifier la lecture et la compr´ehension d’un programme en le d´ecoupant proprement

I Maximiser la r´eutilisation de code

Exemple

i n t main ( ) { i n t i , n=1 ,m=10;

for ( i =2; i<=m; i ++) { n∗= i ;

} }

i n t f a c t o r i e l l e (i n t m) { i n t i , n=1;

for ( i =2; i<=m; i ++) { n∗= i ;

}return n ; }i n t main ( ) {

i n t n= f a c t o r i e l l e ( 1 0 ) ; }

(9)

D´eclaration de fonctions : notion de prototype

Le prototype d’une fonction pr´ecise : 1. la valeur de retour

2. le nom de la fonction 3. le type des arguments Exemples :

i n t f a c t o r i e l l e (i n t ) ;

f l o a t a i r e r e c t a n g l e (f l o a t l ,f l o a t d ) ;

Valeur de retour

I De type quelconquesauf tableau....

I valeur renvoy´ee par l’instructionreturn i n t f a c t o r i e l l e (i n t m) {

i n t i , n=1;

i f (m==0) { return 1;

}for ( i =2; i<=m; i ++) { n∗= i ;

}return n ; }

Arguments

I De type quelconque.

I Dans un prototype, les identificateurs de variable n’ont aucune signification pour le compilateur (mais peuvent faire comprendre au lecteur `a quoi servent les

arguments...).

I

ATTENTION au cas des tableaux :

I Sp´ecifier la taille d’un tableau pass´e en argument ne sert `a rien, le compilateur ne la regarde mˆeme pas ...

I Sauf dans le cas d’un tableau `a plusieurs dimensions !

I Il n’y a aucun moyen de connaˆıtre la taille du tableau dans la fonction. Elle doit ˆetre d´efinie comme variable globale ou pass´ee en argument !

I Explications plus tard...

Port´ee d’une d´eclaration

Comme pour une variable...

Cas 1 :

i n t f (i n t ) ; i n t g (i n t i ) {

/∗ f est connue ∗/ }i n t f (i n t i ) {

. . .

}i n t h (i n t i ) {

/∗ f est connue ∗/ }

Cas 2 :

i n t g (i n t i ) {

/∗ f n ’ est pas connue ∗/ }i n t f (i n t ) ;

i n t h (i n t i ) {

/∗ f est connue ∗/ }i n t f (i n t i ) {

. . . }

(10)

Le ”type” void

1. Lorsqu’une fonction ne doit pas renvoyer de valeur.

Exemple :void afficher resultats(float f[10]);

Peut ˆetre vu comme une proc´edure.

2. Lorsqu’une fonction ne prend pas d’arguments.

Exemple :void effacer ecran(void);

Peut se d´eclarer aussi :void effacer ecran();

Passage de param`etres

Passage par valeur void f (i n t n ) {

n=n+1;

}i n t main (void) { i n t i =2;

p r i n t f ( ” 1: i=%d ” , i ) ; f ( i ) ;

p r i n t f ( ” 2: i=%d ” , i ) ; }

Donne le r´esultat suivant : 1: i =2

2: i =2

Comment faire si on veut que les modifications r´ealis´ees dans la fonction ne soient pas perdues ?→r´eponse plus tard ! ATTENTION au cas des tableaux :ils ne sont pas transmis par valeur... Pourquoi ?→r´eponse plus tard !

Fonctions de la libc

Beaucoup de fonctions `a connaˆıtre : gestion des fichiers, des chaˆınes de caract`eres, ...

I retenir dans un premier temps le nom uniquement

I faire des fiches ou savoir retrouver rapidement

l’information dans un livre (droit aux documents pendant partiel et examen !)

I sur ordinateur, dans un terminal, taper :

man 3 <nom de fonction>(touche ’q’ pour sortir)

Exemple

(11)

Pr´esentation du probl`eme

Construction d’une biblioth`eque

I besoin de planches de longueur vari´ee (largeur unique)

I planches vendues dans le commerce de longueur unique : 2 m`etres

I Probl`eme : combien de planches acheter pour pouvoir couper toutes les planches souhait´ees ?

3 2 1

Algorithme choisi

Hypoth`ese simplificatrice : 3 planches maximum `a d´ecouper par planche du commerce.

Tant qu’il reste des planches `a d´ecouper Initialiser max `a 0

Pour toutes les combinaisons de 3 planches `a d´ecouper Est-ce qu’il reste des planches de ces longueurs `a couper ?

Est-ce que la longueur est inf´erieure `a 2m Si la longueur est sup´erieure au max, on met `a jour le max

Fin pour

Mise `a jour du nombre de planches restantes Afficher r´esultat

Fin tant que

Algorithme choisi (2

eme

version)

Calcul par r´ecurrence. Fonction r´ecurrente utilis´ee :

Si la longueur restante est trop petite: on arrˆete S’il ne reste plus de planches: on arrˆete

Pour toutes les planches restantes Longueur restante=Appel recursif

Si Longueur restante<Min longueur restante On enregistre le nouveau min

On renvoie le min.

(12)

UE C avanc´e

cours 2: d´ecoupage, compilation et d´ebogage et chaˆınes de caract`eres

Jean-Lou Desbarbieux et St´ephane Doncieux UMPC 2013/2014

Sommaire

D´ecoupage d’un programme et compilation

Outils

Chaˆınes de caract`eres

D´ecoupage d’un programme

.h, .c : fichiers de source multiples

I Le code peut ˆetre divis´e entre plusieurs fichiers sources disctincts qui ne seront assembl´es que dans la derni`ere

´etape de cr´eation d’un ex´ecutable.

I Pour pouvoir utiliser des fonctions disponibles dans d’autres fichiers, on doit d´efinir la signature de la fonction que l’on souhaite r´eutiliser

I Pour pouvoir utiliser des variables d´efinies dans d’autres fichiers, il faut d´eclarer le type et le nom de la variable pr´ec´ed´es du mot cl´e extern

I Ces d´eclarations de variables et de fonctions peuvent ˆetre regroup´ees dans unfichier header(.h). Ces headers sont ensuite inclus dans tous les fichiers sources grˆace `a la macro#include

(13)

.h, .c : exemple

Fichier mes fonctions.h :

extern f l o a t ma variable ; i n t ma fonction1 (int, f l o a t) ; void ma fonction2 (f l o a t, char[ 1 0 ] ) ;

Fichier mes fonctions.c :

f l o a t ma variable = 1 2 . ;

i n t ma fonction1 (int, f l o a t) { . . .

}void ma fonction2 (f l o a t, char[ 1 0 ] ) { . . .

}

Fichier

mon programme.c, utilisant les fonctions d´efinies dans

mes fonctions.c :

#include ” mes fonctions . h ” i n t main ( ) {

i n t i =0 , j ;

f l o a t f =ma variable ; j =ma fonction1 ( i , f ) ; . . .

}

compilation, macros et pr´eprocesseur

Les ´etapes permettant de passer d’un fichier source `a un executable :

I Traitement de chaque fichier source ind´ependamment :

I pr´etraitement : gestion des macros et autres directives au preprocesseur

I compilation : transformation du source obtenu en un fichier objet

I ´Edition des liens entre les fichiers objets pour g´en´erer la biblioth`eque ou l’ex´ecutable.

compilation, macros et pr´eprocesseur : exemple

Compilation de l’exemple pr´ec´edent :

I Un header : mes fonctions.h

I Deux fichiers sources : mes fonctions.c, mon programme.c 1. preprocessing et compilation des sources :

gcc -c -o mes fonctions.o mes fonctions.c gcc -c -o mon programme.o mon programme.c 2. ´edition des liens :

gcc -o mon programme mon programme.o mes fonctions.o

(pas de traitement `a faire sur le header, il sera inclus dans les fichiers .c par la macro#includepar le pr´eprocesseur)

compilation, macros et pr´eprocesseur : macros

Intructions ex´ecut´ees avant compilation.

I #defineassociation d’une ´etiquette `a une valeur

I #includeinclusion d’un fichier

I #ifdef ou#ifndef ...

#endif

(14)

Qualifieurs : extern

I Indique au compilateur qu’une variable a ´et´e d´eclar´ee dans un autre fichier source

I Unicit´e de la variable : pas de nouvelle r´eservation d’espace m´emoire.

Qualifieurs : const

D´eclaration d’une variable constante : const <type> <nom de variable>

Exemple :

const i n t i =3;

const f l o a t x =2.∗3.1415926;

Port´ee des variables

I Variables globales : partout apr`es leur d´efinition

I Si pr´ec´ed´ee deextern: d´eclar´ee effectivement dans un autre fichier, mais peut ˆetre ensuite manipul´ee comme si d´ecrite dans le mˆeme fichier

I Variables locales : de leur d´eclaration `a la fin du bloc.

Outils

(15)

GCC

Pr´eprocesseur, compilateur, ´editeur de lien selon les options.

gcc [options] source1.c source2.c...

Options couramment utilis´ees :

I -c: ne pas faire l’´edition de lien

I -o fichier sortie: nom du fichier de destination (fichier .o ou ex´ecutable selon les cas). Si non sp´ecifi´e, a.outpour un ex´ecutable,source.opour un fichier objet.

I -Wall: affiche tous les warnings

I -g: inclure les informations de debogage Pour information :

I -E: ne fait que le pr´etraitement et envoie le r´esultat sur la sortie standard.

D´eboggage : GDB &DDD

I Le programme doit ˆetre compil´e avec l’option-g

I dddinterface graphique pourgdb

I Permet d’ex´ecuter pas `a pas.

I Permet de poser des points d’arrˆet.

I Permet d’observer les variables.

D´eboggage m´emoire : electricFence & valgrind

ElectricFence

I Biblioth`eque remplac¸ant les fonctions C de gestion de la m´emoire

I Objectifs : faciliter la d´etection de

I d´ebordements en m´emoire

I d’utilisation de m´emoire lib´er´ee

I Utilisation :gcc -lefence -o monprog monprog.c Valgrind

I Logiciel permettant (entre autres) de v´erifier l’utilisation de la m´emoire :

I D´etecte :

I l’utilisation de variables non initialis´ees

I l’utilisation de m´emoire lib´er´ee

I les fuites m´emoires

I Utilisation :valgrind ./monprog

Makefile

`A quoi c¸a sert : simplifier la compilation, prendre en compte automatiquement les d´ependances...

Exemple de makefile

a l l : mon programme

mes fonctions . o : mes fonctions . h mes fonctions . c gcc co mes fonctions . o mes fonctions . c mon programme . o : mon programme . c mes fonctions . h

gcc −c −o mon programme . o mon programme . c mon programme : mon programme . o mes fonctions . o

gcc −o mon programme mon programme . o mes fonctions . o clean :

rm −f . o mon programme

(16)

Chaˆınes de caract`eres

Chaˆınes de caract`eres : repr´esentation en m´emoire

I Dans un tableau, termin´e par un

’\0’

I Exemple :

char nom [ ] = ” david ” ; char nom2[ 7 ] = ” g o l i a t h ” ;

/∗ i l manque une case pour ’\0 ’ ∗/ char nom3 [ ] = ” david\0 g o l i a t h ” ;

p r i n t f ( ”nom2=%s\n ” ,nom2 ) ; /∗ r e s u l t a t ? ∗/ p r i n t f ( ”nom3=%s\n ” ,nom3 ) ; /∗ r e s u l t a t ? ∗/

Quelques fonctions utiles : strlen

#include <s t r i n g . h>

s i z e t s t r l e n (const char ∗s ) ;

Renvoie la longueur d’une chaˆıne de caract`eres.

Remarque : le typechar *correspond `a un tableau surchar.

Quelques fonctions utiles : strcmp

#include <s t r i n g . h>

i n t strcmp (const char ∗s1 , const char ∗s2 ) ; i n t strncmp (const char ∗s1 , const char ∗s2 ,

s i z e t n ) ;

Comparaison entre chaˆınes de caract`eres.

La valeur de retour est :

I 0 si les deux chaˆınes sont ´egales

I n´egative si s1 arrive avant s2

I positive sinon

(17)

Quelques fonctions utiles : strcpy

#include <s t r i n g . h>

char ∗s t r c p y (char ∗dest , const char ∗src ) ; char ∗strncpy (char ∗dest , const char ∗src ,

s i z e t n ) ;

Copie entre deux chaˆınes de caract`eres.

Renvoie un pointeur sur dest.

(18)

UE C avanc´e cours 3: pointeurs

Jean-Lou Desbarbieux et St´ephane Doncieux UMPC 2013/2014

Sommaire

D´eclaration

D´eclaration et initialisation

Exemples d’utilisation des pointeurs Le pointeur NULL

Remarques

Manipulations d’un pointeur

Manipulation directe des pointeurs Manipulation de la donn´ee point´ee Affectation entre pointeurs

Tableaux & Pointeurs Allocation

Vous avez dit pointeurs ?

Lesvariablesutilis´ees par un programme sont stock´ees en m´emoire `a uneadressedonn´ee.

Lespointeurspermettent de manipuler ces adresses directement. Ce sont des variables qui vont contenir une adresse m´emoire.

Dans quel but ? Exemples d’utilisation :

I modifier la valeur d’un param`etre d’une fonction

I allouer de la m´emoire dynamiquement

I cr´eer des structures complexes, autor´ef´erentes (listes chaˆın´ees)

I ...

Exemple

i n t i =2 , j =36 ,k =124;

i n t ∗l =& i ; 2

36 124 0x1234 0x1234

0x1238 0x123C 0x1240

i j k l Dans cet exemple, l contient l’adresse de la variable i.

(19)

D´eclaration et initialisation

I D´eclaration :on ajoute “*” au typede la donn´ee point´ee.

Exemples :int *i; char *c;

I L’adresse d’une variable est r´ecup´er´ee grˆace `a l’op´erateur

“&”. Exemple : i n t i =2;

i n t ∗l ; /∗ l est un p o i n t e u r sur e n t i e r ∗/ l =& i ; /∗ l p o i n t e sur i ∗/

I La valeur stock´ee en m´emoire `a l’adresse indiqu´ee par un pointeur peut ˆetre r´ecup´er´ee grˆace `al’op´erateur “*” (on parle ded´er´ef´erenciation). Ex :

i n t i =2;

i n t ∗l =& i ; /∗ l est un p o i n t e u r sur i ∗/

∗l =3; /∗ l a v a l e u r de i passe a 3 ∗/

Exemple : passage de param`etres `a une fonction

Passage par valeur void f (i n t n ) {

n=n+1;

}i n t main (void) { i n t i =2;

p r i n t f ( ” 1: i=%d ” , i ) ; f ( i ) ;

p r i n t f ( ” 2: i=%d ” , i ) ; }

Donne le r´esultat suivant :

1: i =2 2: i =2

Exemple : passage de param`etres `a une fonction

Passage par r´ef´erence void f (i n t ∗n ) {

∗n=∗n+1;

}

i n t main (void) { i n t i =2;

p r i n t f ( ” 1: i=%d ” , i ) ; f (& i ) ;

p r i n t f ( ” 2: i=%d ” , i ) ; }

Donne le r´esultat suivant :

1: i =2 2: i =3

Le pointeur NULL

NULL (ou 0) est une valeur sp´eciale pour un pointeur.

C’est une valeur, par d´efinition, qui ne pointe pas sur une zone m´emoire valide.

Peut-ˆetre utilis´e pour indiquer qu’un pointeur n’est pas encore initialis´e.

Exemple d’utilisation : i n t ∗p=NULL ;

. . .

i f( p==NULL) {

p r i n t f ( ” p n ’ a pas ete i n i t i a l i s e !\n ” ) ; }

(20)

Les pointeurs de pointeurs de ...

i n t i =3;

i n t ∗j =& i ; i n t ∗∗k=& j ;

3 0x1234 0x1238 0x1234

0x1238

i j k k est un pointeur de pointeur sur entier. Il contient donc l’adresse d’une variable contenant l’adresse d’une variable de type int.

Il est ´egalement possible de d´efinir des pointeurs de pointeurs de pointeurs sur une type donn´e et ainsi de suite...

Astuce

Pour retrouver `a quoi correspond un pointeur, il fautlire les

´el´ements composant sa d´eclaration de droite `a gauche:

I int *iest un pointeur (*) sur entier (int).

I const int *iest un pointeur (*) sur entier constant (const int).

I char **iest un pointeur sur un pointeur sur char

Types

I Les pointeurs sonttyp´es: i n t i =3;

f l o a t ∗p=& i ; /∗ genere un warning ∗/

I Pointeur g´en´erique :void *.

I pointeur non typ´e

I ne peut ˆetre d´er´ef´erenc´e

I doit ˆetre cast´e en un type d´efini i n t i =3;

void ∗p=& i ; i n t ∗q=p ;

∗p=4; /∗ i n t e r d i t ∗/

∗q=4; /∗ a u t o r i s e ∗/

Addition/soustraction d’un entier `a un pointeur

i n t i =3;

i n t ∗p=& i ; p=p+1;

ATTENTION : en pratique, lorsque l’on faitp=p+1on ajoute sizeof(int) `a p...

Sur IA32, on ajoute en fait 4 `a p. Si p est un pointeur sur double,p=p+1incr´emente p de 8.

Simplifie l’utilisation des pointeurs,p+1pointe sur l’´el´ement directement apr`es celui point´e par p, sans avoir besoin de se pr´eoccuper de sa taille.

(21)

Manipulation de la donn´ee point´ee

Le pointeur d´er´ef´erenc´e peut se manipuler comme la donn´ee point´ee :

i n t i =3;

i n t ∗j =& i ;

(∗j ) + + ; /∗ incremente i de 1 ∗/

∗( j + + ) ; /∗ incremente j de 1 ∗/

∗j = ∗j / 10 /∗ d i v i s e i par 10 ∗/

Affectation entre pointeurs

i n t i =3;

i n t ∗j =& i ; i n t ∗k ; k= j ;

Il est possible d’affecter `a un pointeur la valeur d’un autre pointeur de mˆeme type.

Tableaux & Pointeurs

Une r´ef´erence `a un tableau est ´equivalente `a un pointeur constant sur son premier ´el´ement !

i n t a [ 1 0 ] ; i n t ∗b=a ;

a⇐⇒b⇐⇒&a[0]⇐⇒&b[0]

Exception :

I sizeof(a)6=sizeof(&a[0]). sizeof(a) rend la taille du tableau, soit 10*sizeof(int) alors que sizeof(&a[0]) rend la taille d’un pointeur sur entier.

Tableaux & Pointeurs

Cons´equence : on ne peut pas connaitre la taille d’un tableau pass´e par argument

i n t f (i n t a [ 1 0 ] ) { unsigned i n t i ; for ( i =0; i<10; i ++) {

a [ i ]+=1;

} }

i n t main (void) {

i n t b [ 5 ] ={0 , 0 , 0 , 0 , 0}; f ( b ) ; /∗POSSIBLE ! !∗/

/∗ e r r e u r non detectee . . . ∗/ }

int f(int a[10])est

´equivalent `aint f(int *a). La taille sp´ecifi´ee n’est pas prise en compte !

Si la taille doit ˆetre connue dans la fonction, il faut la passer en param`etre.

(22)

Tableaux & Pointeurs

La notation avec [] est ´equivalente `a l’addition de l’indice : i n t a [ 1 0 ] ;

i n t ∗b=a ;

a[2]⇐⇒ ∗(a+2)⇐⇒b[2]⇐⇒ ∗(b+2)

Allocation dynamique

I Les pointeurs sont utilis´es pour manipuler la m´emoire

I Ils peuvent manipuler des donn´ees d´ej`a allou´ees

I Est-il possible d’allouerdynamiquementde la m´emoire ?

I Exemple d’utilisation : d´eclaration d’un tableau de taille variable

allocation de la m´emoire : malloc

#include <stdlib.h>

void *malloc(size t taille)

I Argument :tailleen octets

I size t: entier non sign´e

I Valeur renvoy´ee de typevoid *

I D´eclar´e dansstdlib.h

I ATTENTION :la zone m´emoire allou´ee n’est pas initialis´ee...

malloc : exemple

Allocation d’un tableau de taille donn´ee par une variable : i n t ∗allouerTableau (i n t t a i l l e ) {

i n t ∗tab =(i n t ∗) malloc ( t a i l l e∗sizeof(i n t ) ) ; i f ( tab==NULL) {

p r i n t f ( ” Probleme d ’ a l l o c a t i o n\n ” ) ; return NULL ;

}unsigned i n t i ;

for ( i =0; i<t a i l l e ; i ++) { tab [ i ] = 0 ;

/ / ou de facon e q u i va l e n t e : / / ∗( tab+ i )=0

}return tab ; }

(23)

autres fonctions d’allocation : realloc

#include <stdlib.h>

void *realloc(void *adr, size t taille)

I Changement de taille d’un emplacement m´emoire pr´ec´edemment allou´e

I La nouvelle taille esttaille, elle peut ˆetre inf´erieure ou sup´erieure

I Les octets conserv´es de l’ancien tableau sont identiques

I L’emplacement en m´emoire peut changer

I Exemple :

i n t n=10 ,m, tab=malloc ( nsizeof(i n t) ) , tab2 ; . . . / code i n i t i a l i s a n t m /

tab2= r e a l l o c ( tab ,m) ; i f( ! tab2 ) {

p r i n t f ( ” Erreur de r e a l l o c a t i o n\n ” ) ; e x i t ( 1 ) ;

}tab=tab2 ; . . .

Lib´eration de la m´emoire : free

#include <stdlib.h>

void free(void *adr)

I Lib´eration de la m´emoire

I Lib`ere, d’un coup, un bloc pr´ec´edemment allou´e par malloc, calloc ou realloc

I Il n’est pas possible de ne lib´erer la m´emoire que partiellement

I free(NULL)ne fait rien

I Lib´erer deux fois de suite la m´emoire conduit `a un comportement ind´etermin´e : g´en´eralement un seg fault...

Copie de blocs m´emoire : memcpy

#include <string.h>

void *memcpy(void *restrict s1, const void

*restrict s2, size t n);

I Copienoctets `a partir de l’adresse contenue dans le pointeurs2vers l’adresse stock´ee danss1

I Remarque :s2doit pointer vers une zone m´emoire de taille suffisante.

I la fonction renvoie la valeur des1

(24)

UE C avanc´e

cours 4: Fichiers et structures

Jean-Lou Desbarbieux et St´ephane Doncieux UMPC 2013/2014

Sommaire

Fichiers

Structures

Fichiers : principes

I Fichiers manipul´es au travers d’une structure (FILE)

I Cette structure est initialis´ee par une fonction d’ouverture de fichier, et est d´etruite par une fonction defermeturede fichier

Exemple :

#include<s t d i o . h>

i n t main ( ) {

FILE m o n f i c h i e r ; i n t x , y , z ;

i f ( ( m o n f i c h i e r = fopen ( ” f i c h i e r . t x t ” , ” r ” ))==NULL) { p r i n t f ( ” Erreur a l ’ ouverture de f i c h i e r . t x t\n ” ) ; return 1;

}f s c a n f ( m o n f i c h i e r , ”%d %d %d ” ,&x ,&y ,& z ) ; p r i n t f ( ” Valeurs lues : %d %d %d\n ” , x , y , z ) ; f c l o s e ( m o n f i c h i e r ) ;

return 0;

}

Ouverture d’un fichier : fopen/fclose

I FILE *fopen(const char *nom fichier, const char *mode): ouvre le fichier selon le mode indiqu´e (“r”,

“w”, “a”,...)

I int fclose(FILE *flux): vide ´eventuellement le tampon de lecture/´ecriture, lib`ere la m´emoire

correspondante et ferme le fichier

(25)

Lecture/´ecriture format´ee

I int fscanf(FILE *flux,const char *format, ...): lecture de donn´ees `a partir d’un format depuis un fichier

I int fprintf(FILE *flux, const char

*format,...): ´ecriture de donn´ees selon un format sp´ecifi´e dans un fichier

I int fputc(int c, FILE *flux): ´ecrit un caract`ere dans un fichier

I int fgetc(FILE *flux): lit un caract`ere depuis un fichier

I char * fgets(char *buffer, int n, FILE

*flux): lit une ligne dans un fichier (longueur maximale=n)

Exemple

#include <s t d i o . h>

i n t main ( ) { FILE src , dest ; i n t car ;

i f ( ( src = fopen ( ” source . t x t ” , ” r ” ))==NULL) { p r i n t f ( ” Erreur a l ’ ouverture de source . t x t\n ” ) ; return 1;

}i f ( ( dest= fopen ( ” d e s t i n a t i o n . t x t ” , ”w” ))==NULL) { p r i n t f ( ” Erreur a l ’ ouverture de d e s t i n a t i o n . t x t\n ” ) ; return 1;

}car = f g e t c ( src ) ; while ( car !=EOF) {

f p u t c ( car , dest ) ; car = f g e t c ( src ) ; }f c l o s e ( src ) ; f c l o s e ( dest ) ; return 0;

}

Lecture d’un fichier ligne `a ligne

Lecture d’un fichier contenant 3 entiers par ligne avecfgetset sscanf

#include<s t d i o . h>

#define LONGUEURLIGNE 128 i n t main ( ) {

FILE src ;

i f ( ( src = fopen ( ” source . t x t ” , ” r ” ))==NULL) { p r i n t f ( ” Erreur a l ’ ouverture de source . t x t\n ” ) ; return 1;

}char b u f f e r [LONGUEURLIGNE ] ;

char ∗res= f g e t s ( b u f f e r , LONGUEURLIGNE, src ) ; i n t a , b , c ;

while ( res != NULL) {

sscanf ( b u f f e r , ” %d %d %d ” ,&a , &b , &c ) ; res= f g e t s ( b u f f e r , LONGUEURLIGNE, src ) ;

p r i n t f ( ” Lu l e s e n t i e r s a=%d , b=%d , c=%d\n ” ,a , b , c ) ; }

f c l o s e ( src ) ; return 0;

}

La lecture binaire

s i z e t fread (void p t r , s i z e t size , s i z e t nmemb, FILE ∗stream ) ;

La fonction fread lit nmemb ´el´ements de donn´ees, chacun d’eux repr´esentant size octets de long, depuis le flux point´e par stream, et les stocke `a l’emplacement point´e par ptr.

Les donn´ees peuvent ˆetre de type quelconque,ptrpeut ˆetre un pointeur sur un int, un float, une struct... Il peut ˆetre un tableau de donn´ees d’un type quelconque.

ATTENTION: il n’y a aucune esp`ece de format, les donn´ees

´ecrites dans le fichier sont recopi´ees directement en m´emoire.

(26)

La lecture binaire

FILE f i c h i e r ;

/ ouverture du f i c h i e r /

i f ( ( f i c h i e r =fopen ( n o m f i c h i e r , ” rb ” ))==NULL) {

p r i n t f ( ” Erreur l o r s de l a l e c t u r e de %s\n ” , n o m f i c h i e r ) ; e x i t ( 1 ) ;

}i n t i ;

i n t n b l u = fread (& i , sizeof(i n t) , 1 , f i c h i e r ) ; i f ( n b l u == 1) {

p r i n t f ( ‘ ‘ Lecture OK\n ’ ’ ) ; }else {

p r i n t f ( ‘ ‘ Lecture KO\n ’ ’ ) ; }

L’´ecriture binaire

s i z e t f w r i t e (const void p t r , s i z e t size , s i z e t nmemb, FILE ∗stream ) ;

La fonctionfwrite ´ecritnmemb ´el´ements de donn´ees, chacun d’eux repr´esentantsizeoctets de long, dans le flux point´e par stream, apr`es les avoir lus depuis l’emplacement point´e par ptr.

L’´ecriture binaire

i n t tab [ 1 0 ] ;

/ I n i t i a l i s a t i o n de tab / . . .

/ ouverture du f i c h i e r ∗/

i f ( ( f i c h i e r =fopen ( n o m f i c h i e r , ”wb” ))==NULL) {

p r i n t f ( ” Erreur l o r s de l ’ e c r i t u r e de %s\n ” , n o m f i c h i e r ) ; e x i t ( 1 ) ;

}

/ ATTENTION : pas de ’& ’ car tab est un tableau ! / f w r i t e ( tab ,sizeof(i n t) , 1 0 , f i c h i e r ) ;

/ fermeture du f i c h i e r ∗/

f c l o s e ( f i c h i e r ) ;

Structures

(27)

Vous avez dit structures ?

I Les structures sont destypes compos´esd´efinis par le programmeur.

I Les structures regroupent `a l’int´erieur d’une mˆeme variable des variabless´emantiquement li´ees. Exemple : une fiche d’un r´epertoire contient le nom, le pr´enom, l’adresse, le num´ero de t´el´ephone...

Exemple simple

Point dans un espace 3D : struct p o i n t {

f l o a t x ; f l o a t y ; f l o a t z ; };

struct p o i n t p1 ; p1 . x = 1 2 . 0 ; p1 . y = 2 4 . 2 ; p1 . z = 4 2 . 0 ;

D´eclaration

struct <nom de type>

{ type1 var1 ; type2 var2 ;

. . .

typen varn ; };

Utilisation

I D´eclaration d’une variable du type d´efini

struct <nom de type> <nom de variable>;

Exemple :struct point p1;

struct point *pp1;

ATTENTION,il faut bien pr´eciser le mot-cl´estruct

I R´ecup´eration d’un champ : var.<nom du champ>

Exemple :p1.x=44.20;

pvar-><nom du champ>

Exemple :pp1->x=44.20;

(28)

typedef

I D´efinition de types synonymes. Exemple : typedef i n t e n t i e r ;

e n t i e r i =3;

I cas des tableaux :

typedef i n t vect [ 3 ] ; vect v1 , v2 ;

I cas des struct

typedef struct p o i n t {i n t x ;i n t y ;} p o i n t ; p o i n t A ;

Espaces de nom

I On ne peut pas utiliser deux fois un mˆeme nom dans une structure :

struct bidon { i n t var1 ;

f l o a t var1 ; /∗ INTERDIT ∗/ };

I Par contre il n’y a pas collision entre les noms de diff´erentes structures :

struct f i c h e { . . .

unsigned i n t i d ; . . .

};

struct c l i e n t { . . .

unsigned i n t i d ; . . .

};

Initialisation

Initialisation semblable `a celle de tableaux : typedef struct p o i n t {

f l o a t x ; f l o a t y ; f l o a t z ; } p o i n t ;

p o i n t p={ 1.0 , 2.0 , 3 . 0};

Affectation entre structures

Possibilit´e de copier directement une structure par affectation : p o i n t A={12 ,4 ,5},B ;

/∗ p o i n t equiv . a s t r u c t p o i n t ∗/

B=A ; ´equivalent `a B . x=A . x ;

B . y=A . y ; B . z=A . z ; ATTENTIONaux pointeurs ...

(29)

Tableaux et structures

Tableaux dans une structure

struct personne { char nom [ 3 0 ] ; char prenom [ 3 0 ] ;

unsigned i n t nb commande ; unsigned i n t n commande [ 1 0 ] ; };

. . .

struct personne c l i e n t 1 ={” Dupond ” , ” A l b e r t ” ,0 , {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0}};

. . .

c l i e n t 1 . n commande [ c l i e n t 1 . nb commande ] = 3406;

c l i e n t 1 . nb commande++;

Tableaux de structure

struct personne c l i e n t s [ 1 0 0 ] ; . . .

c l i e n t s [ 2 0 ] . n commande [ c l i e n t s [ 2 0 ] . nb commande ] = 4807;

c l i e n t s [ 2 0 ] . nb commande++;

Structures dans une structure

struct date {

unsigned char j o u r ; unsigned char mois ; unsigned i n t annee ; };

struct personne { char nom [ 3 0 ] ; char prenom [ 3 0 ] ;

struct date date naissance ; };

. . .

struct personne c l i e n t ={” Dupond ” , ” A l b e r t ” , {24 ,5 ,1950}};

i f ( c l i e n t . date naissance . annee>1940) { . . .

}

Structure et pointeurs

typedef struct personne { char nom ;

char prenom ; } personne ;

personne p1 , p2 ;

p1 . nom = (char ) malloc ( 7 + 1 ) ; s t r c p y ( p1 . nom, ” Deckard ” ) ; p1 . prenom = strdup ( ” Rick ” ) ;

/ / strdup e q u i v a l e n t a malloc puis s t r c p y p2=p1 ; / / cela f a i t quoi ?

p r i n t f ( ” p2 . nom=%s p2 . prenom=%s\n ” , p2 . nom, p2 . prenom ) ; f r e e ( p1 . nom ) ;

f r e e ( p1 . prenom ) ;

/ / Quel est l e r e s u l t a t de cet appel ?

p r i n t f ( ” p2 . nom=%s p2 . prenom=%s\n ” , p2 . nom, p2 . prenom ) ;

(30)

UE C avanc´e cours 5: Entr´ees/sorties

Jean-Lou Desbarbieux et St´ephane Doncieux UMPC 2013/2014

Sommaire

Chaˆınes de caract`eres : le retour...

Entr´ees/sorties

Chaˆınes de caract`eres : le retour...

Retour sur strlen

s i z e t m y s t r l e n (const char ∗s ) {

}

(31)

Retour sur strcpy

char ∗my strcpy (char ∗dest , const char ∗src ) {

}

Quelques autres fonctions utiles : strdup

#include <s t r i n g . h>

char ∗strdup (const char ∗s1 ) ;

Alloue une nouvelle chaˆıne de caract`ere de longueur

strlen(s1)+1et l’initialise avec la chaˆınes1(´equivalent `a malloc+strcpy)

ATTENTION : il faut bien penser `a lib´erer par unfreela chaˆıne de caract`eres ainsi cr´e´ee.

Quelques autres fonctions utiles : strcat

#include <s t r i n g . h>

char ∗s t r c a t (char ∗dest , const char ∗src ) ; char ∗s t r n c a t (char ∗dest , const char ∗src ,

s i z e t n ) ;

Ajoute la chaˆıne de caract`ere src `a la fin de dest.

Renvoie un pointeur sur dest.

Entr´ees/sorties

(32)

Comment faire ...

... pour ´ecrire des donn´ees `a l’´ecran : m´ethode 1

I utiliser une fonction transformant les variables `a ´ecrire directement en chaˆınes de caract`eres (printf) m´ethode 2

I ´ecrire caract`eres par caract`eres

Comment faire ...

... pour lire des donn´ees tap´ees depuis le clavier : m´ethode 1

I utiliser une fonction de lecture traduisant directement la chaˆıne lue dans le(s) type(s) souhait´e(s)

m´ethode 2

I lire caract`eres par caract`eres

Comment faire ...

... pour lire des donn´ees depuis un fichier : m´ethode 1

I ouvrir le fichier

I utiliser une fonction de lecture traduisant directement la chaˆıne lue dans le(s) type(s) souhait´e(s)

I fermer le fichier m´ethode 2

I ouvrir le fichier

I utiliser une fonction de lecture caract`eres par caract`eres

I fermer le fichier m´ethode 3

I ouvrir le fichier

I utiliser une fonction de lecture copiant les donn´ees brutes depuis le fichier vers la m´emoire (lecture dite binaire)

I fermer le fichier

Comment faire ...

... pour ´ecrire des donn´ees depuis un fichier : m´ethode 1

I ouvrir le fichier

I utiliser une fonction d’´ecriture transformant les variables `a

´ecrire directement en chaˆınes de caract`eres

I fermer le fichier m´ethode 2

I ouvrir le fichier

I utiliser une fonction d’´ecriture caract`eres par caract`eres

I fermer le fichier m´ethode 3

I ouvrir le fichier

I utiliser une fonction d’´ecriture copiant la m´emoire vers le fichier sans transformation (´ecriture dite binaire)

I fermer le fichier

(33)

Retour sur printf

I Affichage d’un message `a l’´ecran.

I Renvoie un entier : nombre de caract`eres ´ecrits

I Message sp´ecifi´e par unformatcontenant descodes de format

I Exemples :

double p i =3.141592653589793;

p r i n t f ( ” Pi : %f\n ” , p i ) ;

p r i n t f ( ” Pi avec 2 decimales : %.2 f , 4 decimales : %.4 f\n ” , pi , p i ) ;

p r i n t f ( ” 2 Pi : %f\n ” ,2∗p i ) ;

scanf

I Lecture de donn´ees tap´ees au clavier

I Renvoie un entier : nombre d’entit´es lues

I Exploite ´egalement un format avec des codes de format f l o a t x ;

i n t n ;

scanf ( ”%f %d ” ,&x ,&n ) ;

scanf

ATTENTION: lors de la lecture, seul ce qui est demand´e est lu ! Exemple pathologique :

char c ;

scanf ( ”%c ” ,&c ) ;

p r i n t f ( ” Char l u : %c\n ” , c ) ; scanf ( ”%c ” ,&c ) ;

p r i n t f ( ” Char l u : %c\n ” , c ) ; Que fait le programme ?

Lecture d’un seul caract`ere ! Le 2eme ´etant le retour `a la ligne...

Solution ajouter un ’ ’ avant le premier code de format : scanf ( ” %c ” ,&c ) ;

→l’espace indique que lescanfdoit ”consommer” tous les espaces, retour `a la ligne et autre tabulation avant de lire quoi que ce soit...

scanf

ATTENTION: lors de la lecture, seul ce qui est demand´e est lu ! Exemple pathologique :

char c ;

scanf ( ”%c ” ,&c ) ;

p r i n t f ( ” Char l u : %c\n ” , c ) ; scanf ( ”%c ” ,&c ) ;

p r i n t f ( ” Char l u : %c\n ” , c ) ; Que fait le programme ?

Lecture d’un seul caract`ere ! Le 2eme ´etant le retour `a la ligne...

Solution ajouter un ’ ’ avant le premier code de format : scanf ( ” %c ” ,&c ) ;

→l’espace indique que lescanfdoit ”consommer” tous les espaces, retour `a la ligne et autre tabulation avant de lire quoi que ce soit...

(34)

Quelques codes de format courants

I %d : entier

I %u : entier non sign´e

I %f : flottant

I %c : caract`ere

I %s : chaˆıne de caract`eres (ATTENTION...)

I %p : pointeur

getchar/putchar

I int getchar(): lecture d’un caract`ere. Renvoie le code du caract`ere lu,EOFsi probl`eme. ´Equivalent `a

scanf("%c",&c lu)

I int putchar(int c): ´ecriture d’un caract`ere. Renvoie le code du caract`ere ´ecrit,EOFsi probl`eme. ´Equivalent `a printf("%c",c a ecrire)

I Fonctions plus simples et plus rapides

getchar

ATTENTION: mˆeme probl`eme sur legetcharque surscanf Exemple de solution :

i n t c ; do

c=getchar ( ) ; while ( c== ’\n ’ ) ;

ou pour ´eviter aussi espaces, retours `a la ligne et autres tabulations :

#include <ctype . h>

i n t c ; do

c=getchar ( ) ; while ( isspace ( c ) ) ;

Structures et entr´ees/sorties

typedef struct p o i n t { f l o a t x ;

f l o a t y ; f l o a t z ; } p o i n t ;

p o i n t p1={ 1.0 , 2.0 , 3.0}, p2 ; FILE ∗f =fopen ( ” m o n f i c h i e r ” , ”wb” ) ;

f w r i t e (&p1 ,sizeof( p o i n t ) , 1 , f ) ; f c l o s e ( f ) ;

f =fopen ( ” m o n f i c h i e r ” , ” rb ” ) ; fread (&p2 ,sizeof( p o i n t ) , 1 , f ) ;

(35)

Structures et entr´ees/sorties

/ / Avec un tableau ? typedef struct c o n t a c t {

char nom [ 3 0 ] ; char prenom [ 3 0 ] ; } contact ;

contact c1={” T y r e l l ” , ” Eldon ” }; FILE ∗f =fopen ( ” m o n f i c h i e r ” , ”wb” ) ;

f w r i t e (&c1 ,sizeof( contact ) , 1 , f ) ; f c l o s e ( f ) ;

/ / ca marche !

/ / Que c o n t i e n t l e f i c h i e r ?

Structures et entr´ees/sorties

/ / Avec des p o i n t e u r s ? typedef struct c o n t a c t {

char ∗ nom ; char ∗ prenom ; } contact ;

contact c1 ;

c1 . nom = strdup ( ” T y r e l l ” ) ; c1 . prenom = strdup ( ” Eldon ” ) ;

FILE ∗f =fopen ( ” m o n f i c h i e r ” , ”wb” ) ; f w r i t e (&c1 ,sizeof( contact ) , 1 , f ) ; f c l o s e ( f ) ;

/ / qu ’ est−ce qui est e c r i t ?

Structures et entr´ees/sorties

/ / Avec des p o i n t e u r s ? E c r i t u r e : typedef struct c o n t a c t {

char ∗ nom ; char ∗ prenom ; } contact ;

contact c1 ;

c1 . nom = strdup ( ” T y r e l l ” ) ; c1 . prenom = strdup ( ” Eldon ” ) ; FILE ∗f =fopen ( ” m o n f i c h i e r ” , ”w” ) ;

f p r i n t f ( f , ”%s\n ” , c1 . nom ) ; f p r i n t f ( f , ”%s\n ” , c1 . prenom ) ; f c l o s e ( f ) ;

/ / quel est l e contenu du f i c h i e r ?

Structures et entr´ees/sorties

/ / Avec des p o i n t e u r s ? Lecture contact c2 ;

FILE ∗f =fopen ( ” m o n f i c h i e r ” , ” r ” ) ; char b u f f e r [ 1 2 8 ] ;

f g e t s ( b u f f e r ,128 , f ) ; / / pour enlever l e ’\n ’

b u f f e r [ s t r l e n ( b u f f e r )−1]= ’\0 ’ ; c2 . nom= strdup ( b u f f e r ) ;

f g e t s ( b u f f e r ,128 , f ) ; / / pour enlever l e ’\n ’

b u f f e r [ s t r l e n ( b u f f e r )−1]= ’\0 ’ ; c2 . prenom= strdup ( b u f f e r ) ; f c l o s e ( f ) ;

(36)

UE C avanc´e

cours 6: r´evisions et exercices

Jean-Lou Desbarbieux et St´ephane Doncieux UMPC 2012/2013

Quizz pointeurs

Que font les instructions suivantes : i n t n =42;

i n t ∗m=n ;

∗m = 2 4 ;

Quizz pointeurs

Que font les instructions suivantes : i n t n =42;

i n t ∗m=n ;

∗m = 2 4 ;

→ erreur de segmentation ! ! Il manque un ’&’ `a la 2eme ligne :

i n t n =42;

i n t ∗m=&n ; // & a a j o u t e r

∗m = 2 4 ; R´esultat ?

Quizz pointeurs

Que font les instructions suivantes : i n t t [ 4 ] ={0 , 1 , 2 , 3};

i n t ∗m=t ;

∗(m++) += 3 ;

∗(++m) += 4 ; (∗m)++;

(37)

Que fait la fonction ? Comment y fait-on appel ?

v o i d m y s t e r e (i n t ∗n , i n t m) { i f( (m= = 0 )||(m==1)) {

∗n =1;

} e l s e {

m y s t e r e ( n ,m−1);

∗n ∗= m;

} }

Initialiser le contenu d’un tableau dans une fonction

I Possible ?

I Si oui :

I quel prototype ?

I quelle fonction ?

I comment utiliser la fonction ?

Initialiser le contenu d’un tableau dans une fonction

v o i d i n i t i a l i s e r (i n t ∗tab , i n t n , i n t v a l =0) { unsigned i n t i ;

f o r ( i =0; i<n ; i ++) { t a b [ i ]= v a l ; }

}

Allouer un tableau dans une fonction

I Possible ?

I Si oui :

I quel prototype ?

I quelle fonction ?

(38)

Allouer un tableau dans une fonction

i n t ∗a l l o u e r T a b l e a u (i n t n ) {

i n t ∗t a b =(i n t ∗) m a l l o c ( n∗s i z e o f(i n t ) ) ; i f ( t a b == NULL) {

p r i n t f ( ” Probleme p e n d a n t l ’ a l l o c a t i o n\n” ) ; }

r e t u r n t a b ; }

Changer la taille d’un tableau dans une fonction

I Possible ?

I Si oui :

I quel prototype ?

I quelle fonction ?

Changer la taille d’un tableau dans une fonction

i n t ∗c h a n g e r T a i l l e T a b l e a u (i n t ∗tab , i n t n ) { i n t ∗t a b 2 =(i n t ∗) r e a l l o c ( tab , n∗s i z e o f(i n t ) ) ; i f ( t a b 2 == NULL) {

p r i n t f ( ” Probleme p e n d a n t l ’ a l l o c a t i o n\n” ) ; r e t u r n t a b ;

}

r e t u r n t a b 2 ; }

Changer la taille d’un tableau dans une fonction (bis)

Autre ´ecriture : renvoievoid et modifie le param`etre transmettant le tableau.

v o i d c h a n g e r T a i l l e T a b l e a u 2 (i n t ∗∗tab , i n t n ) { // a t t e n t i o n , t a b e s t un ’ i n t ∗∗’

i n t ∗t a b 2 =(i n t ∗) r e a l l o c (∗tab , n∗s i z e o f(i n t ) ) ; i f ( t a b 2 == NULL) {

p r i n t f ( ” Probleme p e n d a n t l ’ a l l o c a t i o n\n” ) ; r e t u r n;

}

∗t a b=t a b 2 ; }

(39)

Structure

s t r u c t p o i n t { f l o a t x ; f l o a t y ; f l o a t z ; };

i n t main ( ) {

p r i n t f ( ” s i z e o f ( p o i n t)=%d\n” , s i z e o f(s t r u c t p o i n t ) ) ; }

Qu’est-ce qui est affich´e `a l’´ecran ?

Structure

s t r u c t p o i n t { f l o a t x ; f l o a t y ; f l o a t z ; };

i n t main ( ) {

p r i n t f ( ” s i z e o f ( p o i n t)=%d\n” , s i z e o f(s t r u c t p o i n t ) ) ; r e t u r n 0 ;

}

Qu’est-ce qui est affich´e `a l’´ecran ? sizeof(struct point)=12

Structure et passage de param`etres

v o i d f (s t r u c t p o i n t p ) { p . x =42;

p . y =24;

p . z =12;

}

i n t main ( ) {

s t r u c t p o i n t p ={1 , 2 , 3}; f ( p ) ;

p r i n t f ( ”p . x=%f p . y=%f p . z=%f\n” , p . x , p . y , p . z ) ; r e t u r n 0 ;

}

Qu’est-ce qui est affich´e `a l’´ecran ?

Références

Documents relatifs

Perdre ses photos de vacances : ¸ca n’a pas de

• Ex ´ecuter les t ˆaches de base de la gestion des donn ´ees, telle que l’insertion, la modification et la suppression de donn ´ees des tables. • Effectuer des requ ˆetes

La boucle tant que est utilis ´ee lorsque le nombre d’it ´erations n’est pas connu `a l’avance: elle ex ´ecute le bloc d’instructions tant que la condition reste vraie.

(Affectation parallèle, - ) Déterminer les contenus des variables après interprétation de la suite d'instructions.. (Échange des contenus de deux variables, ♥) On suppose que

Au total, le lecteur habile dispose d’une panoplie d’automatismes qui lui per- mettent de reconnaître les mots presque toujours sans y penser : automatismes dans la

Sauvegarder votre script R : En activant la fenˆ etre qui le contient (celle du haut ` a gauche : le curseur doit clignoter en noir) puis en allant de nouveau dans la barre de menu

La variable 'var' pour la fonction fwrite sera ni plus ni moins qu'une suite d'octets en mémoire, une utilisation de cette dernière va inscrire dans un fichier les octets

• Ex ´ecuter les t ˆaches de base de la gestion des donn ´ees, telle que l’insertion, la modification et la suppression de donn ´ees des tables. • Effectuer des requ ˆetes