Title: Classe 1 CSI2572
1Classe 1CSI2572
2Autres modificateurs de déclaration de variables
- volatile
- register
- static
- auto
- extern
- const
volatile Indique au compilateur que la variable
risque d'être modifiée par des facteurs
exterieurs au programme en train d'éxécuter
(thread). Les variables déclarées volatile sont
laissé à l'extérieur du processus d'optimization
par le compilateur. volatile int a 4
extern Variable globale, que on peut accéder d'un
autre fichier (aussi placées dans le texte du
programe). extern int e
const Déclare une constante. Ne peut être
assignée après initialisation. const int e 4
static Indique au compilateur que la variable
doit être placée dans le texte du programme
(loadé avant le début de l'éxécution). La
variable devient une variable globale. static
double c 1.3
auto Jamais (ou rarement) indiqué. C'est le
défaut. Indique au compilateur que la variable
doit être placée dans le programe stack. auto
float d 4.3 float d 4.3
register Indique au compilateur que la variable
sera très utilisée, et qu'elle devrait donc être
placée directement dans un des registres du CPU
pour accès direct. Très peu utilisé, et réduira
vitesse d'éxécution si mal utilisé. register char
b 'a'
3Autres Structures de donnéesLes tableaux
/INITIALISATION D'1 TABLEAU / define ROW
2 define COLUMN 3 int main() int n100,
ctr for(ctr 0 ctr lt 99 ctr) nctr
0 int w5 32, 21, 56, 32, 45 char
a "Hello" char b6 'H','e','l','l','o','
\0' int matROWCOLUMN 1,2, 2,6,
5,7 mat02 3
- int a12
- Tableau de 12 éléments, typés entiers
- char a
- Tableau d'éléments typés charactères, taille
- détérminée à l'initialisation (chaine de
- caractères si tableau terminé par '\0')
- float a54
- Matrice de nombres point flottants (5x4)
- Les tableaux sont indexés de 0 à n-1
- (n étant le nombre d'éléments ds le tableau)
4Autres Structure de données ( enum )
int main() enum day Mon10, Tues, Wed45,
Thurs, Fri, Sat70, Sun day T1
Tues day T2 Fri day T3
Sun printf("d\n",T1)
printf("d\n",T2) printf("d\n",T3) re
turn 0
enum
- pour créer des constantes énumérées
11 47 71
5Autres Structure de données ( enum )
struct point double x double y struct
point p p.x 13.2 p.y -4.2 void
f(struct point p) ... struct point f()
struct point p ... return p struct
point p1, p2 ... p1 p2
include ltstdio.hgt int main() struct
Point3D int x
int y int z
struct Point3D point 3,3,6
printf("x d\n", point.x) printf("y
d\n", point.y) printf("z d\n",
point.z) point.y 5 return 0
struct
typedef struct int x
int y int z
Point3D
- pour créer des structures complexes
Point3D point 3, 3, 6
6pointeurs
0X0A2BD
- Une variable qui pointe vers une autre variable
- Une adresse mémoire
int ptr
int ptr int a
int ptr int a ptr a
int ptr int a ptr a a 123
0X0A2B8
ptr
0X0A2B9
0X0A2BA
0X0A2BB
0X0A2BC
0X0A2BD
a
ptr est maintenant initialisé
123
0X0A2BE
pas encore défini (garbage)
7a ptr ptr ptr a
0x0A2BD 0x0A2BD 0x0A2B8 123 123
0X0A2BD
0X0A2B8
ptr
0X0A2B9
0X0A2BA
0X0A2BB
0X0A2BC
0X0A2BD
a
123
0X0A2BE
8Pointeurs (encore)
int a char c int pi char pc void gp
pi a / OK / pi c / TYPE MISMATCH /
pc c / OK / pc a / TYPE MISMATCH /
gp a / OK / gp c / OK /
Les pointeurs aussi sont typés. Mais il existe un
pointeur de type générique. C'est le pointeur de
type void
9Next
- Allocation de mémoire
- Déallocation de mémoire
- Tableaux (n dimensions)
- Arithmetique des pointeurs
- Pointeurs sur fonctions
10Allocation de mémoire
- Dans C comme dans C, il y à 3 manières
dallouer de lespace - mémoire
- Mémoire Statique
- La mémoire est allouée par le linker au début du
programme, et est - libérée lorsque le programme à fini d'éxécuter.
- Mémoire Automatique
- La mémoire est automatiquement allouée, gérée et
libérée pendant - l'éxecution du programme. Les arguments des
fonctions et les - variables locales obtiennent de l'espace de cette
manière - Mémoire Dynamique
- La mémoire est requise explicitement par le
programme(ur). Le - programme(ur) gère et libère la memoire (en
principe).
11Où se trouve la variable?
- compile-time program-text
- variables globales
- variables static
- automatic stack
- variables locales
- parametres de fonctions
- valeur de retour des fonctions
- run-time heap
- malloc
- calloc
- realloc
-
12Les espaces mémoire alloués de manière statiques
ou automatiques ne sont généralement pas 1
problème pour le programmeur (qui
n'a généralement pas besoin de s'en occuper). Il
faut cependant en être conscient pour pouvoir
optimiser ces programmes.
int x / global / int f(int n) int x /
local to f / if (n gt 3) int x / local
to if / ... / a local scope
"out of the blue" / int x
- S T A T I Q U E
- Constantes
- Variables globales
- Variables déclarées static
- A U T O M A T I Q U E
- Variables Locales
- Paramétres de fonctions
- Retours de fonctions
13Allocation de mémoire dynamique
- L'allocation de mémoire dynamique a par contre
tendance à être 1 peu problématique pour le
programmeur. C lui (ou L) qui l'alloue, qui la
gère et qui n'oubli pas de la rendre au systeme
quand il n'en a besoin. Si la job est mal
faite, attendez vous à des problèmes!!! - Le heap sert à l'allocation dynamique de blocs de
mémoire de taille variable. - De nombreuses structures de données emploient
tout naturellement l'allocation de mémoire dans
le heap, comme par exemple les arbres et les
listes. - Le seul risque est la fragmentation du heap, par
allocation et libération successives. Il n'existe
pas en C de mécanisme de "ramasse-miettes"
(garbage collector).
14int x (int)malloc(sizeof(int)) int a
(int)calloc(10,sizeof(int)) x 3 a2 5
free(a) a 0 free(x) x 0
Fonctions de gestion de mémoire (C) void
malloc(size_t size) void calloc(size_t n,
size_t size) void realloc(void ptr,size_t
size) void free(void ptr)
15Demande d'allocation de mémoire (malloc)
include ltstdio.hgt include ltstdlib.hgt main()
char ptr struct s_fiche char nom30
int numero struct s_fiche suiv
fiche ptr (char ) malloc(80) / demande
d'allocation de 80 octets / if ( ptr NULL)
printf("Allocation mémoire impossible\n")
exit(1) if (fiche (struct s_fiche )
malloc(sizeof(struct s_fiche)) NULL)
printf("Allocation mémoire impossible\n")
exit(1) free(fiche) / libération de la
mémoire / free(ptr)
- malloc demande l'allocation d'un bloc de mémoire
de size octets consécutifs dans la zone de
mémoire du heap. - Syntaxe
- include ltstdlib.hgt
- void malloc(size_t size)
- Valeur retournée
- Si l'allocation réussit, malloc retourne un
pointeur sur le début du bloc alloué. Si la place
disponible est insuffisante ou si size vaut 0,
malloc retourne NULL. - Attention Les fonctions d'allocation dynamique
retournent des pointeurs sur des void. Il faut
donc opérer des conversions de types explicites
pour utiliser ces zones mémoire en fonction du
type des données qui y seront mémorisées.
16Demande d'allocation de mémoire (calloc)
include ltstdio.hgt include ltstdlib.hgt int
main() int str NULL str (int )
calloc(10, sizeof(int)) printf("d\n", str9)
free(str) return 0
- La fonction calloc réserve un bloc de taille
nelem x elsize octets consécutifs. Le bloc alloué
est initialisé à 0. - Syntaxe
- include ltstdlib.hgt
- void calloc(size_t nelem, size_t elsize)
- Valeur retournée
- Si succès, calloc retourne un pointeur sur le
début du bloc alloué. Si échec, calloc retourne
NULL s'il n'y a plus assez de place ou si nelem
ou elsize valent 0. - Attention Les fonctions d'allocation dynamique
retournent des pointeurs sur des void. Il faut
donc opérer des conversions de types explicites
pour utiliser ces zones mémoire en fonction du
type des données qui y seront mémorisées.
17Demande d'allocation de mémoire (realloc)
- La fonction realloc ajuste la taille d'un bloc Ã
size octets consécutifs. - Syntaxe
- include ltstdlib.hgt
- void realloc(void ptr, size_t size)
- Valeur retournée
- Si succès, retourne l'adresse de début du bloc
réalloué. Cette adresse peut avoir changé par
rapport à celle fournie en argument. Dans ce cas,
le contenu de l'ancien bloc est copié à la
nouvelle adresse et l'ancienne zone est
automatiquement libérée. Si échec, (pas assez de
place en mémoire ou size à 0), realloc retourne
la valeur NULL - Arguments
- ptr pointeur sur le début d'un bloc mémoire
créé par malloc, calloc, ou realloc. Si ce
pointeur est NULL, realloc équivaut à malloc.
size nouvelle taille du bloc en octets.
182 dimensions (matrices)
double alloc_matrix(int n, int m) double
M (double)calloc(n,sizeof(double)) int
i for(i0 iltn i) Mi
(double)calloc(m,sizeof(double)) return M
19Libération!!
include ltstdio.hgt include ltstdlib.hgt int
main() char str str (char )
malloc(100 sizeof(char)) gets(str) /
saisie d'une chaine de caracteres / /
suppression des espaces en tete de chaine /
while ( str ' ') str / free ne
libere pas toute la zone allouee car ptr ne
designe plus le debut de la zone memoire
allouee par malloc / free(str) return 0
- La fonction free libère un bloc mémoire
d'adresse de début ptr. - Syntaxe
- include ltstdlib.hgt
- void free(void ptr)
- Ce bloc mémoire a été précédemment alloué par
une des fonctions malloc, calloc, ou realloc. - Attention
- Il n'y a pas de vérification de la validité de
ptr. Ne pas utiliser le pointeur ptr après free,
puisque la zone n'est plus réservée. - A tout appel de la fonction malloc ( ou calloc )
doit correspondre un et un seul appel à la
fonction free.
20Déallocation de la mémoire de notre matrice 2
dimensions
void free_matrix(double M, int n) int i
for(i 0 iltn i) free(Mi) free(M)
... free_matrix(M, 5) M 0
21Arithmetique des pointeurs
- Il est possible de déplacer la position d'un
pointeur en lui ajoutant ou en lui retranchant
une valeur entière. Par exemple - ptr_str 1
- Le compilateur aqvance d'un ou plusieur octets
par rapport à la position de ptr_str. - Les entiers ajoutés ou retranchés ont des
tailles scalaires différentes selon le type du
pointeur. En d'autres termes, ajouter ou
soustraire 1 à un pointeur n'équivaut pas à se
déplacer d'un octet, mais à aller à l'adresse
suivante ou précédente.
22Arithmetique des pointeurs
p12 3 ((p 1))2 3 (p1
2) 3 ((p 1) 2) 3
- Le format général du déplacement d'un pointeur
est le suivant - pointeur n
- n est un entier positif ou négatif. pointeur est
le nom de la variable déclarée ainsi - type pointeur
- Le compilateur interprète l'expression pointeur
n comme suit - pointeur n sizeof(type)
23pointeurs sur fonctions
void array_apply(double, int, void
()(double)) void array_apply(double a, int
n, void (f)(double)) int i for(i0 iltn
i) (f)(ai) void triple(double x) x
3 void negate(double x) x - x
... double a10 ... array_apply(a,10,
triple) array_apply(a,10,negate)
- Il est possible de déclarer un pointeur
initialisé avec la valeur gauche (c'est à dire
l'adresse) d'une fonction. On peut ensuite
utilisé de pointeur pour appeler la fonction
référencée - int f()
- int (fp)()
- int g()
-
- int f1()
-
- int f2()
- int (fp)()
- fp f1
- (fp)()
-