Pas de dépendances
#include <stdio.h> struct test { int a:3; int b:5; int c:1; int d:7; int v:15; }; int main() { struct test S; printf("Taille memoire de test : %d\n",sizeof(struct test)); S.c=1; S.a=2; printf("c=%d ; a=%d\n",S.c,S.a); return 0; }
Voici une façon d'optimiser la mémoire énormément. Cette leçon parle de mémoire de près. Lancez l'application et voyez plusieurs choses qui peuvent paraitre étranges. Avant de vous étonner, n'oubliez pas q'un "int" est un entier stocké sur 4 octets. (Note : la fonction sizeof renvoie le nombre d'octets que coute ce qu'on lui passe en paramètre.) Avant d'aller plus loin, faites l'exerice 1, pour mieux comprendre. Normalement, la structure fait 20 octets : 5 int de 4 octets chacuns (5*4) Donc rien d'extraordinaire. Maintenant, rétablissez l'exempel original. Première chose bizarre : le sizeof de test affiche 4. ----------------------- C'est à dire que cette structure, contenant pourtant 5 int, ne coute QUE 4 octets en mémoire. La raison est simple : nous avons créé des variables stockant que quelques bits !! Un entier int fait 4 octets = 32 bits (car 1 octet = 8 bits) Donc si je fais int a; cela revient à : int a:32; --> les :x précisent combien de bits on veut allouer à l'entier. Par défaut, c'est 32 pour un int. Donc ici, on crée 5 int, mais dont la somme en mémoire fait : 3+5+1+7+15 bits = 31 bits. pour stocker 31 bits, on a besoin de 4 octets, d'ou la réponse de sizeof... Note : le dernier bit (car on a 31 bits) n'est donc pas utilisé. Deuxieme chose bizarre : le sizeof de test affiche 4. ----------------------- On a mis : S.c = 1 et le cout m'affiche S.c = -1 La raison est tordue mais bien évidente. S.c est une variable d'un seul bit. c'est un "int", donc implicitement un "signed int" (pour les matheux, dans Z, pour les non matheux : elle garde un signe + ou -) Si elle garde un signe, alors le seul bit de la variable est automatiquement le signe. donc en fixant ce bit à 1, on fixe le signe à -, donc le signe donné est négatif. Le domaine de c est [-1,0]. En le fixant à 1, on déborde, on n'est pas dans le domaine. Le résultat est donc un autre nombre puisque 1 ne peut pas etre le résultat. La gestion de la mémoire et la gestion des débordements interne du processeur défini alors cette variable comme étant -1. tordu non ? De toute évidence, il est conseillé d'éviter les débordements... Ce probleme est du pur codage de nombre en mémoire. ----------------------------------- Exercice 1) Changez le programme en enlevant les :1, :3 etc... pour avoir : struct test { int a; int b; int c; int d; int v; }; Constatez ce que vous pensiez constater... 2) Pour le sizeof, remplacez l'argument "test" par l'arguement "S". 3) Un int porte 32 bits. Essayez de créer un int de 33 bits, ou de 6000 bits. 4) Remplacez le "int c" par "unsigned int c", testez et expliquez. 5) Définissez un "unsigned char c=255", faites "c=c+1", affichez c, et expliquez. 6) Et un "char c=127", faites "c=c+1", affichez c, et expliquez. 7) Quel est le domaine général d'un nombre de n bits. signed ? et unsigned ? ----------------------------- Réponses : 1) sizeof = 5*4 = 20 : rien d'étonnant. S.c et S.a ont les valeurs rentrées. 2) sizeof reconnait aussi bien le type qu'une variable de ce type. Ainsi : sizeof(struct test) sizeof(S) donnent le meme résultat. 3) int a:33; int b:6000; --> Impossible, le compilateur vous jette. Cette notation permet uniquement de créer des variables de moins de bits que le type porteur (ici, le type porteur est un int, donc de 32 bits, impossible de créer + de 32 bits) 4) unsigned int est dans N (pas de signe) donc son domaine est [0, 1] Si vous assignez c = 1, vous etes dans le domaine, pas de débordement, tout se passe bien. 5) c=0. le domaine d'un "unsigned char" est [0, 255]. 256 n'existe pas. Pour les nombres unsigned, lorsque l'on sort à droite, on revient à gauche et réciproquement. 0 - 1 = 255. 6) c=-128 Le domaine d'un "char" est [-128,127] Meme explication que ci dessus. 7) Pour unsigned : le domaine est [0, 2^n-1] // ^ = puissance. (exemple unsigned char : 8 bits, 2^n = 256, 2^n-1 = 255 CQFD) Pour signed : le domaine est [-2^(n-1), 2^(n-1)-1] (exemple char : 8 bits : 2^(n-1) = 2^7 = 128, donc à la sortie : [-128,127])