Programmation en C Représentation des variables en...

22
Programmation en C Représentation des variables en mémoire 20170206 Gabriel Risterucci

Transcript of Programmation en C Représentation des variables en...

Page 1: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

Programmation en CReprésentation des variables en mémoire

2017­02­06

Gabriel Risterucci

Page 2: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

1 ‐ SOMMAIRE DU COURSPetits rappelsDiverses representationsLe binaireComplément à 2La mémoireLes charLes intLes float/doubleLes opérateurs bit à bitDépassement de capacitéCast

Page 3: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

2 ‐ PETITS RAPPELSDifférents types de variables : char, int, float…Ces variables ont une taille : un octet, 4 octets…Un octet = 8 bits

On peut également appliquer des modificateurs / variations :

Valeur signée / non signée (signed, unsigned…)Adresse (*)

Page 4: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

Valeur :

Hexadécimal (base 16) : 13Décimal (base 10) : 19Octal (base 8) :23Binaire (base 2) : 10011 0 0 0 1

1

0 0 1 1

3

3 ‐ DIVERSES REPRESENTATIONSchar a = 19;

Chiffres base 16 : 0 1 2 3 4 5 6 7 8 9 A B C D E FChiffres base 10 : 0 1 2 3 4 5 6 7 8 9Chiffres base 2 : 0 1

Dans un nombre, le chiffre le moins significatif est appelé de poids faible, le chiffre le plussignificatif est appelé de poids fort.

Page 5: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

Bin. → Dec. 0 → 0 1 → 1 10 → 2 11 → 3

Bin. → Dec. 0001 → 1 (2^0) 0010 → 2 (2^1) 0100 → 4 (2^2) 1000 → 8 (2^3)

4 ‐ LE BINAIRE [1/2]La representation binaire est une representation en base 2 des nombres.

Chaque « chiffre » successif represente donc une puissance de 2.

En base 10, multiplier un nombre par 10 équivaut à « ajouter » un zéro : 34 x 10 = 340. Enbinaire, la même chose se passe lorsque l'on multiplie par 2 : 1012 x 210 = 10102.

Cela ressort si on reste sur la representation binaire: 101 x 10 = 1010.

Page 6: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

5 ‐ LE BINAIRE [2/2]Il ne s'agit là que d'une façon de representer l'information. D'un point de vue sémantique,3410=1000102=0x22.

En pratique, l'ensemble des outils informatiques manipulent les données sous leur representationbinaire.

On réalise « en binaire » les mêmes opérations qu'habituellement : addition, soustraction, etc.La seule différence est qu'on n'a que deux chiffres à disposition. Les autres règles de calcul(retenues, etc.) restent les mêmes.

Page 7: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

6 ‐ COMPLÉMENT À 2 [1/3]Le complément à 2 est utilisé pour representer les nombres négatifs. Il s'agit d'unetransformation sur la représentation binaire d'un nombre.

Exemple sur un octet (signed char) : ­17

1. Representation binaire de 17 : 000100012. Complément à 1 (=inversion) : 111011103. Ajouter 1 : 11101111

Sur un octet, ‐1710 = 111011112

Avantages de cette representation : les opérations basiques (addition, soustraction) fonctionnentsans aucune transformation. On peut également déterminer le signe facilement en testant le bitde poids fort.

Page 8: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

Addition

Somme de ­17 et 12 :

11101111 = ‐17 00001100 = 12 ‐‐‐‐‐‐‐‐‐ 11111011Complément à 2 :11111011 00000100 00000101000001012=5 Donc ‐17 + 12 = ‐5

Dépassement de capacité

Que se passe­t­il lorsque l'on excède lespossibilité d'un octet ? On parle dedépassement de capacité.

L'utilisation du complément à 2 estcompatible avec cette notion :

11111111 = ‐1 +00000001 = 1 ‐‐‐‐‐‐‐‐‐ 00000000 = 0

7 ‐ COMPLÉMENT À 2 [2/3]

Page 9: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

8 ‐ COMPLÉMENT À 2 [3/3]On utilise le complément à 2 pour les nombres signés.

Il s'agit là d'une façon d'interpréter la valeur en mémoire !

