4. Pointeurs et allocation dynamique. Définitions et déclarations Tableaux et pointeurs Structures Tableaux multidimensionnels

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

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

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

Le langage C. Séance n 4

Chap III : Les tableaux

Algorithmique et Programmation, IMA

Les structures. Chapitre 3

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

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

Chapitre 1 : La gestion dynamique de la mémoire

Le prototype de la fonction main()

Les chaînes de caractères

Programmation système I Les entrées/sorties

Programmation impérative

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

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

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

Cours de Programmation Impérative: Zones de mémoires et pointeurs

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

Introduction au langage C

INF111. Initiation à la programmation impérative en C amini/cours/l1/inf111/ Massih-Reza Amini

Rappels Entrées -Sorties

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)

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

Conventions d écriture et outils de mise au point

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

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP


Outils pour la pratique

INITIATION A LA PROGRAMMATION

Algorithmique, Structures de données et langage C

I. Introduction aux fonctions : les fonctions standards

Cours Programmation Système

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

PROJET ALGORITHMIQUE ET PROGRAMMATION II

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

Programmation en langage C

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

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

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

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

Table des matières. Chapitre 4 : Variables pointeurs

Les fichiers. Chapitre 4

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

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

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

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

Programmation C. J.-F. Lalande. 15 novembre 2012

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

Les structures de données. Rajae El Ouazzani

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

Programmation en langage C d un µcontrôleur PIC à l aide du compilateur C-CCS Sommaire

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

Premiers Pas en Programmation Objet : les Classes et les Objets

Gestion de la mémoire

MINIMUM. connaissances nécessaires à la programmation des microcontrôleurs PIC18 en langage C (une introduction au langage c A.N.S.

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

Architecture des ordinateurs

GESTION DES FICHIERS C/UNIX

#include <stdio.h> #include <stdlib.h> struct cell { int clef; struct cell *suiv; };

Cours d Algorithmique et de Langage C v 3.0

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

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

Dans le chapitre 1, nous associions aux fichiers ouverts des descripteurs de fichiers par lesquels nous accédions aux fichiers.

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

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

TP : Gestion d une image au format PGM

Langage Éric Guérin 5 octobre 2010

Notes du cours 4M056 Programmation en C et C++ Vincent Lemaire et Damien Simon

Le langage C. Introduction, guide de reference

Claude Delannoy. 3 e édition C++

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

Programmation système de commandes en C

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Programmation Classique en langage C

Les processus légers : threads. Système L3, /31

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

Java Licence Professionnelle CISII,

Logiciel de base. Première année ENSIMAG

Programmation système en C/C++

Algorithmes et Programmes. Introduction à l informatiquel. Cycle de vie d'un programme (d'un logiciel) Cycle de vie d'un programme (d'un logiciel)

Plan du cours. Historique du langage Nouveautés de Java 7

Cours de Système : Gestion de Fichiers

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

Cours de C. Allocation dynamique. Sébastien Paumier

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

Le Langage C Licence Professionnelle Qualité Logiciel Pr. Mouad BEN MAMOUN ben_mamoun@fsr.ac.ma Année universitaire 2011/2012

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Cours 1: Java et les objets

OS Réseaux et Programmation Système - C5

Archivage Messagerie Evolution pour usage HTML en utilisant Hypermail

BTS IRIS Cours et Travaux Pratiques. Programmation C. A. Lebret, TSIRIS, Lycée Diderot, 1995/06. en conformité avec le référentiel du BTS IRIS

INF 104 (SELC) Introduction au langage C

L exclusion mutuelle distribuée

as Architecture des Systèmes d Information

SUPPORT DE COURS. Langage C

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

Arguments d un programme

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Transcription:

1 4. Pointeurs et allocation dynamique Définitions et déclarations Tableaux et pointeurs Structures Tableaux multidimensionnels

2 Pointeurs Chaque variable a une adresse en mémoire qu il peut être utile de connaître. Pour obtenir cette adresse : opérateur adresse de & Exemple : void main () { int i = 7 ; } Résutat : p = &i ; printf( valeur de i = %d\n, i); affecte adresse de i dans p printf( adresse de i = %p\n, &i); > valeur de i = 7 > adresse de i = 0x03F0 (1008 (10) ) @ memoire: 0x03EC 0x03F0 0x03F4 24 7 542 i

