L1 Informatique Université Paris 8-2010-2011 Programmation Impérative I Rim Chaabane rchaabane@ai.univ-paris8.fr - Cours 6 - Les pointeurs



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

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

Chapitre 1 : La gestion dynamique de la mémoire

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

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

Les structures. Chapitre 3

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

Conventions d écriture et outils de mise au point

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Les chaînes de caractères

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

Algorithmique, Structures de données et langage C

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

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

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


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

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

INITIATION A LA PROGRAMMATION

Cours de C. Allocation dynamique. Sébastien Paumier

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

Claude Delannoy. 3 e édition C++

Chap III : Les tableaux

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

Le langage C. Séance n 4

V- Manipulations de nombres en binaire

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

Algorithmique et Programmation, IMA

Les structures de données. Rajae El Ouazzani

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

Rappels Entrées -Sorties

Utilisation d objets : String et ArrayList

I. Introduction aux fonctions : les fonctions standards

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

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

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

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

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

Programmation en langage C

Programmation impérative

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

SUPPORT DE COURS. Langage C

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

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

Gestion de la mémoire

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

Le prototype de la fonction main()

Table des matières. Chapitre 4 : Variables pointeurs

Arguments d un programme

OS Réseaux et Programmation Système - C5

Initiation à la programmation en Python

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

Premiers Pas en Programmation Objet : les Classes et les Objets

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

Généralités sur le Langage Java et éléments syntaxiques.

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

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

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

Introduction au langage 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)

Programmation système I Les entrées/sorties

INF 104 (SELC) Introduction au langage C

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

TP : Gestion d une image au format PGM

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

PROJET ALGORITHMIQUE ET PROGRAMMATION II

Programme Compte bancaire (code)

Cours d Algorithmique et de Langage C v 3.0

Rappels d architecture

Les arbres binaires de recherche

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

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

Cahier des charges. driver WIFI pour chipset Ralink RT2571W. sur hardware ARM7

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

Le langage C. Introduction, guide de reference

Assurance Qualité. Cours de génie logiciel. Renaud Marlet. LaBRI / INRIA (d'après A.-M. Hugues) màj 23/04/2007

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

Programmation en langage C Eléments de syntaxe

Cours Programmation Système

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

Logiciel de Base. I. Représentation des nombres

Cours 1: Java et les objets

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

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

Recherche dans un tableau

Langage Java. Classe de première SI

TP 1. Prise en main du langage Python

as Architecture des Systèmes d Information

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

1.6- Génération de nombres aléatoires

Architecture des ordinateurs

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

COMPARAISONDESLANGAGESC, C++, JAVA ET

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)

Cours de programmation avancée. Le langage C. Université du Luxembourg

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

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

ALGORITHMIQUE ET PROGRAMMATION En C

TP2 : tableaux dynamiques et listes chaînées

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

Transcription:

Les pointeurs Le langage C permet de manipuler des adresses d objets ou de fonctions par le biais de pointeurs. Pour ce faire on peut désigner des variables dites de type pointeur, destinées à contenir des adresses mémoires. Les pointeurs sont fortement typés, par exemple nous ne pouvons pas placer des caractères dans l adresse mémoire pointée par un pointeur de type entier. L utilisation de l opérateur cast peut toutefois autoriser certaines conversions. Il nous est possible effectuer, dans une certaine mesure, des opérations arithmétiques sur les pointeurs : incrémentation, décrémentation, soustraction. Ces opérations vont plus loin qu un simple calcul d adresse, elles prennent en compte la taille des objets pointés. Nous verrons également qu il y a une étroite relation entre la notion de tableau et celle de pointeur. 1. La notion de pointeur La déclaration suivante : int *adr ; Précise que adr est une variable de type pointeur sur des objets de type int. 1.1. Attribuer une valeur à une variable de type pointeur Etant donné que la variable adr n a pas encore été initialisées, alors sa valeur est pour l instant indéfinie. Pour attribuer une valeur à adr, il faut la faire pointer sur un entier précis. Pour faire cela il existe différentes méthodes : Méthode 1 : int n ; adr = &n ; ou int tab[3] ; adr = &tab[0] ; 1