Si l'on « sait » qu'un octet represente une valeur signée, alors on peut déterminer son signe avecson bit de poids fort, et si ce dernier vaut 1, déterminer la valeur en utilisant le complément à 2.

Page 10: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

9 ‐ LA MÉMOIREToutes les informations se situent en mémoire, notamment :

Les variablesLe contexte des appels de fonctions

La mémoire vive est analogue à un « ruban » de cases pouvant chacune contenir un octet.Chaque case est identifiée par son adresse, c'est à dire son numéro.

Question : comment stocker des valeurs plus longues qu'un octet en mémoire ?

Page 11: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

Non signé

Intervalle : 0→255 Aucune modification

Signé

Intervalle : ­128→127 Representation : complément à 2

char A = 41; char A2 = 'A';

Bien que le type s'appelle char il s'agit biend'un type numérique sur lequel on peuteffectuer des calculs.

10 ‐ LES CHARTaille : 1 octet. On utilise régulièrement le type char pour modifier la mémoire octet par octet.

Les constantes littérales utilisés pour representer un octet peuvent être des nombres entiers oudes « caractères » representé entre guillement simple. Les deux variables suivantes ont la mêmevaleur :

Page 12: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

11 ‐ LES INT [1/2]Taille : variable (8, 16, 32, 64 bits ou 1, 2, 4, 8 octets)

Pour les entiers signé, le complément à 2 est utilisé.

Les representations de plus d'un octet sont découpées en octets dans un ordre qui dépend del'architecture courante : Little­Endian ou Big­Endian

De façon analogue aux bits de poids fort/faible on découpe les entiers en octets de poidsfort/faible. Exemple sur 2 octets :

149210 = 00000101 110101002

La première moitiée est l'octet de poids fort, la deuxième l'octet de poids faible. Le rangementdans les octets de la mémoire commence donc par l'octet de poids fort en mode Big­Endian, etl'octet de poids faible en mode Little­Endian.

Page 13: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

Little­Endian :… C0 AF E3 00 …

Big­Endian :… 00 E3 AF C0 …

12 ‐ LES INT [2/2]Même exemple sur 4 octets :

1492166410 = 00000000 11100011 10101111 110000002 = 0x00E3AFC0

Représentations de valeurs entières constantes :

1492 : valeur entière signée de la taille d'un int, base 101492u : valeur entière non signée de la taille d'un int, base 100x05D4 : valeur entière signée de la taille d'un int, base 1602724 : valeur entière signée de la taille d'un int, base 8

→ → → → → → → → → →

Page 14: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

13 ‐ LES FLOAT/DOUBLE [1/2]Les float/double representent les nombres dit « à virgule flottante ».

Leur précision se mesure en nombre de chiffres significatifs. Ils ne doivent cependant pas êtreutilisé pour réaliser des calculs de précisions sur des valeurs décimales, car leur representationbinaire ne permet pas de representer l'ensemble des nombres décimaux.

Leur representation en mémoire est complexe, et est découpée en trois parties : le signe, lamantisse et l'exposant.

Sans entrer dans les détails, un nombre à virgule flottante est representé en notation scientifiquesous la forme suivante :

signe mantisse .2exposant

Page 15: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

14 ‐ LES FLOAT/DOUBLE [2/2]On manipule beaucoup moins souvent les bits d'un float/double que d'un int.

Représentations de valeurs à virgule flottante :

.63 : double34. : double34.63 : double34.f : float34.63f : float

La representation interne des float/double est standardisée dans la norme IEEE 754.

Page 16: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

15 ‐ LES OPÉRATEURS BIT À BIT [1/4]Les opérateurs bit à bit agissent sur la representation binaire des variables.

Ils permettent :

D'appliquer des opérations logiques au niveau des bits d'une variableD'effectuer des décalages

Comme pour les autres opérateurs, les opérateurs bit à bit utilisent le type le plus large deleurs opérandes pour effectuer le calcul et retourner leur resultat.

On parle en anglais d'opérateurs bitwise.

Page 17: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

a++ a‐‐ (function) [array]~a !a ++a ‐‐a ‐a (cast) *a &a sizeofa*b a/b a%ba+b a‐ba<<b a>>ba<b a<=b a>b a>=ba==b a!=ba&b

