La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Les pointeurs L'opérateur &.

Présentations similaires


Présentation au sujet: "Les pointeurs L'opérateur &."— Transcription de la présentation:

1 Les pointeurs L'opérateur &.
L'opérateur adresse & retourne l'adresse d'une variable en mémoire. Exemple : int i = 5; printf'(" Voici i: %d\n",i); printf'(" Voici son adresse : %p\n",&i); Pour afficher l'adresse d'une variable ont utilise généralement %p qui affiche l'adresse en hexadécimal (4 octets). L'adresses d'une variable correspond à l'adresse de début de la variable dans la mémoire. Voici i: 5 Voici son adresse : 0028FF40

2 Les pointeurs L'opérateur &.
Adresse Contenu Identifiant . . . 0028FF3F ? 0028FF40 5 Variable i 0028FF41 i 0028FF42 0028FF43 0028FF44 15 Variable B 0028FF45 B 0028FF46 0028FF47 0028FF48 0028FF49 0028FF4A Les pointeurs L'opérateur &. L'opérateur adresse & retourne l'adresse d'une variable en mémoire. Exemple : int i = 5; printf'(" Voici i: %d\n",i); printf'(" Voici son adresse : %p\n",&i); Pour afficher l'adresse d'une variable ont utilise généralement %p qui affiche l'adresse en hexadécimal (4 octets). L'adresses d'une variable correspond à l'adresse de début de la variable dans la mémoire. Voici i: 5 Voici son adresse : 0028FF40

3 Les pointeurs Qu'est-ce qu'un pointeur? Adresse de X Valeur de X
Contenu Identifiant . . . 0028FF3F ? 0028FF40 44 *X 0028FF41 FF 0028FF42 28 0028FF43 0028FF44 15 X 0028FF45 0028FF46 0028FF47 0028FF48 0028FF49 0028FF4A Les pointeurs Qu'est-ce qu'un pointeur? C'est une variable qui contient l'adresse d'une autre variable. On dit que le pointeur pointe sur la variable. Exemple : int *P; P = &X; Adresse de X Valeur de X pointeur Variable