Méthode 3 : #include <stdlib.h> Adr = (int) malloc( sizeof(int) ); La première méthode consiste à affecter à adr l adresse réservée à la variable n ou à l élément d indice 0 du tableau d entiers tab[0]. La seconde méthode consiste à allouer dynamiquement un emplacement mémoire d une taille égale au type qui y sera stocké. 1.2. L opérateur * Cet opérateur sert à accéder à la valeur de l objet pointé. Si adr est un pointeur alors *adr est l objet pointé par adr. Exemple : int * adr; int n = 20; ad = &n; /*ad pointe sur l'entier n qui contient la valeur 20 */ printf("%d", *ad); /*affiche la valeur de 20 */ *ad = 30; printf("%d", *ad); /*affiche la valeur de 30 */ printf("%d", n); /* affiche la valeur de 30 aussi */ L avant dernière instruction est équivalente à : n = 30; L intérêt d une telle utilisation peut s avérer utile, comme dans le cas suivant :... if (n>p) adr = &n; else adr = &p;... *adr = 30; /* place la valeur de 30 dans n ou dans p suivant le cas */ Si l emplacement adr avait été alloué dynamiquement alors l on pourrait affecter une valeur à l adresse mémoire réservée de la même façon : adr = malloc(sizeof(int)) ; *adr = 30; 1.3. Exemples de déclarations de pointeurs Déclaration de pointeurs sur des objets de type de base ou de type structure, ou défini par typedef. 2

unsigned int n, *ptr, q, *adr; struct point { char nom; int x, y; }; - adr et ptr sont des pointeurs sur des éléments de type unsigned int - Il est nécéssaire de répéter le symbole * dans chaque déclarateur de pointeur. - ps est un pointeur sur des structures de type struct point. - s est une structure de type struct point. struct point *ps, s; typedef int vecteur[3]; vecteur *pv; - vecteur est synonyme de int[3] - pv est un pointeur sur des tableaux de 3 int pointeur de pointeur float x, *pf, **ppf; - x est un float et pf est un pointeur sur un float - **ppf est un float - *ppf est un pointeur sur un float - ppf est un pointeur sur un pointeur sur un float int (**chose)[10]; - (* *chose)[10] est un int - (* *chose) est un tableau de 10 int - *chose est un pointeur sur un tableau de 10 int - chose est un pointeur de pointeur sur un tableau de 10 int Attention à bien mettre les parenthèses ici. Sans les parenthèses l interprétation est différente comme nous pouvons le voir dans la suite. int *pt[10]; - *pt[10] est un int - pt[10] est un pointeur sur un int - pt est un tableau de 10 pointeurs sur un int int **ppt[10]; - **ppt[10] est un int - *ppt[10] est un pointeur sur un int - ppt[10] est un pointeur sur un pointeur sur un int - ppt est un tableau de 10 pointeurs sur un pointeur sur un int int *f(float x); - *f(float x) est un int - f(float x) est un pointeur sur un int - f est une fonction recevant un float et retournant un pointeur sur un int 2. Les propriétés des pointeurs 2.1. Opérations entre pointeurs Addition ou soustraction d un entier à un pointeur : Si nous déclarons un pointeur comme ci-dessous : int * adr; 3

alors l expression adr + 1 va retourner un pointeur sur un int et sa valeur est l adresse de l entier suivant l entier pointé par adr. On pourra relever que la différence entre l adresse de pn et pn+1 est de 4. Cette valeur correspond au nombre d octets d un int. pn + 1 ne modifie pas le contenu de pn. Par contre l appel à pn++ va faire pointer pn vers l adresse (pn+1) et dans ce cas le contenu de pn vas changer. De la même façon : pn+3 permet de pointer sur un int qui se troive trois adresses plus loin que celle contenue dans pn. Donc attention à l emploi de cette opération!! /!\ pn++!= (pn+1) Soustraction entre deux pointeurs : Il est possible de soustraire les valeurs de deux pointeurs de même type. Comme nous l avons vu précédemment, en additionnant un entier n à un pointeur pn cela nous positionne sur la nième adresse devant pn. Soit par exemple les pointeurs suivants : int *pn, *pm; pm = pn + 4; printf("%d", pn - pm); /* va afficher 4 */ pm pn va retourner 4 qui correspond au nombres d adresses mémoires contenant un int entre pm et pn. De même dans le cas suivant : int t[10]; int *pn = &t[3]; int *pm = &t[8]; pm - pn /* va retourner 5 */ Il y a bien 5 éléments de type int séparant t[3] et t[8]. 4