3 Pointeurs Un pointeur est une variable pouvant contenir une adresse mémoire. Donc p = &i ; affecte l adresse de i à la variable p On dit que p pointe désormais sur i. &i p * : opérateur d indirection ou de déréférencement; Appliqué à un pointeur, donne accès à l objet pointé. Donc j = *p ; j = objet pointé par p j = i; /* i et *p interchangeables*/ &i p * 7 i

4 Pointeurs Déclaration : en fonction du type de l objet pointé Entier : int *i; /* car *i est un entier */ Réel: float *f ; Caractère: char *c; &? i q Exemple issu du K&R: int x = 1, y = 2, z[10]; int *pi; /* pi est un pointeur sur 1 int */ &? pi pi = &x; /* pi pointe maintenant sur x */ y = *pi; /* y vaut désormais 1 */ &x pi * 1 x *pi = 0; /* x vaut désormais 0 */ pi = &z[0]; /*pi pointe désormais sur z[0]*/ &x pi &z[0] pi * 0 x?? z[0] z[1]

5 Pointeurs Opérations sur les objets pointés : les opérations permises sur l objet int *pi = &x; *pi = *pi + 2; /* *pi et x ici interchangeables */ /* <-> x = x + 2 */ y = *pi 1; /* <-> y = x 1 */ (*pi)++; /* idem. (*pi) += 1; <-> x++ */ Opération sans indirection : car les pointeurs sont aussi des variables int *qi, *pi; &e avant: qi qi = pi ; /* qi pointe sur même objet que pi */ &f pi après: &f qi &f pi

6 Pointeurs Initialisation : int a,*pi; (1) pi=&a; *pi=3; //ok (2) avec malloc() (voir plus loin) Ne pas utiliser un pointeur non initialisé par l adresse effective d une variable!! Déclarer un pointeur réserve un espace mémoire pour stocker une adresse mais en aucun cas pour l objet pointé. &? pi int *pi; *pi=3; /* pointeur non initialisé, contient une & aléatoire*/ /* et pas de mémoire réservée pour stocker l entier &? pointé*/ pi * Attention: ce code ne fait pas d erreur à la compilation mais une erreur à l exécution (Segmentation Fault) &? pi &a pi &a pi *? a? a 3 a

7 Pointeurs xkcd.com

8 Tableaux et pointeurs Par définition: si pa est un pointeur sur un élément d un tableau alors, pa+i pointe sur le i-ème élément du tableau après pa pa-i pointe sur le i-ème élément avant pa int *pa, a[5]; pa = &a[0]; /*pa point sur l élément 0 de a*/ &a[0] pa pa+1 pa+2????? a[0] a[1] a[2] a[3] a[4] Note : si pa contient 0x10, l adresse du premier élément, alors pa+1 ou p++ vaut 0x14 dans le cas où l entier signé est codé sur 4 octets.

9 Tableaux et pointeurs Ainsi a[i] identique à *(pa+i), si pa pointe sur le premier élément: *(pa+2)=12; /* idem. a[2]=12*/ &a[0] pa pa+1 pa+2?? 12?? a[0] a[1] a[2] a[3] a[4] *pa = *(pa+2); /* noter l importance des parenthèses */ &a[0] pa 12? 12?? a[0] a[1] a[2] a[3] a[4] *pa = *pa + 2 ; &a[0] pa 14? 12?? a[0] a[1] a[2] a[3] a[4]

10 Tableaux et pointeurs Le nom d un tableau vaut l adresse de son 1er élément: a &a[0] Donc, *(a+i) identique à a[i] a a+1 a+2 fondamental! int a[5]; *a=7; /* affecte 7 à a[0] */ *(a+1)=2; /* idem a[1] = 2 */ int *pa = a; /* idem. pa = &a[0]; */????? a[0] a[1] a[2] a[3] a[4] pa+1 a a+1 a 7 2 pa a[0] a[1] Note : pa est une variable donc pa = a; puis pa = b; et pa++; VALIDES, mais a est juste un nom donc a = pa; et a++ ; INVALIDES.

