Règles de stockage des données en "langage C" en mémoire

insérez la description de l'image ici

avant-propos

Xiaoyang a récemment partagé le contenu d'apprentissage de base du langage C avec les presse-agrumes de fer. Ensuite, Xiaoyang continuera à mettre à jour ses connaissances avancées en langage C. Amis, asseyez-vous sur le banc, prenez le stylo et commencez le cours ~


1. Introduction des types de données

Jusqu'à présent, nous avons appris les types intégrés de base :

char       //字符数据类型
short      //短整型
int        //整形
long       //长整型
long long  //更长的整形
float      //单精度浮点数
double     //双精度浮点数

Classification de base des types

  1. 整形家族
char:
   unsigned char
   signed char
short:
   unsigned short[int]
   signed short[int]
int:
   unsigned int
   signed int
long:
   unsigned long[int]
   signed long[int]

non signé:无符号数类型

Lorsqu'un nombre est de type non signé, son 1 ou 0 le plus significatif, comme les autres bits, est utilisé pour représenter la taille du nombre.

signé:有符号数类型

Lorsqu'un nombre est de type signé, le nombre le plus élevé est appelé « bit de signe ». Lorsque le bit de signe est 1, cela signifie que le nombre est négatif, et lorsqu'il est 0, cela signifie un nombre positif.

注意:有符号类型可以表示正数,负数或0,无符号类型仅能表示大于等于0的值

  1. 浮点型家族
float
double
  1. 构造类型:
       //数组类型
struct //结构体类型
enum   //枚举类型
union //联合类型
  1. 指针类型:
int* p;
char* p;
float* p;
void* p;
  1. 空类型:
void//(空类型)

Deuxièmement, le stockage des entiers en mémoire

Prenons l'exemple du type entier int. Nous savons tous que int occupe quatre octets dans les compilateurs courants, alors comment ces quatre octets stockent-ils les données dans l'ordinateur ?
Ensuite, comprenons d'abord les concepts de nombres de machines et de valeurs vraies , puis comprenons les concepts de code original, de code inverse et de code complémentaire.

2.1 Nombre de machines

La représentation binaire d'un nombre dans un ordinateur est appelée le numéro machine du nombre. Le numéro de machine est signé et le bit le plus élevé du numéro de machine est utilisé pour stocker le signe dans l'ordinateur, le nombre positif est 0 et le nombre négatif est 1.

Par exemple:

+ 3的机器数:0000 0011
- 3的机器数:1000 0011

2.2 Valeur de vérité

Le premier bit étant le bit de signe, la valeur formelle du numéro de machine n'est pas égale à la valeur réelle. Ainsi, par souci de distinction, la valeur réelle correspondant au numéro de machine avec le bit signé est appelée valeur réelle du numéro de machine.

Par exemple:

0000 0001的真值 = +000 0001 = +1
1000 0001的真值 = -000 0001 = -1

2.3 Code original, code inverse, code complément

Pour un numéro, l'ordinateur doit utiliser une certaine méthode de codage pour le stocker. Le code original, le code inverse et le code complémentaire sont les méthodes de codage permettant à la machine de stocker un numéro spécifique.

Les trois méthodes comportent toutes deux parties, un bit de signe et un bit de valeur . Le bit de signe est 0 pour indiquer un « nombre positif », 1 pour indiquer un « nombre négatif » et le bit de valeur est divisé en nombres positifs et négatifs.

正数的原码、反码、补码都相同,负数的原码、反码、补码各不相同

原码:
Le code original peut être obtenu en traduisant directement la valeur en binaire sous forme de nombres positifs et négatifs
反码:
le bit de signe du code original reste inchangé, et les autres bits sont inversés bit par bit
补码:
le bit de signe du code inverse reste inchangé et la valeur est +1

反码回到原码的两种方式:
1. Le code complémentaire -1 est inversé pour obtenir le code original
2. Le code complémentaire est inversé et +1 est obtenu pour obtenir le code original

Pour le façonnage : les données stockées dans la mémoire sont en fait stockées dans du code complémentaire, alors pourquoi ?

Dans les systèmes informatiques, les valeurs sont toujours exprimées et stockées en complément à deux. La raison en est qu'en utilisant le code complémentaire, le bit de signe et le
champ de valeur peuvent être traités de manière uniforme, et en même temps, l'addition et la soustraction peuvent également être traitées de manière uniforme (la CPU ne dispose que d'un additionneur). et le code original sont convertis l'un en
l'autre , et le processus de fonctionnement est le même, aucun circuit matériel supplémentaire n'est requis.

