Vous êtes sur la page 1sur 31

Algorithmique et Langage C

Algorithmique et Langage C
www.polytech.unice.fr/~vg/fr/enseignement/xidian

Granet Vincent - vg@unice.fr

Xi’an - Octobre 2015 - Mai 2024


Algorithmique et Langage C
Sommaire

Sommaire

1 Sommaire 2 Les tableaux

2 Introduction 2 Chaînes de Caractères

2 Actions élémentaires 2 Pré-processeur C

2 Types élémentaires 2 Structures et Unions

2 Expressions 14 Pointeurs

2 Actions Structurées 15 Compilation séparée

2 Routines

2 Énoncés Itératifs
2/233
Algorithmique et Langage C
Pointeurs

Les Pointeurs

148/233
Algorithmique et Langage C
Pointeurs

Pointeurs

Définition
un pointeur est une adresse qui désigne une valeur en mémoire.
l’accès à la valeur pointée se fait de façon indirecte.

p 125.38

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 pointeurs sur
réels.
dans les langages modernes (e.g. Java), mais aussi dans les langages
fonctionnels (e.g. Lisp), la notion de pointeur disparaît.

149/233
Algorithmique et Langage C
Pointeurs

Pointeurs en C

les bases
déclaration : T *p (e.g. double *p)
les pointeurs sont typés ⇒ compatibilité obligatoire pour l’affectation !
Conversions
implicite pour n’importe quel pointeur avec void *
pour les autres une conversion explicite est nécessaire
#define NULL ((void *) 0) //dans <stddef.h>
En C les pointeurs sont très utilisés. les programmes sont :
plus compacts
plus efficaces
mais bien moins lisibles
et sujets à plus d’erreurs

150/233
Algorithmique et Langage C
Pointeurs

Pointeurs en C

Exemples de déclarations

i n t *p1, *p2; //deux pointeurs sur int


char *p3, p4; //un pointeur sur char, un char
char **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

151/233
Algorithmique et Langage C
Pointeurs

Pointeurs en C

Opérations de bases
* indirection (déréférencement)
& adresse de (référencement)

{ int *pi, i, j, *q = NULL;

pi i j q
i = 10; 10

pi = &i; 10

j = *pi; 10 10

(*pi)++; 11 10

q = pi; 11 10
}

152/233
Algorithmique et Langage C
Pointeurs

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

153/233
Algorithmique et Langage C
Pointeurs

Pointeurs en C

T *p, *q;

∆ ∆ ∆ = sizeof(T)
0 max

p−1 p p+1 p+2 q

q−p // = 5

154/233
Algorithmique et Langage C
Pointeurs

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

155/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Simulation transmission par référence


quand une fonction doit renvoyer plus d’un résultat

FAUX OK

v o i d swap( i n t a, i n t b) v o i d swap( i n t *a, i n t *b)


{ {
i n t aux; i n t aux;
aux = a; a = b; b = aux; aux = *a; *a = *b; *b = aux;
} }
... ...
i n t x=2, y=3; i n t x=2, y=3;
//échanger x et y //échanger x et y
swap(x, y); swap(&x, &y);
//x=2, y=3 //x=3, y=2

156/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Pointeurs et tableaux
pointeurs et tableaux sont des notions très proches
un tableau est un pointeur constant sur le premier élément du tableau.
t[i] ⇔ *(t+i)
t[i][j] ⇔ *(*(t+i)+j)

i n t *p, t[8];
char *s = "hello";

p = t;
p = &t[0]; //idem
/*
t[2]==*(t+2)==*(p+2)==p[2]
s[2]==*(s+2)==*("hello"+2)=="hello"[2]
*/

157/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Différence entre pointeurs et tableaux

char t[9] = "hello"; t h e l l o \0

char *p = "hello"; p h e l l o \0

p++; //OK
t++; //KO

printf("%ld %ld\n", s i z e o f (p), s i z e o f (t));


//8 9

158/233
Algorithmique et Langage C
Pointeurs

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 tramsise par valeur !

Notation de tableau Notation de pointeur

v o i d reset( f l o a t t[], c o n s t i n t n) v o i d reset( f l o a t *t, c o n s t i n t n)


{ {
f o r ( i n t i=0; i<n; i++) f o r ( i n t i=0; i<n; i++)
t[i] = 0.0; *t++ = 0.0;
} }
... ...
f l o a t ftab[MAX]; f l o a t ftab[MAX];
reset(ftab, MAX); reset(ftab, MAX);

159/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C


Pointeurs et matrice

v o i d reset( d o u b l e mat[][N], c o n s t i n t m, c o n s t 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[], c o n s t i n t m, c o n s t 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, c o n s t i n t m, c o n s t 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;
}

160/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Chaînes de caractères et pointeurs


une chaîne de caractères est un tableau de caractères, donc un pointeur.

strlen strcpy