11 Tableaux et pointeurs aussi : a+i identique à &a[i] *(a+2)=12; /* idem. a[2]=12*/ a a+1 a+2 *a = *(a+2); /* noter l importance *a = *a + 2 ; des parenthèses sinon :*/ a[0] a[1] a[2] a[3] a[4] a[0] a[1] a[2] a[3] a[4]?? 12?? a 12? 12?? a 14? 12?? a[0] a[1] a[2] a[3] a[4]

12 Allocation dynamique de la mémoire Allocation statique: Taille d'un tableau doit être une constante. int tab[50]; int tab[]={3,4,5,6} ( tab[4] ) int tab[n] interdit! (bien qu une norme et des compilateurs récents l autorisent maintenant L ) Or la taille n est parfois pas connue à l avance. Ø Surdimensionner le tableau (ex: tab[4000]) mais probablement un gâchis de mémoire inutilisable Ø Définir la taille pendant l exécution (Allocation dynamique) : 1. une fonction malloc() recherche un bloc mémoire libre contigüe de taille désirée et renvoie son adresse. 2. cette adresse est affectée à un pointeur pour utilisation du bloc mémoire.

13 Allocation dynamique de la mémoire Allocation dynamique: malloc() malloc (int size) : recherche un bloc contigüe de size octets libre en mémoire et retourne l adresse de début du bloc. Retourne le pointeur NULL, si échec (pas assez de mémoire libre). int n=4, *tb; tb = (int*) malloc ( n*sizeof(int) ); &bloc &? tb???? Accès (similaire au tableau statique) : tb[i] ou *(tb+i) &bloc tb tb+1???? tb[0] tb[1]

14 Allocation dynamique de la mémoire Allocation dynamique: NULL est un symbole constant valant 0, défini dans stdlib.h. sizeof(type): renvoie la taille en octets de l objet de type type malloc() renvoie un pointeur de type void*. void *ptr; définit un pointeur générique, i.e dont le type de l objet pointé est indéfini. Avant utilisation, le convertir explicitement: int *pi; pi=(int*) ptr; /* pi contient la même adresse que ptr */ /* mais pi pointe sur un entier de taille sizeof(int) et pi+1 sur l entier suivant */

15 Allocation dynamique de la mémoire #include <stdio.h> #include <stdlib.h> /* pour le prototype de malloc() */ int main(void) { int n, *tab; printf ( Taille désirée? ); scanf ( %d,&n); tab=(int*) malloc (n*sizeof(int)); /* allocation dyn. de n entiers */ if (tab==null) /* test si échec de l allocation */ { printf( erreur allocation tab ); return(-1);} /*sort du programme si échec!*/ tab[0]=1; /* idem. *tab=1; */ free(tab); /* libération du bloc mémoire alloué par malloc*/ return(0); }

16 Allocation dynamique de la mémoire Libération de la mémoire allouée par malloc() : free(void *ptr): libère le bloc mémoire d adresse ptr précédemment alloué par un malloc. Toujours libérée la mémoire dès que l on en a plus besoin (en fin de programme?) La mémoire libérée en cours d exécution peut être réutilisée pour d autres allocations. Note: malloc et free peuvent être utilisés pour allouer un bloc mémoire une variable du type pointé (un tableau d 1 seul élément).

17 Erreur de Segmentation Segmentation de la mémoire : Le système d exploitation alloue de la mémoire à chaque programme. Un programme ne peut accéder (lecture/écriture) à la mémoire d un autre programme par sécurité: un programme avec des erreurs ne peut ainsi corrompre un autre programme. Erreur de Segmentation (Segmentation Fault): Si un programme tente d accéder de la mémoire qui ne lui appartient pas Ø détection par le système de la violation mémoire qui envoie un signal (SIGSEGV) au programme Ø avec pour résultat de stopper immédiatement l exécution du programme