Regardons le stockage en mémoire :
insérez la description de l'image ici
on sait que a et b sont stockés en complément à deux en mémoire, mais on constate que l'ordre de stockage est un peu erroné.
-10 doit être stocké sous la forme FFFFFFF6 en mémoire, et nous voyons F6FFFFFF.
Quant à l’agneau ici, découvrons les gros et petits bouts des presse-agrumes en fer.

2.4 Introduction au grand et au petit endian

Qu'est-ce que le grand et le petit endian :

Mode de stockage big endian : signifie que les bits faibles des données sont stockés à l'adresse haute de la mémoire, tandis que les bits forts des données sont stockés à l'adresse basse de la mémoire Mode de stockage
small , tandis que les bits hauts des données sont stockés dans l'adresse mémoire haute

Par exemple:

Le numéro 0x12 34 56 78 est en mémoire :

Mode big endian : (le mode auquel nous pensons habituellement intuitivement)

        低地址 --------------------> 高地址
         0x12  |  0x34  |  0x56  |  0x78

Mode petit endian :

        低地址 --------------------> 高地址
         0x78  |  0x56  |  0x34  |  0x12

** Pourquoi y a-t-il du big endian et du little endian ? **
Parce que dans le système informatique, nous utilisons les octets comme unité, chaque unité d'adresse correspond à un octet et un octet fait 8 bits. Mais dans le langage C, en plus des caractères 8 bits, il existe également des types courts 16 bits et des types longs 32 bits (selon le compilateur spécifique). De plus, pour les processeurs de plus de 8 bits, comme 16 bits Ou un processeur 32 bits, puisque la largeur du registre est supérieure à un octet, il doit y avoir un problème sur la façon d'organiser plusieurs octets. Par conséquent, cela conduit au mode de stockage big-endian et au mode de stockage small-endian.

Comment juger le code du grand et du petit bout :

#include<stdio.h>
int main()
{
    
    
	int i = 1;//0000 0001
	char* p = &i;
	if (*p == 1)//若第一个地址存的是1,即为小端,反则大端
		printf("小端");
	else
		printf("大端";
	return 0;
}

Test de fonction personnalisé :

#include<stdio.h>

int check_sys()
{
    
    
	int a = 1;
	char* p = (char*)&a;
	if (*p == 1)
		return 1;
	else
		return 0;
}

int main()
{
    
    
	if (check_sys() == 1)
		printf("小端");
	else
		printf("大端");
	return 0;
}

3. Stockage des nombres à virgule flottante en mémoire

#include<stdio.h>
int main()
{
    
    
	int n = 9;
	float* p = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*p的值为:%f\n", *p);
	*p = 9.0;
	printf("n的值为:%d\n", n);
	printf("*p的值为:%f\n", *p);
	return 0;
}

Essayons d'abord de deviner le résultat.
Le résultat indique :
insérez la description de l'image ici
 Que diriez-vous, ce résultat n'est-il pas un peu inattendu ! Suivez ensuite l'agneau pour apprendre les règles de stockage des nombres à virgule flottante.

3.1 Règles de stockage des nombres à virgule flottante

Format de stockage à virgule flottante :

Selon la norme internationale IEEE (Institute of Electronics and Electronics Engineering) 754 , tout nombre binaire à virgule flottante V peut être exprimé sous la forme suivante :

(-1) ^ S * M * 2 ^ E

 1. (-1) ^ S représente le bit de signe, lorsque S=0, V est un nombre positif ; lorsque S=1, V est un nombre négatif
 2. M représente un nombre valide, et 1 <= M <2
 3. 2 ^ E signifie exposant

Par exemple:

  1. 5.0 en décimal, écrit en binaire est 0101 ------> 1.10x2^2
    peut obtenir s=0, M=1.01, E=2
  2. Décimal -7.0, écrit en binaire est 0111 ------->1.11x2^2
    peut obtenir s=-1, M=1.11, E=2

IEEE 754 déclare :

Pour les nombres à virgule flottante de 32 bits (simple précision), le bit le plus élevé est le bit de signe s, les 8 bits suivants sont l'exposant E et les 23 bits restants sont le nombre effectif M.

insérez la description de l'image ici

Pour les nombres à virgule flottante de 64 bits (double précision), le bit le plus élevé est le bit de signe S, les 11 bits suivants sont l'exposant E et les 52 bits restants sont le nombre effectif M.
insérez la description de l'image ici
IEEE 754 a des réglementations spéciales sur les chiffres valides **M** et l'exposant E.
Comme mentionné précédemment, 1≤M<2, c'est-à-dire que M peut s'écrire sous la forme 1.xxxxxx, où xxxxxx représente la partie fractionnaire.
IEEE 754 stipule que lorsque M est enregistré dans l'ordinateur, le premier chiffre de ce numéro est toujours 1 par défaut, il peut donc être supprimé et seule la partie xxxxxx qui suit est enregistrée. Par exemple, lors de la sauvegarde de 1.01, enregistrez uniquement 01, puis ajoutez le premier 1 lors de la lecture. Le but de cette opération est d’économiser 1 chiffre significatif. Prenons l'exemple du nombre à virgule flottante de 32 bits, il ne reste que 23 bits pour M et 24 chiffres significatifs peuvent être enregistrés une fois le premier 1 arrondi.

Quant à l'indice E, la situation est plus compliquée. Premièrement, E est un entier non signé (unsigned int)
, ce qui signifie que si E est de 8 bits, sa plage de valeurs est de 0 à 255 ; si E est de 11 bits, sa plage de valeurs est de 0 à 2 047. Mais nous savons que E en notation scientifique peut avoir des nombres négatifs, c'est pourquoi la norme IEEE 754 stipule qu'un nombre intermédiaire doit être ajouté à la valeur réelle de E lorsqu'il est stocké en mémoire. Pour un E 8 bits, ce nombre intermédiaire est 127 ; pour un E 11- bit E, ce nombre intermédiaire est 1023. Par exemple, le E de 2^10 est 10, donc lorsque vous l'enregistrez sous forme de nombre à virgule flottante de 32 bits, il doit être enregistré sous 10+127=137, c'est-à-dire 10001001.

3.2 Lecture du type à virgule flottante

Nous savons qu'une fois le type à virgule flottante stocké en mémoire, le processus de suppression est l'inverse des étapes.
1. Nombre effectif M :

IEEE 754 stipule que lorsque M est enregistré dans l'ordinateur, le premier chiffre de ce nombre est toujours 1 par défaut, il peut donc être arrondi et seule la partie décimale est enregistrée. Par exemple, lorsque vous enregistrez 1.0110001101, enregistrez uniquement 0110001101 et ajoutez 0 aux chiffres suivants. Lors de la lecture, ajoutez 1 au premier chiffre.

2. Indice E

E est un entier non signé (unsigned int), qui peut être divisé selon les trois cas suivants selon les différentes valeurs du champ exposant :

1) E n'est pas entièrement 0 ou pas entièrement 1 (valeur normalisée)