/* /*
* Rôle : renvoie la longueur de * Rôle : affecte la chaîne s2
* la chaîne de caractères s * à s1 (i.e. s1 = s2)
*/ */
i n t strlen( c o n s t char *s) char *strcpy(char *s1, c o n s t char *s2)
{ {
char *p = s; char *p = s1;

w h i l e (*s++) /* vide */; w h i l e (*s1++ = *s2++)/* vide */;


r e t u r n (s−1)−p; r e t u r n p;
} }

161/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Paramètres programmes
le support d’exécution peut transmettre à la fonction main deux (ou
trois) paramètres au démarrage du programme pour accéder aux
paramètres du programmes
argc est le nombre de paramètres programme et argv contient tous les
paramètres

argc == 4
i n t main( i n t argc, char *argv[])
argv[0] m y p r o g \0
{ .... }
argv[1] − o p t \0
argv[2] 1 2 5 \0
% myprog -opt 125 file argv[3] f i l e \0
NULL

162/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C


argc - argv
Exemple :
./echo Bonjour à tous !
Bonjour à tous !

echo (v0) echo (v1)

i n t main( i n t argc, char *argv[]) i n t main( i n t argc, char *argv[])


{ {
f o r ( i n t i = 1; i < argc; i++) i f (argc>1) {
printf("%s%c", argv[i], w h i l e (−−argc > 1)
i<argc−1 ? ’ ’ : ’\n’); printf("%s ",*++argv);
} printf("%s\n",*++argv);
}
}

163/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Pointeurs et structures

s t r u c t complexe {
d o u b l e préelle;
d o u b l e pimg;
} *c; //c pointeur sur struct complexe

Accès à un champ

(*c).préelle
(*c).pimg

ou à l’aide de l’opérateur −> (plus lisible)


c−>préelle //ou
c−>pimg

164/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Pointeurs et structures
Une structure ne peut pas s’auto-référencer, c’est-à-dire être récursive,
et donc posséder un champ de son propre type.
Les déclarations de types récursifs utilisent les pointeurs

s t r u c t noeud {
i n t item;
s t r u c t noeud *next;
} *l;

165/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C


Allocation dynamique
pour réserver de l’espace mémoire dans le tas (heap)

tas

void f(void ) { espace libre


int y;
...
}

int x; pile d’évaluation


int main(void ) {
f();
... zone globale
}

Figure: Organisation de la mémoire (1)

166/233
Algorithmique et Langage C
Pointeurs

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);

ces fonctions renvoient un pointeur sur le 1er octet de la zone allouée


(initialisée à 0 avec calloc), ou NULL en cas d’erreur

167/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Allocation dynamique

tas
5

void f(void ) { espace libre


int *p;
p=malloc(sizeof(int));
f
} *p = 5;
pile d’évaluation
int main(void ) {
f();
zone globale
...
}

Figure: Organisation de la mémoire (2)

168/233
Algorithmique et Langage C
Pointeurs

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é par ptr, précédemment


alloué par malloc, calloc or realloc

169/233
Algorithmique et Langage C
Pointeurs

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 q
*p = 15;
15
q = p;
printf("*q=%d\n", *q); //15
free(q);
printf("*p=%d\n", *p); //????

170/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Structures dynamiques
pour l’implémentation de structures des données (liste, arbres, ...)
intérêts vs tableaux : pas de taille max, taille de la structure
proportionnelle au nombre d’élements
par exemple : la liste l = <15, −7, 52> pourra être représentée par
la structure simplement chaînée :
next
l 15 −7 52
item

NULL

171/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Structures dynamiques
une structure simplement chaînée

t y p e d e f s t r u c t noeud { /* Rôle : alloue un nouveau noeud */


i n t item; liste créerNoeud( c o n s t i n t x)
s t r u c t noeud *next; {
} *liste; liste 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;
}

172/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C


Pointeurs et fonctions
le nom d’une fonction est un pointeur constant sur fonction

//Note : 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 );

173/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C


Utilisation des pointeurs sur fonction
Fonctions paramétriques

/*
* Antécédent: a⩽b et n>1
* Rôle : calcule l’aire de la fonction continue f surl’intervalle[a,b]
* Algorithme : méthode des rectangles,n est le nb de rectangles calculés
*/
d o u b l e aire( c o n s t d o u b l e a, c o n s t d o u b l e b, c o n s t i n t n,
d o u b l e (*f)( c o n s t 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 = ∑i−11 (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;
174/233
}
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C

Utilisation des pointeurs sur fonction


Fonctions paramétriques

d o u b l e f1( c o n s t d o u b l e x) { r e t u r n cos(x)+x; }
d o u b l e f2( c o n s t d o u b l e x) { r e t u r n x; }

i n t main( v o i d ) {
printf("aire=%f\n", aire(0, M_PI/2, 1000, f1));
printf("aire=%f\n", aire(2, 3, 1000, f2));
r e t u r n EXIT_SUCCESS;
}

175/233
Algorithmique et Langage C
Pointeurs

Utilisation des pointeurs en C


Utilisation des pointeurs sur fonction
Fonctions paramétriques

# 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;
}

176/233

Vous aimerez peut-être aussi