18 Erreur de Segmentation Cause courante d erreur de segmentation : Avec scanf (, void *) dont les arguments sont des adresses où écrire les donnés lues au clavier, int n; scanf ( %d, n); /*n non initialisé*/ /*adresse de stockage: contenu aléatoire de n */ /* correct : scanf ( %d,&n) -> adresse : adresse de n*/ Utiliser un pointeur non initialisé (déjà vu) int *pi; /* pi contient une adresse aléatoire */ *pi = 3; /* accès en écriture à une adresse aléatoire: risque de Seg Fault*/ &? pi *??

19 Erreur de Segmentation Cause commune d erreur de segmentation : Débordement de tableau statique ou dynamique int a[2]; a[2] = 3; /* idem *(a+2)=3 */ *(a - 1) = 1; a-1? a a+1 a+2??? a[0] a[1] Note: parfois pire (pas de segmentation fault) mais un programme bogué int N=2, a[2]; a[2] = -1; /* hors tableau et tombe sur N*/ N++; /* N vaut 0!!*/ a a+1 a+2 si le hasard fait que l occupation mémoire est:?? a[0] a[1]? N

20 Les Structures regroupe des éléments de types différents facilite l organisation et la manipulation de données composées un composant est appelé un champ ou un membre déclaration de structure: struct nom_facultatif_pour_la_struct { définition }; struct coureur { char nom[30] ; char prenom[30] ; int dossard ; float temps ; }; struct coureur c1, c2, c3 ; /* c1, c2, c3 sont des structures de type coureur */ idem: struct coureur { char nom[30] ; char prenom[30]; int dossard ; float temps ; }c1, c2, c3;

21 Les Structures Initialisation à la déclaration : struct coureur c1={ Bolt, Usain,23,9.58}; accès aux champs par l opérateur. c1.temps = 9.54 ; c2.dossard = 2 ; structures et pointeurs struct coureur *c4 ; /*n alloue pas de mémoire pour la structure*/ c4 = (struct coureur *)malloc(sizeof(struct coureur)); (*c4).temps = 42.54 ; /* parenthèse nécessaire */ c4->temps = 42.54 ; /* idem avec opérateur -> pour alléger l écriture */

22 typedef permet de définir des noms de nouveau type de données Exemple : typdef int Longueur; /*rend Longueur synonyme de int*/ Longueur i, *j; /* définit 1 variable et 1 pointeur (sur entier)*/ allège les déclarations de structure typedef struct { char nom[30] ; char prenom[30] ; int dossard ; float temps ; } coureur ; /* désormais on peut omettre le mot-clé struct :*/ coureur c1, c2, *c3 ; c3 = (coureur*) malloc (1*sizeof(coureur));

Segmentation Fault 23

24 Tableaux multidimensionnels Un tableau à 2 dimensions (L,C) est un tableau de tableau : un tableau L éléments (/lignes) contenant chacun un tableau de C éléments. Déclaration : int a[l][c]; L lignes de C éléments int a[2][3]={{1,2,3},{4,5,6}}; avec initialisation a[0] a[1] a: 1 2 3 a[0][0] a[0][1] a[0][2] 4 5 6 a[1][0] a[1][1] a[1][2] a[0][0] a[0][1] a[0][2] on se permet de le représenter ainsi pour plus de lisibilité : a[0] a[1] 1 2 3 4 5 6 a[1][0] a[1][1] a[1][2]

25 Tableaux multidimensionnels Comme pour un tableau 1D: a &a[0][0] ( a[0]est le nom du tableau de la première ligne, a[0] &a[0][0] et a[1] &a[1][0] ) a a[0][0] a[0][1] a[0][2] Accès aux composantes : a[i][j] a[0] a[1] (à préférer J ) 1 2 3 4 5 6 a[1][0] a[1][1] a[1][2] a[1]+1 ou *( a[i] + j ) ou encore *( *(a+i) + j )

26 Tableaux multidimensionnels #include <stdio.h> void main(void) { int m[2][3] = {{11,12,13},{21,22,23}}; *((*m)+1) = -2; m[1][0]= -1; } printf("%i %i %i \n", printf("%i %i %i \n", m[0][0], m[0][1], m[0][2]); **(m+1), *(*(m+1)+1), *( m[1]+2)); Sortie écran: 11-2 13-1 22 23