2.2. Lien entre pointeurs et tableaux Tableau à une dimension : Soit un tableau tab de int et un pointeur pn sur un int déclarés comme suit : int tab[10], *pn; Pour accéder au nième élément du tableau, on fait appel à tab[n]. Maintenant faisons pointer pn sur le premier élément du tableau tab : pn = &tab[0]; /* ou pn = &tab; ce qui est équivalent */ Pour accéder au nième élément du tableau, il suffit d écrire : tab[n] ou *(pn + n) Exemple : int *pn, tab[5]={4,2,7,0,6}; printf("%d\n", tab[3]); /* affiche 0 */ pn = &tab; printf("%d\n", *(pn+3)); /* affiche 0 aussi */ Ainsi, déclarer un tableau revient à déclarer un pointeur sur un int. Comme nous venons de voir pour accéder au nième élément du tableau : - soit nous faisons appel au pointeur pn : *(pn+3) - soit nous utilisons les indices du tableau : tab[n] - soit nous utilisons directement le tableau comme un pointeur : *(tab+3) Donc t[i] est équivalent à *(t+i). De même *(pn+i) équivaut à pn[i] même si pn est de type pointeur il nous est possible d accéder au i ème élément de même type avec l emploi des indices, tout comme pour les tableaux. Tableau à deux dimensions : L expression t[i][j] s interprète comme (t[i])[j], ce qui peut se traduire par : T[j] <-> *(T+j) <-> *( *(t+i) +j) Pour résumer, nous avons : &t[0] <-> t &t[i] <-> t+i t[1] <-> *(t+1) t[i] <-> *(t+i) t[i][0] <-> *t[i] <-> **(t+i) t[i][j] <-> (t[i])[j] <-> ( *(t+i))[j] <-> *( *(t+i) + j) 5

3. Le pointeur NULL et le pointeur générique void * Le pointeur NULL : Le symbole NULL du langage C permet d initialiser un pointeur qui ne pointe sur rien. Cette valeur NULL peut être affectée à tout pointeur quel que soit sont type. Ce symbole est défini dans les librairies stdio.h, stdlib.h. int *pn = NULL ; En utilisant le pointeur NULL, cela nous permet alors de comparer si deux pointeurs sont égaux (opérateur ==) ou non égaux (!=) entre eux. Par contre les comparaisons d inégalité (<,>,>=, >=) ne sont pas autorisés avec les pointeurs sauf si l on manipule des tableaux. Dès que l on déclare une variable de type pointeur, il est préférable de l initialiser à NULL, surtout dans le cas oùu l on ne connait pas sa valeur initiale au début du programme. Au moment d utiliser un pointeur, il est préférable de tester si sa valeur est bien non nulle : if(pn!= NULL) *pn =... Equivalent à : if(pn) *pn =... Cela s avèrera utile pour la gestion des listes chaînées. Le pointeur générique : Nous avons vu jusqu à maintenant qu un pointeur pointe sur un objet typé. Or il est possible de déclarer un pointeur sans type. Comme pour les déclarations de fonction, il nous est possible de déclarer des fonctions sans type. Particulièrement lorsqu elles ne renvoient aucun résultat. Il nous est donc aussi possible de déclarer des pointeurs sans type particulier. Dans ce cas ce sera l adresse contenu dans le pointeur qui aura un sens. Ceci est particulièrement utile lorsque : - Une fonction doit traiter des objets de différents types, alors qu elle a reçu l adresse de l objet en argument. - L on souhaite seulement échanger les valeurs de deux pointeurs. Un pointeur de type générique se déclare comme suit : void * pn; void *pn, *pm, n; /* incorrect, n ne peut être de type void*/ pn++; /* interdit */ pn = pn + 5; /* l'expression p + 5 est interdite */ int i = pm - pn; /* l'expression pm -pn est interdite */ int *pi; if (pn!= pi) /* correct */ if (pn == pi) /* correct */ 6

4. Le cast d un pointeur Exemple : char * pc ; int * pi ; pi= (int *) pc ; ou pc = (char *) pi ; 7