Algorithmique et Langage C
www.polytech.unice.fr/žvg/index-xidian.html
Granet Vincent - Vincent.Granet@univ-cotedazur.fr
Xi’an - Octobre 2021 - Mai 2022
Pointeurs
Les Pointeurs
Pointeurs Définiton
Pointeurs
Définition
unpointeurest uneadressequi désigne une valeur en mémoire.
l’accès à la valeur pointée se fait de façonindirecte.
125.38 p
dans les langages typés (e.g.C) le type d’un pointeur est fonction du type des valeurs pointées. On parlera, par exemple, de pointeurssur réels.
dans les langages modernes (e.g.Java), mais aussi dans les langages fonctionnels (e.g.Lisp), la notion de pointeur disparaît.
son
Pointeurs Définiton
Pointeurs en C
les bases
déclaration :T p(e.g.double p)
les pointeurs sont typés⇒compatibilitéobligatoirepour l’affectation ! Conversions
implicitepour n’importe quel pointeur avecvoid * pour les autres une conversionexpliciteest nécessaire
#define NULL ((void ) 0) //dans <stddef.h>
En C les pointeurs sonttrèsutilisés. les programmes sont : plus compacts
plus efficaces
mais bien moins lisibles et sujets àplus d’erreurs son
Pointeurs Déclaration
Pointeurs en C
Exemples de déclarations
i n t p1, p2; / deux pointeurs sur int /
c h a r p3, p4; / un pointeur sur char, un char /
c h a r s; / un pointeur sur pointeur sur char /
i n t pi; / un pointeur sur pointeur sur pointeur sur int /
v o i d r; / pointeur sur void (générique) /
f l o a t s[10] / tableau de 10 pointeurs sur float /
f l o a t ( t)[10] / pointeur sur tableau de 10 float /
i n t ( pfunc)(v o i d); / pointeur sur fonction sans paramètre,
renvoyant un int /
i n t ( tp[5])(v o i d); / tableau de 5 pointeurs du type précédent /
son
Pointeurs Opérateurs
Pointeurs en C
Opérations de bases
indirection (déréférencement)
&adresse de (référencement)
i = 10;
pi = &i;
j = *pi;
(*pi)++;
q = pi;
pi i j q
10
10 10
10
11 10
10 11 { int *pi, i, j, *q = NULL;
}
son
Pointeurs Opérateurs
Pointeurs en C
Arithmétique sur les pointeurs
Comparaison :
== != < <= > >=Addition/soustraction d’un entier :
pointeur+n→pointeur pointeur−n→pointeur
décalage de n sizeof(type_pointé)
Soustraction de deux pointeurs de même type
pointeur−pointeur→entier
le résultat est en terme de nombre d’objets du type des valeurs pointées son
Pointeurs Opérateurs
Pointeurs en C
0 max
∆ ∆ ∆
T *p, *q;
= sizeof(T)
p
p−1 p+1 p+2 q
q−p // = 5 son
Pointeurs Opérateurs
Pointeurs en C
Exemples de déclarations
Pointeur constant. Doit être initialisé à la déclaration
i n t c o n s t pconst = &x;
Pointeur sur un objet constant. L’objet ne peut être modifié par l’intermédiaire du pointeur
c o n s t i n t pconst;
Pointeur constant sur objet constant
c o n s t i n t c o n s t pconst_to_const = &x;
//mais attention c o n s t i n t i = 1;
i n t p = &i; // faux
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Simulation transmission par référence
quand une fonction doit renvoyer plus d’un résultat
FAUX
v o i d swap(i n t a, i n t b) {
i n t aux;
aux = a; a = b; b = aux;
} ...
i n t x=2, y=3;
// échanger x et y swap(x, y);
// x=2, y=3
OK
v o i d swap(i n t a, i n t b)
{
i n t aux;
aux = a; a = b; b = aux;
} ...
i n t x=2, y=3;
// échanger x et y swap(&x, &y);
// x=3, y=2
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Pointeurs et tableaux
pointeurs et tableaux sont des notions très proches
un tableau est un pointeurconstantsur le premier élément du tableau.
t[i]⇔*(t+i)
t[i][j]⇔*(*(t+i)+j)
i n t p, t[8];
c h a r s = "hello";
p = t;
p = &t[0]; // idem /
t[2]== (t+2)== (p+2)==p[2]
s[2]== (s+2)== ("hello"+2)=="hello"[2]
/
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Différence entre pointeurs et tableaux
e l
h l o \0
e l l o \0 h
t
char p
char t[9] = "hello";
*p = "hello";
p++; // OK t++; // KO
printf("%ld %ld\n",s i z e o f p, s i z e o f t);
// 8 9
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Tableau en paramètre
Un tableau est un pointeur. Il n’y a pas de copie des éléments du tableau !
C’est l’adresse du tableau qui est tramsisepar valeur!
v o i d reset(f l o a t t[], i n t n) {
f o r (i n t i=0; i<n; i++) t[i] = 0.0;
} ...
f l o a t ftab[MAX];
reset(ftab, MAX); // OK
v o i d reset(f l o a t t, i n t n) {
f o r (i n t i=0; i<n; i++) t++ = 0.0;
} ...
f l o a t ftab[MAX];
reset(ftab, MAX); // OK
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Pointeurs et matrice
v o i d reset(d o u b l e mat[][N], i n t m, i n t n) { f o r (i n t i=0; i<m; i++)
f o r (i n t j=0; j<n; j++) mat[i][j]=0.0;
}
v o i d reset(d o u b l e mat[], i n t m, i n t n) { f o r (i n t i=0; i<m; i++)
f o r (i n t j=0; j<n; j++)
mat[i n + j]=0.0; // idem mat[i][j]=0.0 ; }
v o i d reset(d o u b l e mat, i n t m, i n t n) { f o r (i n t i=0; i<m; i++)
f o r (i n t j=0; j<n; j++)
(mat + (i n + j)) = 0.0; // idem mat[i][j]=0.0 ; }
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Chaînes de caractères et pointeurs
une chaîne de caractères est un tableau de caractères,doncun pointeur.
strlen
/
Rôle : renvoie la longueur de la chaîne de caractères s /
i n t strlen(c o n s t c h a r s) {
c o n s t c h a r p = s;
w h i l e ( s++) / vide /;
r e t u r n (s•1)•p;
}
strcpy
/
Rôle : affecte la chaîne s2 à s1 (i.e. s1 = s2) /
c h a r strcpy(c h a r s1,c o n s t c h a r s2) {
c h a r p = s1;
w h i l e ( s1++ = s2++)/ vide /;
r e t u r n p;
}
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Paramètres programmes
le support d’exécution peut transmettre à la fonctionmaindeux (ou trois) paramètres au démarrage du programme pour accéder aux paramètres du programmes
argcest le nombre de paramètres programme etargvcontient tous les paramètres
i n t main(i n t argc, c h a r argv[])
{ .... }
% myprog -opt 125 le
m y p r o g\0 pt \0
− o 2 \0 1 5 f i l e\0 argv[0]
argv[1]
argv[2]
argv[3]
argc == 4
NULL son
Pointeurs Utilisation
Utilisation des pointeurs en C
argc - argv Exemple :
./echo Bonjour à tous ! Bonjour à tous !
echo (v0)
i n t main(i n t argc, c h a r argv[])
{
f o r(i n t i=1; i<argc; i++) printf("%s%c", argv[i],
i<argc•1 ? ' ' : '\n');
r e t u r n EXIT_SUCCESS;
}
echo (v1)
i n t main(i n t argc, c h a r argv[])
{
i f (argc>1) { w h i l e (••argc > 1)
printf("%s ", ++argv);
//écrire le dernier paramètre programme
printf("%s\n", ++argv);
}
r e t u r n EXIT_SUCCESS;
}
son 165/229
Pointeurs Utilisation
Utilisation des pointeurs en C
Pointeurs et structures s t r u c t complexe {
d o u b l e preelle;
d o u b l e pimg;
} c; //c pointeur sur struct complexe
Accès à un champ
( c).preelle ( c).pimg
ou à l’aide de l’opérateur•>(plus lisible)
c•>preelle / est équivalent à / ( c).preelle
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Allocation dynamique
pour réserver de l’espace mémoire dans letas(heap)
espace libre
pile d’évaluation
zone globale tas
inty=0;
int
} x=1;
intmain(void) { voidf(int
...
}
x ) {
5 0
... 1 f(5);
FIGURE–Organisation de la mémoire son
Pointeurs Utilisation
Utilisation des pointeurs en C
Allocation dynamique
la bibliothèque standard libc propose plusieurs fonctions
Fonctions
# i n c l u d e <stdlib.h>
v o i d malloc(size_t size);
v o i d calloc(size_t nbelems, size_t size);
v o i d realloc(v o i d ptr, size_t new_size);
v o i d reallocarray(v o i d ptr, size_t nmemb, size_t size);
ces fonctions renvoient un pointeur sur le 1er octet de la zone allouée (ou réallouée), initialisée à 0 aveccalloc, ouNULLen cas d’erreur son
Pointeurs Utilisation
Utilisation des pointeurs en C
espace libre
pile d’évaluation tas
zone globale int*p;
}
intmain(void) { voidf(void
p=malloc(sizeof(
) {
...
f();
}
*p=5
5
f int));
FIGURE–Organisation de la mémoire son
Pointeurs Utilisation
Utilisation des pointeurs en C
Désallocation
pour libérer de l’espace mémoire alloué dans le tas
Fonction
# i n c l u d e <stdlib.h>
v o i d free(v o i d ptr);
cette fonction libère l’espace mémoire pointé parptr, précédemment alloué parmalloc,calloc,reallocarrayorrealloc
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Exemple
Ce petit exemple met en évidence les problèmes rencontrés lorsqu’on laisse au programmeur la gestion de la désallocation de la mémoire
i n t p, q;
p = malloc(s i z e o f(i n t));
p = 15;
q = p;
printf(" q=%d\n", q); //15 free(q);
printf(" p=%d\n", p); // ? ? ? ?
15
p q
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Structures dynamiques
pour l’implémentation de structures des données (liste, arbres, ...) intérêtsvstableaux : pas de taille max, taille de la structure proportionnelle au nombre d’éléments
par exemple la listel = <15, -7, 52>pourra être représentée par la structure simplement chainée :
next
l 15 −7 52 NULL
item struct noeud
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Structures dynamiques
la structure simplement chaînée
t y p e d e f s t r u c t noeud { i n t item;
s t r u c t noeud next;
} liste;
/ Rôle : alloue un nouveau noeud /
s t r u c t noeud creerNoeud(i n t x)
{
s t r u c t noeud p =
malloc(s i z e o f(s t r u c t noeud));
p•>item = x;
p•>next = NULL;
r e t u r n p;
}
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Pointeurs et fonctions
le nom d’une fonction estun pointeur constant sur fonction
//les fonctions suivantes sont sans paramètre //une fonction renvoyant un int
i n t f(v o i d);
//une fonction renvoyant un pointeur sur int i n t f(v o i d);
//pointeur sur fonction renvoyant un int i n t ( f)(v o i d);
//tableau de pointeurs sur fonction renvoyant un int i n t ( t[])(v o i d);
/ fonction renvoyant un pointeur sur fonction renvoyant un pointeur sur int /
i n t ( f(v o i d))(v o i d);
/ tableau de pointeurs sur fonction renvoyant un pointeur sur int
/
i n t ( t[])(v o i d);
Pointeurs Utilisation
Utilisation des pointeurs en C
Utilisation des pointeurs sur fonction Fonctions paramétriques
d o u b l e aire(d o u b l e a, d o u b l e b, i n t n, d o u b l e ( f)(d o u b l e)) { assert(a<=b);
d o u b l e largeurRect=(b•a)/n;
d o u b l e x=a+largeurRect/2;
d o u b l e aire = 0;
f o r (i n t i=1; i<=n; i++, x+=largeurRect)
//aire =∑i1−1(xi+1−xi)×f((xi+xi+1)/2) aire += largeurRect f(x);
//aire =∑n1(xi+1−xi)×f((xi+xi+1)/2) r e t u r n aire;
}
d o u b l e f1(d o u b l e x) { r e t u r n cos(x)+x; } d o u b l e f2(d o u b l e x) { r e t u r n x; } ...
printf("aire = %f\n", aire(0,M_PI/2, 1000, f1));
printf("aire = %f\n", aire(2,3, 1000, f2));
son
Pointeurs Utilisation
Utilisation des pointeurs en C
Utilisation des pointeurs sur fonction
# d e f i n e MAX 100
e x t e r n v o i d bubble(i n t ), quicksort(i n t ), insertion(i n t );
v o i d ( sort_tab[])(i n t ) = { bubble, quicksort, insertion };
v o i d sort(i n t t, v o i d ( f)(i n t )) {
...; f(t); ...
}
i n t main(v o i d) {
i n t i=0, t[MAX];
w h i l e (i++<3) sort(t, sort_tab[i]);
r e t u r n EXIT_SUCCESS;
}
son