a^ba|ba&&ba||ba&=b a^=b a|=b a<<=b a>>=b a=b a+=b a‐=ba*=b a/=b a%=ba,b

16 ‐ LES OPÉRATEURS BIT À BIT [2/4]Voici les opérateurs logiques par ordre de priorité :

On peut bien évidemment utiliser ces opérateurs dans des expressions avec d'autres; il n'y a pasde différence entre opérateurs bit à bit, opérateurs logiques et opérateurs arithmétiques.

Page 18: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

a&b10101010 11110000 ‐‐‐‐‐‐‐‐ 10100000

a^b10101010 11110000 ‐‐‐‐‐‐‐‐ 01011010

a|b10101010 11110000 ‐‐‐‐‐‐‐‐ 11111010

17 ‐ LES OPÉRATEURS BIT À BIT [3/4]Les opérations bit à bit

~a : inverse tous les bits d'une variablea&b : retourne une valeur dont chaque bit est le résultat d'un ET logique appliqué à ses deuxopérandes bit à bita^b : retourne une valeur dont chaque bit est le résultat d'un XOR logique appliqué à sesdeux opérandes bit à bita|b : retourne une valeur dont chaque bit est le résultat d'un OU logique appliqué à ses deuxopérandes bit à bit

Page 19: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

Lors d'un décalage à gauche (<<) Les bits « introduits » à droite sont définis à 0.01010011 << 3 ⇒ 10011000

(cela revient à multiplier la valeur par 210)

Lors d'un décalage à droite (>>) Sur un nombre non signé : les bits« introduits » à gauche sont définis à 0. Sur un nombre signé, le comportement dépenddu compilateur.

(cela revient à diviser la valeur par 210)

18 ‐ LES OPÉRATEURS BIT À BIT [4/4]Les décalages bit à bit

Il existe deux opérateurs de décalage : << et >>.

Chacun de ces opérateurs effectue un décalage des bits de son opérande de gauche du nombreindiqué par son opérande de droite.

Page 20: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

void main() unsigned char a = 255; signed char b = 127; a = a + 1; b = b + 1; printf("%d\n%d\n", a, b);

Le programme précédent affichera :0 ‐128

19 ‐ DÉPASSEMENT DE CAPACITÉOn a aperçu le problème avec les opérations sur le complément à 2, mais que se passe­t­il si unevaleur excède le maximum possible de son type ?

La réponse est systématique : la variable est tronqué à sa taille maximum.

Exemple sur des chars :

Page 21: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

20 ‐ CAST [1/2]« Caster » une variable vers un type donné signifie passer d'un type à un autre. On ne changepas le type d'une variable (c'est impossible !) mais on convertit une valeur vers un type donné.

Deux exemples sont de caster un int en char, ou un float en int.

Avec la multitude de variations de type possible donner une liste exhaustive des cast possiblen'est pas réaliste; cependant, de manière générale :

Les types numériques entiers se castent entre eux, en tronquant tout excedent (dépassementde capacité)Les valeurs à virgule flottante se castent entre elles de la même façonOn peut passer d'une virgule flottante à un entier en perdant de l'informationPasser d'un type signé à un type non signé est possible (dépassement de capacité toujoursapplicable)

Page 22: Programmation en C Représentation des variables en mémoirestephane.ayache.perso.luminy.univ-amu.fr/.../C_5.pdf · Programmation en C Représentation des variables en mémoire ...

21 ‐ CAST [2/2]En C, il est possible d'avoir des cast implicites ou explicites.

Lorsque l'on assigne une expression à une variable d'un type différent, le cast est implicite. Si ilest considéré comme dangereux le compilateur peut émettre un message d'avertissement. Dansce cas, spécifier votre choix avec un cast explicite permet de taire l'avertissement.

Pour réaliser un cast explicite on place le type voulu entre parenthèses avant l'expression àcaster :

int a = 42; char b = (char) a;

Entre types élémentaires les cast explicites servent principalement à taire les avertissements.Cependant, lorsque nous verrons les pointeurs plus en détails ils deviendront essentiels afin depouvoir manipuler la mémoire comme on le souhaite.