Chapitre 1: Rappel du C
Cours systèmes embarqués et DSP
Plan du chapitre
1- Les pointeurs
2- Les Tableaux
3- Les Fonctions
4- Les structures de données
4- Les structures de données
5- Manipulation des bits
6- Portée des variables
7- Préprocesseur
2
ENICarthage- Cours SE-DSP
Les Pointeurs
Partie 1
Qu’est ce qu’un pointeur
Un pointeur est une variable dont le contenu pointe
vers une autre variable.
Le contenu est une adresse d’une autre variable
Un pointeur peut recevoir des valeurs différentes au
cours de l’exécution
Appelé aussi variable d’adresse.
4
L’opérateur d’adresse « & »
Un pointeur est une variable qui contient l'adresse d'une
autre variable.
L'opérateur unaire & donne l'adresse mémoire d'un
objet.
L'instruction :
p = &c;
affecte l'adresse de c à la variable p.
On dit que p pointe sur c.
L'opérateur unaire & s'applique uniquement sur des
objets en mémoire.
5
EXEMPLE1 (éditer et tourner l’exemple 1)
Le format d’affichage d'une variable est %p
(hexadécimal) ou %d (décimal) dans PRINTF
6
DECLARATION DES POINTEURS
Une variable de type pointeur se déclare à l'aide de l'objet
pointé précédé du symbole * (opérateur d'indirection).
char *pc;
int *pi;
float *pr; pr est un pointeur pointant sur un objet de type float
float *pr; pr est un pointeur pointant sur un objet de type float
pc est un pointeur pointant sur un objet de type char
pi est un pointeur pointant sur un objet de type int
L'opérateur * désigne en fait le contenu de l'adresse.
char *pc;
*pc = 34 ;
printf("CONTENU DE LA CASE MEMOIRE: %c\n",*pc);
printf("VALEUR DE L'ADRESSE EN HEXADECIMAL: %p\n",pc);
7
ARITHMETIQUE DES POINTEURS
On peut déplacer un pointeur dans un plan mémoire:
addition,
soustraction,
incrémentation,
décrémentation.
décrémentation.
Ce n’est pas un déplacement de 1 octet!!
Le déplacement signifie aller à l’adresse suivante ou
précédente suivant la taille de la variable.
8
ARITHMETIQUE DES POINTEURS
Le saut des cases mémoire (octets)
dépend des types de variables
in t *p i;
ch ar * p c;
*p i = 0 ;
*p c = 0 x0 a ;
0 0
0 0
0 0
0 0
0 a
pi
p i+ 1
p c
pc + 1
PL AN M E M O IR E
9
ARITHMETIQUE DES POINTEURS
(éditer et tourner l’exemple 2)
10
Pointeurs multiples (tourner l’exemple2)
Plusieurs pointeurs peuvent être dirigés vers un même emplacement
mémoire.
11
Exercices
Exercice 1: Ecrire un programme C qui permet de
créer dynamiquement deux réels, de les initialiser et
de les afficher sur l’écran
Exercice 2: Ecrire un programme C qui permet de
Exercice 2: Ecrire un programme C qui permet de
créer dynamiquement un tableau de 5 entiers, de le
remplir et de déterminer la valeur maximale qu'il
contient
12
ENICarthage- Cours SE-DSP
Les Tableaux
Partie 2
Les tableaux
int T[5];
Nombre
d’éléments
T
indice
T[0] T[1] T[2] T[3] T[4]
Type des
éléments
Nom
int Premiers [4];
En C:
1. Les indices commencent par 0
1. Les indices commencent par 0
2. T[i] : i+1ème élément
Premiers [0] = 2;
Premiers [1] = 3;
Premiers [2] = 5;
Premiers [3] = 7;
printf(“Le 3e nombre premier: %d\n”, Premiers [2]);
printf(“Somme du 2e et du 3e: %d”, Premiers[1]+ Premiers[2]);
Le 3e nombre premier: 5
Somme du 2e et du 3e: 8
14
Utilisation
Indexation par une variable
int T[4];
int i = 3;
T[0]=2; T[1]=3; T[2]=5; T[3]=7;
printf (“L’élément d’indice %d est %d”, i, T[i]);
L’élément d’indice 3 est 7
Parcours d'un tableau à l'aide d'une boucle
int T[4];
int i;
T[0]=2; T[1]=3; T[2]=5; T[3]=7;
for (i= 0; i< 4; i++)
{
Indice 0: Valeur 2
Indice 1: Valeur 3
Indice 2: Valeur 5
Indice 3: Valeur 7
printf (“Indice %d: Valeur %d\n”, i, T[i]);
}
15
Remplir un tableau
Remplir un tableau à l'aide d'une boucle
int T [4], i, x;
for (i= 0; i< 4; i++)
{
printf ("Donnez l'élément n°:%d", i);
scanf (“%d”, &x);
T[i] = x;
scanf (“%d”, &T[i]);
}
}
16
On peut initialiser un tableau lors de sa déclaration
int Tpremiers [4] = {2, 3, 5, 7};
Et même:
int Tpremiers [] = {2, 3, 5, 7};
Par contre, on ne peut pas utiliser l'affectation !
int Tpremiers [4];
Tpremiers = {2, 3, 5, 7};
Exemple: Copie, comparaison: Attention !
On ne peut pas affecter un tableau à un autre par =
int T1 [4] = {2, 3, 5, 7};
int T2 [4];
T2 = T1;
Ni comparer un tableau avec un autre par ==
int T1 [4] = {2, 3, 5, 7};
int T2 [4] = {2, 3, 5, 7};
if (T1 == T2)
printf ("Tableaux identiques.");
else
printf ("Tableaux différents.");
17
Exercice: Comparer le contenu de deux tableaux?
(Tourner l’exemple1 dans dossier tableau)
#include <stdio.h>
void main ()
{
float T1 [4] = {2, 3, 5, 7}, T2 [4];
int i; int Egaux;
for (i = 0; i<4; i++)
{ T2 [i] = T1 [i]; }
Egaux = 1; i = 0;
while ((i < 4) && (Egaux = = 1))
{
if (T1 [i] != T2 [i])
Egaux = 0;
else
i++;
}
if (Egaux = = 1) printf ("Tableaux identiques.");
printf ("Tableaux différents.");
else
}
18
Taille, pointeurs et tableaux
multi dimensions
19
Taille des tableaux
C’est l’espace mémoire occupé par un tableau,
comptabilisé en octets.
Expression 1:
type Tableau[Taille];
type Tableau[Taille];
sizeof(type) * Taille;
Expression 2: en utilisant uniquement le nom
type Tableau[Taille];
sizeof(Tableau);
20
sizeof uniquement pour les tableaux de taille
fixe (Tourner l’exemple2)
Tourner l’exemple et vérifier le résultat ?
21
Taille des tableaux ((Tourner l’exemple3))
22
Tableaux et pointeurs
En déclarant un tableau, on définit automatiquement un
pointeur (on définit en fait l'adresse du premier élément
du tableau).
Les écritures suivantes sont équivalentes:
int *tableau;
int tableau[10];
déclaration
*tableau
tableau[0] le 1er élément
*(tableau+i)
tableau[i]
la valeur du iéme élément
tableau
&tableau[0]
adresse du 1er élément
(tableau + i)
&(tableau[i]) adresse du iéme élement
23
Exercices tableaux
24
Exercice 1
/* Ecrire un programme C qui permet de créer un
tableau statique de 20 entiers et de l'initialiser.
Le programme doit déterminer les valeurs des cases
qui sont divisible par 5*/
25
Exercice 2: Effet de bord
a+=expression ≈ a=a+expression
Si l‘évaluation de a contient un effet de bord, il
n'est effectué qu'une fois
Simuler le programme suivant et interpréter ?
26
Exercice 3: vrai visage du main
Écrire un programme C permettant d’afficher
toutes les variables d’environnement ?
27
Exercice 4
Écrire un programme C permettant d’afficher
l’utilisateur connecté ? (passer " USER" à la fonction
getenv)
28
Exercice 5
Écrire un programme C permettant de lister le
contenu du /home/user/ ?
29
Allocation Dynamique de la
mémoire
Allocation dynamique de mémoire
4 fonctions sont offertes pour gérer l’espace mémoire
dynamiquement:
o malloc()
o calloc()
o realloc()
o free()
Fonctions prédéfinies dans la bibliothèque stdlib.h
Toute allocation dynamique avec malloc(), calloc() et realloc()
nécessite une libération par la suite avec free().
31
Fonction malloc()
Permet d’indiquer la taille de l’emplacement à réserver
Publicité
en mémoire
Syntaxe:
Syntaxe:
#include<stdlib.h>
void* malloc (size_t taille)
Pointeur sur un type
quelconque
Type désignant les tailles en
octets
32
Fonction malloc()
Syntaxe:
#include<stdlib.h>
void* malloc (size_t taille)
Pointeur sur un type
quelconque
quelconque
Type désignant les tailles en
octets
Assure la réservation d’un espace mémoire avec la taille indiquée et retourne :
•
•
l’adresse de l’espace réservé, en cas de succès;
NULL en cas d’échec (pas d’espace mémoire suffisant);
N.B.
pour certains compilateurs le pointeur void*retourné est automatiquement
converti au type de pointeur à gauche de l’affectation
Pour d’autre compilateurs, il est nécessaire de faire explicitement la
conversion (cast)
33
Exécuter l’exemple:
#include<stdio.h>
#include<stdlib.h>
int main() {
int * ptr;
int max;
printf("saisir le nombre d’éléments");
scanf("%d", &max);
/ allocation d’un tableau d’entier de taille max/
/ allocation d’un tableau d’entier de taille max/
ptr = malloc (max * sizeof(int));
/ou encore ptr = (int) malloc (max sizeof(int)); /
if (ptr == NULL)
printf ("Echec d’allocation \n");
else
printf ("succès d’allocation \n");
free (ptr);
return 0; }
34
Fonction calloc()
Permet de réserver un espace mémoire et l’initialiser à 0
Syntaxe:
#include<stdlib.h>
void* calloc (size_t nbre, size_t taille)
Pointeur sur un type
quelconque
Nombre de
cases
Taille de chaque
case
Retourne l’adresse de l’espace réservé en cas de
succès, sinon NULL;
35
Exécuter l’Exemple(Tourner L’exemple1)
ptr1[0] = 2345.1, ptr2[0] = 0.0
ptr1[1] = 7890.6, ptr2[1] = 0.0
ptr1[2] = 9875.8, ptr2[2] = 0.0
Résultats d’exécution
36
Fonction realloc()
Permet de modifier la taille d’un espace déjà réservé à
l’aide de malloc() ou de calloc()
Syntaxe:
#include<stdlib.h>
void realloc (void bloc, size_t taille)
Pointeur sur un type
quelconque
Pointeur sur
l’adresse d’un
espace déjà alloué
Nombre total
d’octets souhaité
Retourne l’adresse de l’espace réservé en cas de
succès, sinon NULL;
37
Remarques importantes
realloc() peut avoir le même effet que la fonction free
quand tailleest égal à 0 :
free(ptr)
realloc(ptr, 0)
realloc()est équivalente à la fonction malloc()si le 1er
argument transmis est NULL
argument transmis est NULL
ptr= realloc (NULL, 10*sizeof(float)) ;
ptr= malloc ( 10*sizeof(float) );
38
Exemple Tourner L’exemple2
39
Les fonctions en C
Partie 3
40
Nous allons apprendre à :
1. Écrire une fonction
2. Appeler une fonction
3. Récupérer le résultat d’une fonction
4. Envoyer des données à une fonction
5. Recevoir des résultats d’une fonction
41
Définition
La définition d’une fonction peut figurer après la fonction
principale main().
Ce qui nécessite sa déclaration précédemment (prototype)
Prototype
Prototype
type_retour nom_fct(type arg1, type arg2…., type argn)
42
Syntaxes
Type du résultat
Nom de la fonction
Données et résultats
Type NomFonction (Liste_Paramètres)
{
Variables et constantes locales
Déclarations;
Instructions;
return resultat;
}
Traitement
Renvoi du résultat
Les paramètres sont optionnels. Les parenthèses sont obligatoires.
43
Programme, fonctions et appel
Déclaration
Fonction
principale
principale
Appel
Définition
#include <stdio.h>
void NomFonction ();
void main()
{
int a, b, valmax;
printf(“ Tapez deux entiers: “);
scanf(“%d %d”, &a, &b);
NomFonction ();
…………………………..
}
void NomFonction()
{
44
}
… ……………….
Exemple:
#include <stdio. h>
Paramètres formels
int max( int v1, int v2);
void main()
{
int a, b, valmax;
printf(“ Tapez deux entiers: “);
scanf(“%d %d”, &a, &b);
scanf(“%d %d”, &a, &b);
Paramètres effectifs
Paramètres effectifs
valmax = max( a, b);
printf(“Maximum des deux valeurs: %d\n”, valmax);
}
int max( int v1, int v2)
{
int maximum;
if (v1 > v2) maximum = v1;
else maximum = v2;
return maximum;
}
Déclaration
Fonction
principale
Appel
Définition
45
Ecrire une fonction et l’appeler
#include <stdio.h>
void Salutation ()
{
printf ("Bonjour\n");
}
void main ()
{
Salutation ();
#include <stdio.h>
void Salutation ();
void main ()
{
Salutation ();
}
}
void Salutation ()
{
printf ("Bonjour\n");
}
}
46
Définition vs déclaration
47
Fonctions: Code retour
Cas 1: La fonction n'a pas de code retour:
1. Dans la fonction:
void NomFonction(){
Rien ou return;}
•
•
La fonction a le type void dans sa déclaration
Aucune instruction return n'est nécessaire
NomFonction ();
2. À l'appel de la fonction:
•
L'appel de la fonction est une instruction
Cas 2: La fonction a un code retour:
1. Dans la fonction:
int NomFonction (){
Return Valeur;}
•
•
La fonction a un type défini à sa déclaration
La dernière instruction est un return d'une valeur de ce type
2. À l'appel de la fonction:
A = NomFonction ();
•
La fonction est appelée dans une expression
48
Fonction avec retour (Tourner L’exemple)
#include <stdio.h>
void CalculerMoy ();
void main()
{
int i;
for (i = 1; i<=50; i++)
exemple1
CalculerMoy ();
}
void CalculerMoy ()
void CalculerMoy ()
{
float N1, N2, M;
printf ("Note 1: ");
scanf ("%f", &N1);
printf ("Note 2: ");
scanf ("%f", &N2);
M=(N10.8)+(N20.2);
printf (“Moyenne: %f", M);
}
49
#include <stdio.h>
CalculerMoy ();
void
float SaisieNote ();
void main()
{ int i;
exemple2
for (i = 1; i<=50; i++)
CalculerMoy ();
}
void CalculerMoy ()
{ float N1, N2, M;
N1 = SaisieNote ();
N2 = SaisieNote ();
M=(N10.8)+(N20.2);
printf (“Moyenne: %f", M);
}
float SaisieNote ()
{ float X;
printf("Note:");
scanf("%f", &X);
return X;
}
Passer des paramètres
50
Principe
Les VALEURS des paramètres effectifs sont copiées dans les
Publicité
paramètres formels
int a, b, valmax;
...
valmax = max( a, b);
...
...
int max( int v1, int v2)
{
int maximum;
if (v1 > v2) maximum = v1;
else maximum = v2;
return maximum;
}
51
La valeur de a est copiée dans v1
La valeur de b est copiée dans v2
La valeur de b est copiée dans v2
L'appel de fonction prend comme
valeur, la valeur renvoyée par
l'instruction return
51
Exemple de transmission de données 1
(Tourner l’exemple3)
int Fact (int x);
int main()
{
int A, F;
printf (“Entrez un entier positif:“); scanf(“%d”, &A);
F = Fact (A);
printf (“Factorielle de %d : %d”, A, F);
}
int Fact (int x)
{
int i, N = 1;
for (i = 1; i<=x; i++)
N = N * i;
return N;
}
52
Passer un tableau en paramètre
(Tourner L’exemple4)
#include <stdio.h>
double MoyenneTableau (int v[], int Taille);
int main()
{
int Valeurs[4] = {2, 4, 3, 8};
double ValeurMoyenne;
ValeurMoyenne = MoyenneTableau (Valeurs, 4);
ValeurMoyenne = MoyenneTableau (Valeurs, 4);
printf(“Moyenne: %f\n”, ValeurMoyenne);
Taille de v
}
double MoyenneTableau (int V[], int Taille)
{
int i, Somme;
Somme = 0;
for (i = 0; i < Taille; i++)
{ Somme = Somme + V[i]; }
return (double)Somme / Taille;
}53
Passer un tableau multidimensionnel
0
1
2
3
4
0 1
1
1
5
2
2
4
3
3
3
4
4
2
5
5
1
54
Passer un tableau multidimensionnel (2)
55
Passer un pointeur en paramètre
56
Retourner une adresse
57
Tableau et pile
58
Messages d’erreurs
59
Exercice: précision sur les flottants
Tourner l’EXERCICE1 et vérifier
60
Exercice 2: améliorer les précisions
Solution: simuler des flottants avec des entiers:
Exemple: n de 0 a 1000000 permet de
représenter des flottants à 2 décimales entre 0 et
10000
Avantages:
précision
précision
vitesse
Inconvénient:
limite des valeurs
61
Exercice 2: Tourner L’EXERCICE2
Utiliser les trois fonctions suivantes pour réaliser
la même somme?
Comparer les deux résultats
62
Localité des variables,
passage par valeur et par
adresse
63
Localité des variables (Tourner L’exemple5)
int main()
{
Visibles : a, b, valmax
NON visibles : maximum, v1, v2
int a, b, valmax;
printf(“ Tapez deux entiers: “);
scanf(“% d% d”, &a, &b);
valmax = max( a, b);
printf(“Maximum de ces deux valeurs: %d”, valmax);
printf(“Maximum de ces deux valeurs: %d”, valmax);
}
int max( int v1, int v2)
{
int maximum;
if (v1 > v2) maximum = v1;
else maximum = v2;
return maximum;
}
64
Visibles : maximum, v1, v2
NON visibles : a, b, valmax
Passage de paramètres
Copie des valeurs des paramètres effectifs dans les paramètres
formels.
void main ()
{
A
B
int A;
int A;
int B;
A = 5;
F1 (A);
B = A;
}
65
X
Y
Y
void F1 (int X)
{
int Y;
int Y;
Y = X;
X = 6;
}
C'est la transmission de paramètres par copie de valeur.
Passage par valeur exemple (Tourner l’exemple6)
void incremente (int val);
void main()
{
int v = 12;
incremente ( v);
incremente ( v);
printf (“v vaut %d”, v);
}
void incremente (int
{
val = val + 1;
val)
}
66
v vaut 12
Passage d’adresses: utilité
quand on doit modifier un paramètre
quand on doit retourner plusieurs valeurs
quand on doit retourner une ou plusieurs valeurs + un code
d'erreur
67
Exemple (Tourner l’exemple7)
void incremente (int * Adr);
void main()
{
int v = 12;
int *pv;
pv = &v;
pv = &v;
printf (“Avant v = %d”, v);
incremente (pv);
printf (“Après v = %d”, v);
}
void incremente (int * Adr)
{
Adr = Adr + 1;
}
68
Avant v = 12
Après v = 13
Après v = 13
Transmission par adresse (Tourner l’exemple)
C'est l’adresse pvqui a été copiée !
void main ()
{
int v = 12;
int v = 12;
int * pv;
v
pv
pv
pv = &v;
incremente (pv);
}
69
Adr
void incremente (int *Adr)
{
Adr = Adr + 1;
}
Exemple 8: écrire une fonction
permettant de permuter le contenu de
deux variables ?
void permuter (int A, int B);
void main()
{
int x, y;
x = 5; y = 18;
permuter (&x, &y);
permuter (&x, &y);
printf (“x = %d et y = %d”, x, y);
}
void permuter (int A, int B)
{
int C;
C = *A;
A = B;
*B = C;}
70
x=18 et y=5
Passage d’adresses
Evolution de la pile
71
Exercice en classe ?
Que contiennent X, Y et Z à la fin de la fonction main () ?
void F2 (int A, int B, int * C);
void F3 (int K, int L, int * M);
void main ()
{ int X, Y, Z;
1
X
Y
2
X= 1; Y = 2; Z = 9;
F2 (X, Y, &Z);
}
}
void F2 (int A, int B, int * C)
{
*C = 4;
F3 (A, B, C);
A = 4;
}
void F3 (int K, int L, int * M)
{
K = 5;
*M = K + L;}
72
X
A
A
K
K
1
1
4
Publicité
1
5
Y
B
B
L
L
2
2
2
2
2
Z
Z
*C
*C
*M
*M
9
7
9
7
4
7
Fonctions: résumé
Qu'il y ait code de retour ou pas, une fonction peut avoir des paramètres
Transmission par copie de valeur pas d'altération (donnée)
Transmission par adresse altération (donnée et résultat)
Un paramètre donnée est transmis par valeur
Un paramètre résultat est transmis par adresse
Un paramètre résultat est transmis par adresse
Attention aux tableaux. Ils sont TOUJOURS (implicitement) transmis
par adresse.
73
Les structures de données :
Partie 4: Les enregistrements
Les énumérés
74
Les enregistrements :
STRUCT
75
Définition de (struct)
struct nom_enreg
{ type champs1;
type champs2;
type champs3;
};
};
Exemple
struct personne
{ char nom[30];
char prenom [20];
int age;
};
76
Déclaration Pratique
typedef struct
{ type champs1;
type champs2;
type champs3;
} nom_enreg;
} nom_enreg;
Exemple
typedef struct
{ char nom[30];
char prenom [20];
int age;
} personne ;
Création de variable de type struct
struct nom_enreg
vble1, vble2, …, vblen;
Exemple:
struct personne
pers1, pers2;
Noter la recommandation du mot clé struct dans l’instanciation
struct
syntaxe un peu lourde d’où la nécessité de typedef
Un typedef allège l’écriture:
typedef struct personne s_pers
….
s_pers
pers1, pers2;
77
Accès aux champs : avec l’opérateur (.)
struct nom_enreg
vble1, vble2, …, vblen;
nom_enreg.champs
Exemple:
Exemple:
struct personne pers1, pers2;
pers1.prenom=“Salah”;
pers1.age = 20;
printf(“l’age de M.%s est:%d”, pers1.prenom,pers1.age);
78
Initialisation des (struct)
Il est possible d’initialiser un enregistrement lors de
sa déclaration
struct nom_enreg {val1, val2, …, valn};
Exemple:
struct pers1 = {“salah”, “ali”, 15}
L’initialisation peut être également par lecture ou
bien par affectation directe
Exemple:
pers1.prenom=“Salah”;
scanf(“%s”, &pers1.prenom);
79
Tableaux de structures (struct)
Chaque case du tableau contient un élément de type structure
struct point
{
int absc;
int ord;
};
struct point courbe[50];
struct point courbe[50];
/Accès à l’abscisse de la case de d’indice i/
courbe[i].absc = 5;
Initialisation lors de la déclaration du tableau
struct point courbe[3]= {{5,2},{6,8},{9,3}};
80
Exemple1: (courbe + points)
Déclarer une structure point définie par son abscisse
et son ordonnée.
Dans le main(), définir un rectangle formé de 4 points
81
Imbrication de structures (exemple2)
struct date
{ int jour;
int mois;
int an;
};
struct personne
{char nom[30];
char prenom [20];
date dat_nais;
};
……
/saisie de la date d’une vble pers1 /
Scanf("%d %d %d", &pers1.dat_nais.jour, &pers1.dat_nais.mois,
&pers1.dat_nais.an);
82
Passage d’une structure en paramètre
d’une fonction
Passage par valeur
struct point
{ int absc;
int ord;
};
/ prototype de fonction/
void fct(struct point y);
83
Tourner l’Exemple3:
int main()
{ struct p1;
p1.absc = 5; p1.ord = 3;
printf(“valeurs avant appel : %d %d”,
p1.absc, p1.ord);
fct (p1);
printf(“valeurs après appel : %d %d”,
printf(“valeurs après appel : %d %d”,
p1.absc, p1.ord);
return 0;
}
void fct (struct point s)
{s.absc = 0; s.ord = 0;}
valeurs avant appel : 5 3
valeurs avant appel : 5 3
84
Pas de
modification
Passage par valeur: inconvénient
85
Passer une structure par adresse
86
Précautions de passages en paramètres
87
Exemple: (tourner l’exemple4)
int main()
{ struct p1;
p1.absc = 5; p1.ord = 3;
printf(“valeurs avant appel : %d %d”,
p1.absc, p1.ord);
fct (&p1);
printf(“valeurs après appel : %d %d”,
printf(“valeurs après appel : %d %d”,
p1.absc, p1.ord);
return 0;
}
void fct (struct point * s)
{s->absc = 0; s->ord = 0;}
valeurs avant appel : 5 3
valeurs avant appel : 0 0
88
Modification
effectuée
Résumé
Une variable de type structure peut être :
Variable locale à une fonction
Variable globale à un programme
Retour d’une fonction
Retour d’une fonction
Paramètre d’une fonction
89
Les énumérations:
ENUM
90
Définition
Le type énuméré enumpermet de déclarer des
constantes entières nommées
Ceci donne plus de lisibilité aux programmes
91
Déclaration
Syntaxe:
enum tag {liste_enumeree} liste_variables;
tag: le nom de l’énumération
Liste_variables: liste des variables de type tag
Liste_enumeres: liste de noms énumérées représentant
des constantes entières.
Exemple:
• enum automobile {4chv, 5chv, 6chv};
Il es possible de définir des variables de type enum ainsi:
enum automobile japonaise, américaine;
Équivaut aussi à:
enum automobile {4chv, 5chv, 6chv} japonaise, américaine;
92
Affecter des valeurs aux noms énumérés
Les éléments des listes énumérées sont incrémentés
de 0 à n. Exemple:
o enum automobile {4chv, 5chv, 6chv} japonaise, américaine;
o 4chv = 0, 5chv= 1 et 6chv=2
Il est possible d’affecter d’autres valeurs entières:
o enum automobile {4chv=60, 5chv=30, 6chv=10};
o 4chv représente le nombre 60
o 5chv représente le nombre 30
o 6chv représente le nombre 10
o enum automobile {4chv=60, 5chv=30, 6chv};
o 4chv représente le nombre 60
o 5chv représente le nombre 30
o 6chv représente le nombre 31
31= 30 + 1
93
Exemple (tourner l’exemple1)
typedef struct { int absc; int ord; }point;
typedef enum { dim =1, lun, mardi, merc, jeudi, vend, samedi }Jours;
dim: 1
Lun:2
Mar:3
Mer:4
Jeu :5
Jeu :5
Ven:6
Sam:7
int main()
{
Jours j1, j2, j3,j4, j5;
Jours j1, j2, j3,j4, j5;
point P1 = {52,9};
j1= merc; j2= vend; j3= dim; j5= samedi;
j4= 2;
printf(" \n Taille ENUM Jours = %d \n ", sizeof (j1));
printf(" \n Taille stuct Point = %d \n ", sizeof (P1));
printf("\nLe jours J1 =%d!\n", j1);
printf("Le jours J2 =%d!\n", j2);
return 0;
}
94
Exemple: conversion minuscule majuscule
(Editer et tourner l’exemple(optionnel))
95
Exemple: conversion minuscule majuscule
96
Exemple: conversion minuscule majuscule
POETE 1
POETE 2
POETE 3
97
TYPEDEF
98
TYPEDEF
99
TYPEDEF
100
Publicité
Manipulation des bits
Partie 5
Opérateurs bits à bits
102
Opérateur &
103
Opérateur |
104
Opérateur ^
105
Opérateur unaire ~
106
Exercice1
Déclarer deux variables A et B non signées et
codées sur 8 bits, initialisées ?
Si A > B complémenter A, sinon complémenter B ?
Forcer les bits pairs de A à 1 et les bits impairs à 0 ?
Copier les bits 3, 4 et 5 de A dans les bits 2,3 et 4
Copier les bits 3, 4 et 5 de A dans les bits 2,3 et 4
respectivement?
Inverser l’état du bit 7 de B ?
107
Décalage à gauche
108
Décalage à gauche (tourner l’exemple1)
109
Décalage à droite
110
Exercice: Décalage circulaire à gauche ?
(tourner l’exemple2)
111
Exercice: Décalage circulaire à droite ?
(tourner l’exemple3)
112
Décalage d’un bit seul
113
Tester le nième bit (tourner l’exemple4)
114
Mettre à 1 le nième bit (tourner l’exemple5)
OU bit à bit entre la valeur à tester et 1<<n
115
Mettre à 0 le nième bit (tourner l’exemple6)
116
Exercice 2: Affecter le nième bit ?
(Tourner l’exercice 2 en se basant sur les deux fonctions suivantes)
117
Portée et classes
d’enregistrement
Partie 6
Thèmes traités
Porté locale
Portée des fichiers
Portée globale
Indicateur auto
Indicateur auto
Indicateur STATIC
Indicateur STATIC
Indicateur REGISTER
Indicateur REGISTER
Indicateur EXTERN
Indicateur EXTERN
Modificateur CONST
Modificateur VOLATILE
119
ENICarthage- Cours SE-DSP
Portées globale et locale
120
ENICarthage- Cours SE-DSP
Portée locale
Un bloc est un ensemble d’instructions limitées par
deux accolades { …}
Une variable déclarée dans un bloc d’instructions a
une portée locale
int main()
int main()
{
{
int i; /portée locale /
int i; /portée locale /
…
…
…
return 0;
}
Une variable ayant une portée locale est appelée une
variable locale.
121
ENICarthage- Cours SE-DSP
Portée d’un bloc imbriqué (tourner Exemple1)
Deux variables de mêmes noms déclarées dans deux blocs
imbriqués sont comme suit:
La variable du bloc extérieur est masquée par celle du bloc intérieur.
int main()
{
BLOC EXTERNE: i = 32
BLOC EXTERNE: i = 32
BLOC INTERNE
i=0,
i=1,
……… ……….
……… ……….
……… ……….
j=10
j=9
i=9,
i=10,
BLOC EXTERNE: i = 32
j=1
j=0
}
122
int i=32; / portée du bloc externe main /
printf(" debut du BLOC EXTERNE : i = %d", i);
{ / début du bloc interne/
int i,j; / i masque le i du BLOC externe /
for(i=0,j=5;i<=5;i++,j--){
printf("BLOC interne:i= %2d et j = %2d", i,j);
}
}/ fin du bloc interne/
printf(" fin du BLOC EXTERNE : i = %d", i);
return 0;
ENICarthage- Cours SE-DSP
Portée globale
Une variable est globale lorsqu’elle est déclarée en
dehors de toute fonction
Elles sont visibles de tous les fichiers constituant
l’exécutable
l’exécutable
int X= 0; /portée globale/
int X= 0; /portée globale/
float y= 0.0; /portée globale /
float y= 0.0; /portée globale /
int main()
int main()
{
int i; /portée locale /
.
.
.
return 0;
}
123
ENICarthage- Cours SE-DSP
Relations entre variables globales et
locales (tourner Exemple2)(optionnel)
Une variable locale masque une autre globale ayant le même nom.
FUNCTION1 :
x= 1234, y=1.234567
BLOC PRINCIPAL :
BLOC PRINCIPAL :
x= 4321, y=1.234567
FUNCTION1 :
x= 1234, y=1.234567
BLOC IMBRIQUE:
x= 4321, y=7.654321
124
ENICarthage- Cours SE-DSP
Indicateurs de classes de
stockage
125
ENICarthage- Cours SE-DSP
Indicateur auto
En C une variable désigne à la fois son emplacement et sa
durée de vie
auto spécifie que l’emplacement occupé par une variable
auto spécifie que l’emplacement occupé par une variable
est temporaire.
est temporaire.
L’espace réservée peut être transféré ou effacé lorsque
L’espace réservée peut être transféré ou effacé lorsque
celle-ci se trouve hors de portée.
Seules les variables locales peuvent être déclarées auto
Rarement employée
126
ENICarthage- Cours SE-DSP
Indicateur static pour une variable locale
Concerne les variables locales et globales
Durée de vie étendue à l’ensemble du programme pour une variable locale
static:
Lorsque la fonction rend la main au programme, l’emplacement réservée à la
variable statique n’est ni effacé ni transféré.
1, 2, 3, 4, 5
1, 2, 3, 4, 5
(tourner Exemple1)
127
ENICarthage- Cours SE-DSP
Simulation de l’exemple
appel de fonction numéro: 1
0 + 5 = 5
appel de fonction numéro: 2
1 + 4 = 5
appel de fonction numéro: 3
2 + 3 = 5
2 + 3 = 5
appel de fonction numéro: 4
3 + 2 = 5
appel de fonction numéro: 5
4 + 1 = 5
Noter ici l’incrémentation de
counter à chaque appel
d’addition, sans perdre
l’ancienne valeur après
retour à la fonction main.
128
ENICarthage- Cours SE-DSP
Indicateur STATIC pour une variable globale
En C, la portée de fichier est attribuée à toute variable
globale déclarée avec l’indicateur static
Elle sera accessible de la déclaration à la fin du fichier
source du programme.
int x =0;
static int y =0; /portée de fichier /
static int y =0; /portée de fichier /
static float y =0.0; /portée de fichier /
int main()
{
int i;
…
return 0;
}
129
ENICarthage- Cours SE-DSP
Indicateur STATIC pour une variable globale
130
ENICarthage- Cours SE-DSP
Indicateur STATIC pour une variable globale
131
ENICarthage- Cours SE-DSP
Indicateur Register
Permet de stocker les variables du programme
dans les registres du CPU plutôt que dans la
mémoire.
Accès rapide
Le stockage n’est pas automatique, le
compilateur vérifie d'abord la possibilité
compilateur vérifie d'abord la possibilité
On ne peut pas extraire l’adresse déclarée en
tant que register
132
ENICarthage- Cours SE-DSP
Indicateur Register
133
ENICarthage- Cours SE-DSP
Indicateur EXTERN
Visible dans tous les fichiers sources constituant
l’exécutable
Pour utiliser une variable globale dans plusieurs
fichiers, il faut la déclarer comme étant extern dans
fichiers, il faut la déclarer comme étant extern dans
chacun des fichiers.
134
ENICarthage- Cours SE-DSP
Indicateur EXTERN
135
ENICarthage- Cours SE-DSP
Indicateur EXTERN (Problème)
(Exemple 2)
136
ENICarthage- Cours SE-DSP
Indicateur EXTERN (SOLUTION)
(Exemple 2)
137
ENICarthage- Cours SE-DSP
Modificateurs des classes de
stockage
138
ENICarthage- Cours SE-DSP
Définition
Ceux sont des qualificateurs définissant la portée
des variables.
On distingue:
const
volatile
139
ENICarthage- Cours SE-DSP
Qualificateur const
const verrouille le contenu d’une variable en mise à
jours après initialisation.
Exemple: la variable pi est protégé en écriture
après cette opération d’affectation.
après cette opération d’affectation.
const double pi = 3.141593;
Publicité
const char str[]= "cela est un tab...