Cours systèmes embarqués et DSP - Chapitre 1: Rappel du C

Page 1 sur 159Lecteur de document UniversityLib

Cours systèmes embarqués et DSP - Chapitre 1: Rappel du C

Embedded Systems and Digital Signal Processing (DSP) · lab

Browse all électronique et automatique documents

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

Advertisement

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

Advertisement

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

Advertisement

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

Advertisement

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;

Advertisement

 const char str[]= "cela est un tab...