C'est la situation la plus courante : lors de la sortie du nombre en mémoire, soustrayez 127 (ou 1023) de la valeur calculée de l'exposant E pour obtenir la valeur réelle, puis ajoutez le premier chiffre 1 avant le nombre effectif M.

2) E est entièrement 0 (valeur non normalisée)

A ce moment, l'exposant E du nombre à virgule flottante égal à 1-127 (ou 1-1023) est la valeur réelle, et le nombre effectif M n'est plus ajouté au premier 1, mais est restitué à une décimale de 0.xxxxxxx. Ceci est fait pour représenter plus et moins zéro, ainsi que de très petits nombres proches de 0.

3) E vaut tout 1 (valeur spéciale)

C'est le cas lorsque le champ des exposants est composé uniquement de 1. À ce stade, si le champ décimal est entièrement à 0 et le champ de signe S=0, cela signifie l'infini positif ; si le champ décimal est entièrement à 0 et le champ de signe S=1, cela signifie l'infini négatif. Si le champ décimal n'est pas entièrement 0, le nombre à virgule flottante sera interprété comme NaN, c'est-à-dire pas un nombre (Not a Number)

Pour expliquer la question précédente :

整形9以浮点型打印
整形存储,浮点型打印
0000  0000 0000 0000 0000 0000 0000 1001
浮点型读取:
s=0,M=000 0000 0000 0000 0000 0110,E=0000 0000(E全为0)
所以结果为:0.0000(近于0的很小的数字)

现在看例题的第二部:
浮点数9.0以整形打印
9.0 -> 1001.0 -> (-1)^0*1.001*2^3 -> s=0,M=1.001,E=3+127=130
所以第一位的符号位s=0,有效数字M为001后面在加200,凑满23位,指数E为3+127=130,即10000010
所以写成S+E+M:
0 10000010 001 0000 0000 0000 0000 000032位的二进制数,还原成十进制,正是1091567616

Résumer

J'espère qu'après avoir lu cet article, il sera utile aux presse-agrumes de fer. Xiaoyang continuera à mettre à jour ses connaissances d'apprentissage du langage C à l'avenir.
insérez la description de l'image ici

추천

출처blog.csdn.net/hsjsiwkwm/article/details/132374637