27 Le tableau de pointeurs! s[0] s[1] s[2] char s[] = "On"; /* idem. char s[3]=.. */ char s1[] = "est"; char s2[] = "jeudi"; s2 s1 s j O n \0 e s t \0 e u d i \0 Si on souhaite mettre les chaines dans un tableau : un tableau avec les adresses du 1 er élément des chaînes (le noms des chaînes) un tableau de pointeurs vers des caractères char * tabs[] = {s, s1, s2}; tabs s[0] s[1] s[2] tabs[1][2] = x; /* idem.= { &s[0], &s1[0], &s2[0] } */ s s1 O n \0 e s x \0 /* car idem *( *(tabs+1) + 2)= */ s2 j e u d i \0

28 Le tableau de pointeurs! Accès au caractères (toujours pareil): tabs[i][j] ou *( *(tabs+i)+j ) car tabs[i] ou *(tabs+i) est l adresse du 1 er élément de la chaine. On peut définir un pointeur sur le tableau de pointeurs (è pointeur sur un pointeur sur 1 caractère): char ** ptr_s = tabs; tabs s[0] s[1] s[2] L accès (toujours pareil) : ptr_s[1][2] = X; tabs ptr_s s s1 O n \0 e s X \0 ou *(*(ptr_s+1)+2) = X; s2 j e u d i \0

29 Tableau de pointeurs sur entiers! int a[3], b[4], c[3]; int * mat[3] = {a,b,c}; ( ) tab ptr_m mat a b a[0] a[1] a[2] 1-4 0 7 2 11 1 ( int ** ptr_m = tab; ) c -4 6 9 Le tableau int* mat[3] peut être alloué dynamiquement puis remplit avec les noms (adresses) des tableaux: &bloc a 1-4 0 ptr_m int **ptr_m; ptr_m = (int**) malloc ( 3*sizeof(int*) ); ptr_m[0] = a; 7 2 11 1-4 6 9 On peut encore allouer les tableaux a, b et c dynamiquement: tableau 2D dynamique. b c

30 Tableaux multidimensionnels dynamiques Allocation dynamique : d un tableau de dimension (3,4) 1. Allocation d un tableau de 3 pointeurs sur des entiers int ** ptr_m; ptr_m = (int**) malloc(n*sizeof(int *)); &bloc ptr_m &? &? &? 2. On alloue 3 tableaux de 4 entiers dont on stocke les adresses dans le tableau de pointeurs avec malloc() &bloc???? &bloc ptr_m &bloc &bloc &bloc ptr_m[0][0]????????????

31 Tableaux multidimensionnels void main(void) { int i; int Lignes = 3,Colonnes = 4; int ** ptr_m; /* pointeur sur un pointeur */ ptr_m = (int**) malloc(sizeof (int*) * Lignes); /* allocation du tableau de pointeurs */ for (i = 0; i < Lignes; i++) ptr_m[i] = (int*) malloc(sizeof (int) * Colonnes); ptr_m[1][3] = 77; /* allocation des tableaux d entiers (chq ligne)*/ } for (i = 0; i < Lignes; i++) free (ptr_m[i]); /* libération du tableau de chaque ligne */ /* ou avec free(mat[i]); */ free(ptr_m); /* libération du int** */

32 Tableaux multidimensionnels Autre solution: considérer le tableau 2D comme un vecteur 1 2 3 4 1 ère ligne 2 ème ligne Déclaration : int matrice [L*C] ; ou int *matrice=(int*)malloc(l*c*sizeof(int)); Accès à l élément correspondant à matrice[i][j] : matrice[i*c+j] ou *(matrice + (i*c) + j)

33 Tableaux multidimensionnels #include <stdio.h> #include <stdlib.h> void main(void) { int m_toto[6] = {11,12,13,21,22,23}; //matrice 2x3 } printf("%i %i %i \n", m_toto[0*3+0], m_toto[0*3+1], m_toto[0*3+2]); printf("%i %i %i \n", *(m_toto+1*3), *(m_toto+1*3+1), *(m_toto+1*3+2)); Sortie écran: 11 12 13 21 22 23