4 Les pointeurs Déclaration d'un pointeur.
Une variable de type pointeur se déclare à l'aide de l'objet pointé précédé du symbole * (opérateur d'indirection). Exemple : int *pi; // pi est un pointeur pointant sur un entier char *pc; // pc est un pointeur pointant sur un char float *pf; // pf est un pointeur pointant sur un float L'opérateur * désigne le contenu de l'adresse, int *pi,X; // pi est un pointeur pointant sur un entier pi = &X; // on initialise le pointeur pi *pi = 5; // On charge l'entier pointé par pi avec la // valeur 5, c'est en fait X

5 Les pointeurs L'arithmétique des pointeurs.
Contenu . . . pi 05 00 pi +1 ? pc 65 pc + 1 Les pointeurs L'arithmétique des pointeurs. On déplace un pointeur dans la mémoire à l'aide des opérateurs d'addition, de soustraction, d'incrémentation, de décrémentation. On ne peut le déplacer que d'un nombre de cases mémoire multiple de la taille de la variable en mémoire. Exemple : int *pi; char *pc; *pi = 5; *pc = 'A';

6 Les pointeurs L'arithmétique des pointeurs. Exemple :
int *pi; // pi pointe sur un objet de type entier (4 octets) char *pc; // pc pointe sur un objet de type char (1 octet) float *pf; // pf pointe sur un objet de type float (4 octets) *pi = 145; // 145 est le contenu de la case mémoire pi *pi+1 = 200; // 200 est de contenu des cases mémoires 4 cases // après pi *pi+2 = 500; // 500 est le contenu des cases mémoires 8 cases // après pi *pc = 'A'; // la case mémoire pc contient le code ASCII de A = 65 pc--; // on décrémente la valeur du pointeur pc de 1 *pf = 1.5; // 1,5 est stocké dans la case mémoire pf et les 4 // suivantes pf++; // on incrémente la valeur du pointeur pf de 4 cases //mémoires qui correspond à la taille d'un float

7 Les pointeurs L'arithmétique des pointeurs. Exemple : int *pi,*qi,i;
pi = qi; // autorisé i = pi + qi; // interdit : on ne peut pas additionner deux pointeurs // ça n'a pas de sens i = pi-qi; // autorisé : donne le nombre d'objets entre les deux // pointeurs I = pi*qi; // interdit : on ne peut pas multiplier deux pointeurs

8 Les pointeurs Les pointeurs avec une fonction.
Exemple : Fonction qui prend un pointeur en paramètre d'entrée int carre(int *A) { int Res; Res = (*A) * (*A); // équivalent à : *A**A ou * A * * A return (Res); } Void main(void) int *X,Y; X = (int*)malloc(1*sizeof(int)); // initialisation du pointeur sur le tas // (heap) zone mémoire réservée aux // données *X = 2; Y = carre(X);

9 Les pointeurs ! Les pointeurs avec une fonction.
Exemple : Fonction qui prend un pointeur en paramètre d'entrée et retourne un pointeur. int *carre(int *A) { int *Res; Res = (int*)malloc(1*sizeof(int)); *Res = (*A) * (*A); // équivalent à : *A**A ou * A * * A return (Res); } Void main(void) int *X,*Y; X = (int*)malloc(1*sizeof(int)); Y = (int*)malloc(1*sizeof(int)); *X = 2; Y = carre(X); free(X);free(Y); // on libère la mémoire allouées aux pointeurs ! La mémoire allouée au pointeur Res n'est pas libérée …

10 Les pointeurs Les pointeurs avec une fonction.
Solution plus efficace : on passe en paramètre deux pointeurs. void carre(int *A, int *Res) { *Res = (*A) * (*A); // équivalent à : *A**A ou * A * * A } void main(void) int *X,*Y; X = (int*)malloc(1*sizeof(int)); Y = (int*)malloc(1*sizeof(int)); *X = 2; carre(X,Y); free(X);free(Y); // on libère la mémoire allouées aux pointeurs

11 Les pointeurs Les pointeurs et les tableaux.
Le langage C gère un tableau comme un pointeur à la différence près qu'il réserve un emplacement dimensionné par la déclaration. Exemple : int T[50]; int i, *pi, T[10]; pi = &i; // *pi représente i car pi pointe sur i *pi = 0; // c'est équivalent à i = 0 pi = &T[0]; // pi pointe maintenant sur le premier élément du tableau T // *pi représente T[0] *pi = 0; // équivalent à T[0] = 0;

12 Les pointeurs Les pointeurs et les tableaux.
La déclaration de T[50] réserve en mémoire 50 entiers, mais nous avons en même temps un nouveau pointeur initialisé sur le début du tableau. Exemple : int *pi, T[10],X; pi = T; // pi pointe sur le début du tableau soit le premier élément *T = 0; // c'est équivalent à T[0] = 0 *(T+2) = 5; // c'est équivalent à T[2] = 5 *(pi+5) = 0; // équivalent à T[5] = 0; Attention ! X = *(T +2) ; // c'est équivalent à X = T[2] : X  5 X = *T + 2; // c'est équivalent à X = T[0] + 2 : X X  2

13 Zone Mémoire inutilisables
Les pointeurs Les tableaux en mémoire : Tableaux de pointeurs Exemple : tableau 1 dimension char Tab1D[5]; Exemple : tableau 2 dimensions avec des chaines de caractères char Tab2D [5][7] ={"UN","DEUX","TROIS","QUATRE","CINQ"}; On alloue le maximum pour ne pas avoir de problèmes de débordement. Zone Mémoire inutilisables T O '\0' U N '\0' D E U X '\0' T R O I S '\0' Q U A T R E '\0' C I N Q '\0'

14 Les pointeurs Les tableaux en mémoire : Tableaux de pointeurs
On déclare un tableau de pointeurs dans lequel chaque pointeur désigne l'adresse d'un autre tableau Exemple : tableau 2 dimensions avec des chaines de caractères char *Tab2D [5] ; U N '\0' D E U X '\0' T R O I S '\0' Q U A T R E '\0' C I N Q '\0'

15 Les pointeurs Les tableaux en mémoire : Tableaux de pointeurs
Exemple : char *Tab[] = { "UN" , "DEUX", "TROIS", "QUATRE", "CINQ"} ; Tab[0]  pointe sur "UN" Tab[1]  pointe sur "DEUX" *Tab[0]  retourne sur 'U' de "UN" *( Tab[0] + 1)  retourne sur 'N' de "UN" *( Tab[1] + 2)  retourne sur 'U' de "DEUX" Attention: *Tab[4] + 1  retourne 'D' car *Tab[4]  'C' et 'C' + 1  'D'

16 Les pointeurs Pointeur de pointeur:
Un pointeur de pointeur est un pointeur pointant sur un pointeur, pointant sur un pointeur, , pointant sur une variable. Cela permet de gérer des tableaux sans aucune dimension prédéfinie. Exemple : tableau de chaine de caractère char *Tab[] = { "UN" , "DEUX", "TROIS", "QUATRE", "CINQ"} ; char **p // déclaration d'un pointeur de pointeur p = &Tab[0] // p pointe sur le début du tableau de chaines de caractères // *  chaine **  caractère *p  pointe sur "UN" *(p+1)  pointe sur "DEUX" **p  retourne sur 'U' de "UN" *(*p + 1)  retourne sur 'N' de "UN" *( *(p+1) + 2)  retourne sur 'U' de "DEUX"

17 Les pointeurs Allocation dynamique des pointeurs: malloc() calloc()
La déclaration d'un pointeur n'engendre pas de réservation en mémoire. Si on ne réserve pas d'emplacement mémoire, le pointeur risque de pointer sur d'autres variables : débordement de pointeur. La réservation ou allocation mémoire pour les pointeurs est réalisée généralement dans une zone réservé appelé le tas (heap). On parle alors d'allocation dynamique (modifiable à tout moment par programme). On gère l'allocation dynamique de la mémoire avec les fonctions suivantes: malloc() calloc() realloc() free()

18 Les pointeurs Allocation dynamique des pointeurs:
La fonction malloc : void *malloc(taille); Elle alloue un bloc de mémoire de taille octets sur le tas Elle renvoie un pointeur sur la zone de type void (valable pour tous les types) qu'il faut donc convertir en un type adapté aux données. Si l'allocation réussit, malloc renvoi un pointeur sur le bloc, elle échoue si taille = 0 ou s'il n'y a pas assez de place en mémoire. Dans ce cas elle retourne un pointeur nul : NULL Ex: int *p; p = (int *) malloc(10 * sizeof(int) ); // réservation pour 10 entiers if ( p== NULL) // test création du pointeur { printf("erreur d'allocation mémoire !!!"); // ici traitement de l'erreur … }

19 Les pointeurs Allocation dynamique des pointeurs:
La fonction calloc : void *calloc(nombre,taille); Elle alloue un bloc de mémoire de (nombre x taille) octets sur le tas Elle renvoie un pointeur sur la zone de type void (valable pour tous les types) qu'il faut convertir en un type adapté aux données. Si l'allocation réussit, calloc renvoi un pointeur sur le bloc, elle échoue si taille = 0 ou s'il n'y a pas assez de place en mémoire. Dans ce cas elle retourne un pointeur nul : NULL Ex: int *p; p = (int *) calloc(10 , sizeof(int) ); // réservation pour 10 entiers if ( p== NULL) // test création du pointeur { printf("erreur d'allocation mémoire !!!"); // ici traitement de l'erreur … }

20 Les pointeurs Allocation dynamique des pointeurs:
La fonction realloc : void *realloc( pointeur , newtaille ); Elle permet de changer la taille d'un bloc déjà alloué. Elle gère l'aspect dynamique des pointeurs. Utilisable à tous moment dans le programme Elle renvoie un pointeur sur la zone de type void (valable pour tous les types) qu'il faut convertir en un type adapté aux données. Si l'allocation réussit, calloc renvoi un pointeur sur le bloc, elle échoue si taille = 0 ou s'il n'y a pas assez de place en mémoire. Dans ce cas elle retourne un pointeur nul : NULL Ex:int *p; p = (int *) realloc( p , 20 * sizeof(int) ); // réservation pour 10 entiers supplémentaires if ( p== NULL) // test création du pointeur { printf("erreur d'allocation mémoire !!!"); // ici traitement de l'erreur … } !!! ATTENTION, les données peuvent être déplacées si l'espace n'est pas suffisant !!!

21 Les pointeurs Allocation dynamique des pointeurs:
La fonction free : free ( pointeur ); Elle permet de libérer l'espace mémoire alloué par les fonctions malloc(), calloc() realloc() Il est très important de libérer l'espace mémoire après utilisation, sinon celui-ci devient inutilisable pour la suite du programme Ex: int *p; p = (int *) malloc( 10 * sizeof(int) ); // réservation pour 10 entiers if ( p== NULL) // test création du pointeur { printf("erreur d'allocation mémoire !!!"); // ici traitement de l'erreur … } … … Free(p); // on libère la mémoire

22 Les structures Qu'est-ce qu'une structure ?
Une structure est un objet composé de plusieurs champs de types différents, qui sert à représenter un objet. Par exemple un client peut être représenté par son nom, son prénom, son année de naissance, son adresse. Ex: struct client // client est le nom de la structure { char nom[25]; char prenom[20]; int annee_naissance; char adresse[100]; } Un_Client ; // Un_Client et le nom d'une variable de type client // optionnel si on déclare seulement le type // ; obligatoire dans tous les cas

23 Les structures Définition du type et déclaration de variables?
Définition de la structure struct client // client est le nom de la structure { char nom[25]; char prenom[20]; int annee_naissance; char adresse[100]; } ; Déclaration de variables : struct client Un_Client; // déclaration de la variable Un_Client struct client NouveauClient; // déclaration de la variable NouveauClient

24 Les structures Définition du type et déclaration de variables?
Définition de la structure typedef struct client CLIENT; // création d'un alias CLIENT sur struct client struct client // client est le nom de la structure { char nom[25]; char prenom[20]; int annee_naissance; char adresse[100]; } ; Déclaration de variables simplifié : CLIENT Un_Client; // déclaration de la variable Un_Client CLIENT NouveauClient; // déclaration de la variable NouveauClient

25 Les structures Manipulation des champs : Exemple :
Les structures peuvent être manipulées champs par champs ou dans leur ensemble, Exemple : typedef struct client CLIENT; // création d'un alias CLIENT sur struct client struct client // client est le nom de la structure { char nom[25]; char prenom[20]; int annee_naissance; char adresse[100]; } ; Int main(void){ CLIENT Un_Client; // déclaration de la variable Un_Client CLIENT NouveauClient; // déclaration de la variable NouveauClient gets(NouveauClient.nom); // initialisation du champs nom gets(NouveauClient.prenom); gets(NouveauClient.adresse); scanf("%d",&NouveauClient.annee_naissance); Un_Client = NouveauClient; // Affectation sur l'ensemble des champs (copie) }

26 Les structures Les pointeurs de structures: Définition de la structure
typedef struct client CLIENT // création d'un alias CLIENT sur struct client struct client // client est le nom de la structure { char nom[25]; char prenom[20]; int annee_naissance; char adresse[100]; } ; Déclaration de variables simplifié : CLIENT Un_Client; // déclaration de la variable Un_Client CLIENT NouveauClient; // déclaration de la variable NouveauClient

27 Les structures Les pointeurs de structures: Définition de la structure
struct date { int jour; int mois; int annee; } *p ; int main (void){ p = (struct date *)malloc(sizeof(struct date)); if (p == NULL){ printf("erreur d'allocation mémoire!!!"); exit(-1); } printf("Donnez le jour : "); scanf("%d",&pdate->jour); printf("Donnez le mois : "); scanf("%d",&pdate->mois); printf("Donnez l'annee : "); scanf("%d",&pdate->annee); printf("La date %d/%d/%d \n", pdate->jour, pdate->mois, pdate->annee ); }

28 Les fichiers Qu'est-ce qu'un fichier ?
Un fichier est un ensemble d'informations stockées sur une mémoire de masse (disque dur, CD-ROM, mémoire flash…) En C, un fichier est une suite d'octets. Les informations contenues dans un fichier ne sont pas forcément de même type (char, int, float structure…) L'adresse d'une information dans le fichier est donnée par un pointeur. Deux types de fichier: Les binaires : Dans un fichier dit "binaire", les informations sont codées telles que comme en mémoire. Se sont généralement des nombres. Les fichiers texte : Dans un fichier dit "texte", les informations sont codées en ASCII. Ces fichiers sont visualisable facilement avec un simple éditeur de texte. Le dernier octet de ces fichiers est EOF.

29 Les fichiers Manipulation des fichiers
La lecture ou l'écriture dans un fichier n'est pas directe, mais utilise une zone mémoire tampon. Une structure spécifique gère ce tampon et d'autre variables nécessaires à la gestion du processus. typdef struct { char *buffer; // pointeur vers le tampon char *ptr; // pointeur vers le caractère suivant dans le tampon int cnt; // nombre de caractères dans le tampon int flag; // bits donnant l'état du fichier int fd; // descripteur (identifiant de fichier) } FILE;

30 Les fichiers Ouverture des fichiers
Avant qu'un programme puisse manipuler un fichier, il doit commencer par l'ouvrir. FILE * fopen( char *nom_fichier, char *mode_acces); Exemple: #include <stdio.h> void main(void) { FILE *fp; fp = fopen("nomdufichier.dat","r"); // Ouverture du fichier en mode lecture if (fp==NULL) { printf("Erreur d'ouverture de fichier\n"); } … … }

31 Les fichiers Ouverture des fichiers
Les différents modes d'accès aux fichiers texte. Pour les fichiers binaires, les modes d'accès sont: "rb","wb", "ab", "rb+", "wb+", "ab+". Mode d'accès cible résultat "r" Ouvrir le fichier en lecture (read) fopen retourne NULL si le fichier n'existe pas "w" Ouvrir le fichier en écriture (write) Le fichier est créé s'il n'existe pas. S'il existe le contenu est écrasé et perdu "a" Ajouter des données (append). Ouverture en écriture à la fin du fichier Le fichier est créé s'il n'existe pas "r+" Ouvrir le fichier en lecture et en écriture Fopen retourne NULL si le fichier n'existe pas "w+" "a+" Ouvrir le fichier en lecture et en ajout

32 Les fichiers Fermeture des fichiers
Quand un fichier n'est plus utilisé, on le ferme. Cela annule sa liaison avec le pointeur FILE correspondant. Attention il ne faut pas oublier de fermer un fichier après utilisation, car le nombre de fichiers susceptibles d'être ouverts simultanément est limité (nombre de pointeurs FILE limité). int fclose( FILE *pointeur_fichier); Exemple: #include <stdio.h> void main(void) { FILE *fp; … … fclose(fp); // Fermeture du fichier, retourne 0 si pas d'erreur sinon EOF }

33 Les fichiers Lecture et écriture en mode caractère:
Lecture : int fgetc( FILE *pointeur_fichier); La fonction fgetc retourne le caractère lu sous la forme d'un int. Si la valeur retourné est EOF ( EOF = -1), c'est que la fin de fichier a été atteinte ou qu'il y a eu une erreur. Exemple: int c; c = fgetc(fp); Ecriture : int fputc( int caractere, FILE *pointeur_fichier); La fonction fputc transfère un caractère dans le fichier pointé par pointeur_fichier. La fonction retourne le caractère écrit si pas d'erreur, et EOF s'il y a une erreur. Exemple: fputc( 'A', fp);

34 Les fichiers Lecture et écriture en mode chaine:
Lecture : char *fgets(char *pointeur_tampon,int nombre, FILE *pointeur_fichier); La fonction fgets lit dans le fichier à partir de la position courante, nombre caractères et les range à l'emplacement pointé par pointeur_tampon. La fonction s'arrête si un saut de ligne '\n' a été lu ou si nombre-1 caractères ont été lu ou si c'est la fin de fichier. Exemple: char stringbuf[81]; fgets(stringbuf, 81 , fp); Ecriture : char * fputs( char *pointeur_tampon, FILE *pointeur_fichier); La fonction fputs écrit une chaine de caractère dans un fichier à partir de la position courante.la fonction retourne une valeur positive si pas d'erreur, et EOF s'il y a une erreur. Exemple: fputs( 'Message', fp);

35 Les fichiers Lecture et écriture formatées:
Lecture : char *fscanf(FILE *pointeur_fichier,char *chaine_formatee, variables,..,..); La fonction fscanf lit des données dans un fichier en les formatant. Elle retourne le nombre de données correctement lues si pas d'erreur. La valeur EOF signifie fin de fichier ou erreur. Exemple: long num; char nom[30]; char prenom[30]; … fscanf(fp, "%ld %s %s",&num, nom, prenom); Ecriture : int * fprintf(FILE * pointeur_fichier,char *chaine_formatee, variables,..,..); La fonction fprintf écrit des données dans un fichier en les formatant, elle retourne le nombre de données correctement écrites si pas d'erreur, et EOF s'il y a une erreur. Exemple: fprintf( fp, "%ld %s %s",num,nom,prenom);

36 Les fichiers Lecture et écriture en bloc:
Lecture : int *fread(void *pointeur_Tampon,size-t taille,size_t nombre,FILE *point_fic); La fonction fread lit un bloc de données de taille x nombre octets et le range à l'emplacement référencé par pointeur_tampon. Elle retourne le nombre d'octets lus. Si la valeur est inférieur à nombre alors erreur. Exemple: struct client k[5]; … fread(k, sizeof(struct client),5,fp); Ecriture : int * fwrite(void *pointeur_Tampon,size-t taille,size_t nombre,FILE *point_fic); La fonction fwrite écrit un bloc de données de taille x nombre octets rangé à l'emplacement référencé par pointeur_tampon dans le fichier pointé par point_fic. Elle retourne le nombre d'objets complétement écrits. Si la valeur est inférieur à nombre alors erreur. Exemple: fwrite(k, sizeof(struct client), 5, fp);

37 Les fichiers Positionnement dans un fichier:
Jusqu'à présent on a supposé un accès séquentiel aux données. Si on veut accéder à la valeur C5 : il faut un accès direct aux données donc positionner le pointeur de fichier au bon endroit C1 C2 C3 C4 C5 C6 C7 C8 C9 1 2 3 4 5 6 7 8 Avant 1éré lecture Après 1éré lecture Après 2éme lecture Après 6éme lecture

38 Les fichiers Positionnement dans un fichier:
int fseek(FILE *pointeur_fichier, long offset, int base); La fonction fseek permet de placer le pointeur de position sur un octet quelconque d'un fichier. Le paramètre offset impose le nombre d'octets dont il faut décaler le pointeur relativement à la base. Si l'offset est négatif le déplacement s'effectue vers le début du fichier. base précise l'origine du déplacement dans le fichier. La fonction retourne 0 si pas d'erreur sinon un nombre non nul. Exemple: fseek(fp,0,0); // on se place au début du fichier fseek(fp,0,SEEK_END); // on se place à la fin du fichier fseek(fp,-3,SEEK_END); // on se place 3 octets avant la fin du fichier Si on veut accéder à la valeur C5 : il faut un accès direct aux données donc positionné le pointeur de fichier au bon endroit base Constante symbolique. signification SEEK_SET Début du fichier 1 SEEK_CUR Position actuelle dans le fichier 2 SEEK_END Fin de fichier

39 Les fichiers Lecture de la position du pointeur dans un fichier:
long ftell(FILE *pointeur_fichier); La fonction ftell permet de connaitre l'octet du fichier sur lequel pointe le pointeur de fichier. La fonction retourne dans un entier long la position courante dans le fichier à partir du début du fichier. Retourne -1 en cas d'erreur. Exemple: long position ; position = ftell(fp); Exemple recherche de la taille d'un fichier (on considère le fichier ouvert) long Taille; fseek(fp,0,SEEK_END); // on se place en fin de fichier Taille = ftell(fp); // lecture de la position dans le fichier Si on veut accéder à la valeur C5 : il faut un accès direct aux données donc positionné le pointeur de fichier au bon endroit


Télécharger ppt "Les pointeurs L'opérateur &."

Présentations similaires


Annonces Google