当前位置:网站首页>Stockage et pratique des données en langage C (haut niveau)

Stockage et pratique des données en langage C (haut niveau)

2022-07-07 07:20:00 ℓ blanc ℓ noir ℓ

Introduction

Comment les variables du type de données sont stockées en mémoire?Qu'est - ce qu'un complément positif et négatif?
Ce chapitre détaille le stockage des données.
Aux fins du présent chapitre32Plate - forme bit

1. Description du type de données

Nous avons déjà appris les types intégrés de base:

char //Type de données de caractère
short //Forme courte
int //Remodelage
long //Forme longue
long long //Remodelage plus long
float //Nombre de points flottants de précision unique
double //Nombre de points flottants de double précision
//CLa langue a - t - elle un type de chaîne?

Et la taille de l'espace de stockage qu'ils occupent.
Le sens du type:

  1. Utilisez ce type pour ouvrir la taille de l'espace mémoire(La taille détermine la plage d'utilisation).
  2. Comment voir la perspective de l'espace mémoire.

1.1 Classification de base des types

Famille orthopédique:

char //Parce quecharLe type stockeASCIIValeur du Code,Il appartient donc aussi à la famille des plasticiens
unsigned char
signed char
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]

Famille de nombres flottants:

float
double

Type de construction:

Type de tableau
Type de structure struct
Type d'énumération enum
Type d'union union

Type de pointeur:

int*pi;
char* pc;
float* pf;
void* pv;

Type vide:

void Indique un type vide(Aucun type)
Type de retour généralement appliqué à une fonction、Paramètres de la fonction、Type de pointeur.

2. Le stockage des formes en mémoire

Nous avons déjà parlé de la création d'une variable pour créer de l'espace en mémoire.La taille de l'espace dépend du type.
Comment exactement les données sont stockées dans la mémoire ouverte?
Par exemple,:

int a = 20;
int b = -10;

Nous savons que a Assigner quatre octets d'espace.
Comment conserver?
Pour comprendre les concepts suivants:

2.1 Code source、Code inverse、Complément

Il y a trois types d'entiers dans un ordinateur2Représentation décimale,C'est le code original.、Inversion et complément.
Les trois représentationsBits de symboleEtBits numériquesDeux parties,Les bits de symbole sont utilisés0Représentation“Positif”,Avec1Représentation“Négatif”,Et les bits numériques.
Original of positive、Contre、Le complément est le même.
Les trois représentations des entiers négatifs sont différentes.

Code source
Le code source peut être obtenu en traduisant les nombres directement en binaires sous forme de nombres positifs et négatifs..
Code inverse
Modifie le BIT de symbole du code source,D'autres bits peuvent être inversés à tour de rôle pour obtenir le Code inverse.
Complément// Valeurs stockées en mémoire
Code inverse+1J'ai un complément.

Pour le remodelage:La mémoire de stockage des données contient en fait un complément.
Pourquoi??

Dans un système informatique,Les valeurs numériques sont toujours représentées et stockées par un complément.La raison en est que,Utiliser un complément,Les bits symboliques et les champs numériques peuvent être traités uniformément;
En même temps,L'addition et la soustraction peuvent également être traitées uniformément(CPUAdder seulement)En outre,Conversion mutuelle du complément et du code source,Le processus de calcul est le même,Aucun circuit matériel supplémentaire n'est nécessaire.

Prenons un exemple.:

int a=1;
int c=a-1;

Ça dit:,CPU Seuls les ajouts peuvent être traités ,C'est - à - direc=a+(-1), Regardons ça d'un point de vue binaire .

aLe code original de
00000000000000000000000000000001 //Les compléments originaux et inversés des nombres positifs sont les mêmes
-1Le code original de
10000000000000000000000000000001 //Code source
11111111111111111111111111111110 //Code inverse
11111111111111111111111111111111 //Complément
Si vous suivezCPUMéthode,a Code original et -1 Le code original de :
10000000000000000000000000000010
Mais s'il y a un supplément ,Les résultats sont les suivants::
Insérer la description de l'image ici

Regardons le stockage en mémoire:
Insérer la description de l'image ici
Nous pouvons voir queaEtbLes suppléments sont stockés séparément.Mais nous avons trouvé l'ordre un peuQuelque chose ne va pas..
Et pourquoi??

2.2 Introduction de la taille

Qu'est - ce que la grande extrémité et la petite extrémité:

Grande extrémité(Stockage)Mode,Le BIT inférieur des données est stocké dans une adresse mémoire élevée,Et le haut niveau des données,Enregistrer en mémoire à faible adresse;
Petit bout(Stockage)Mode,Le BIT inférieur des données est stocké dans une adresse mémoire basse,Et le haut niveau des données,,Enregistrer en mémoire à haute adresse.

Les valeurs stockées en mémoire sont exprimées en hexadécimal , Quant à la raison pour laquelle il n'y a pas de représentation binaire , Parce que le binaire est trop long , Et ce n'est pas beau , Mais ce qui est réellement stocké en mémoire est binaire .
Nous utilisons0x11223344Prenons un exemple.:
11 C'est un haut niveau de données ,44C'est le bas niveau des données
Insérer la description de l'image ici
Pourquoi les grandes et les petites extrémités:

Pourquoi y a - t - il une différence de taille??C'est parce que dans un système informatique,Nous sommes en octets,Chaque Unit é d'adresse correspond à un octet,Un octet est8 bit.Mais dansCDans la langue8 bitDecharAu - delà,Et16 bitDeshortType,32 bitDelongType(Voir le compilateur spécifique),En plus,Pour les chiffres supérieurs à8Processeur de bits,Par exemple16Bits ou32Processeur de bits,Parce que la largeur du registre est supérieure à un octet,Il doit donc y avoir un problème avec la façon de programmer plusieurs octets.Il en résulte des modes de stockage à grande et à petite échelle.
Par exemple:Un 16bit De short Type x ,L'adresse en mémoire est 0x0010 , x La valeur de 0x1122 ,Alors 0x11 Est un octet élevé, 0x22 Faible octet.Pour le mode grand terminal,Juste... 0x11 Placer à basse adresse,C'est - à - dire: 0x0010 Moyenne, 0x22 Placer à haute adresse,C'est - à - dire: 0x0011 Moyenne.Mode petit terminal,Exactement le contraire..Que nous utilisons X86 La structure est un modèle à petite extrémité,Et KEIL C51 Mode grand terminal.Beaucoup.ARM,DSPTous en mode petit bout.CertainsARMLe processeur peut également être sélectionné par le matériel en mode grand ou petit.

Baidu2015Examen écrit annuel de l'ingénieur des systèmes:
Veuillez décrire brièvement les concepts d'ordre des octets de grande et de petite extrémité.,Concevoir une applet pour déterminer l'ordre des octets de la machine actuelle.
Considérez d'abord la logique que ce code devrait implémenter :

Nous pouvons créer une variable comme 1,Et prenez l'adresse.,Type de force converti encharType, Parce que prendre l'adresse prend l'adresse du premier octet , Donc nous imprimons les valeurs à l'intérieur du premier octet et nous voyons 1Toujours0.

Code de référence:

#include <stdio.h>
int check_sys()
{
    
	int i = 1;
	return (*(char*)&i);
}
int main()
{
    
	int ret = check_sys();
	if (ret == 1)
	{
    
		printf("Petit bout\n");
	}
	else
	{
    
		printf("Grande extrémité\n");
	}
	return 0;
}

Le résultat de l'exécution du Code est :
Insérer la description de l'image ici
Le matériel de mon ordinateur est de petite taille .

Exercice

Ces codes sont les suivants:, Sans une simple réflexion , La sortie vous surprendra .
Qu'est - ce que la procédure suivante produit?

//Code1
#include <stdio.h>
int main()
{
    
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a=%d,b=%d,c=%d", a, b, c);
	return 0;
}

Le code fonctionne comme suit:
Insérer la description de l'image ici
-1Le complément est
11111111111111111111111111111111
Stockage dans aMoyenne,Parce que oui.charType,Donc iciTroncature, C'est - à - dire prendre les huit derniers chiffres du binaire .
Stockage dans bMoyenne,Parce que oui.signed char(SignécharType),Et au - dessuscharLe même type.
Stockage dans cMoyenne,Parce que oui.unsigned char(Non signécharType), Ce qui signifie qu'il n'y a pas de bits symboliques .
Utilisé lors de l'impression %d, Besoin d'un lifting plastique ,aEtbEst un type signé, Donc le lifting est un complément à gauche 1,Et enfin-1Le complément est le même.
Et pourtantcEst un type non signé,À gauche.0, Le complément après le complément est comme ceci :
00000000000000000000000011111111
C'est pour ça qu'on imprime 255.

//Code2
#include <stdio.h>
int main()
{
    
	char a = -128;
	printf("%u\n", a);
	return 0;
}

Le code fonctionne comme suit:
Insérer la description de l'image ici
-128Le complément est:
11111111111111111111111110000000
Stockage dans charTypea Pour tronquer ,10000000, C'est un bit signé , Nous imprimons des formes non signées ,C'est pour ça qu'il faut l'améliorer.,Comme ça..
11111111111111111111111110000000
Parce que c'est un entier non signé ,Le complément est égal au code original, Il s'avère que le grand nombre ci - dessus .

//Code3
#include <stdio.h>
int main()
{
    
	char a = 128;
	printf("%u\n", a);
	return 0;
}

Ce code donne les mêmes résultats que ci - dessus ,C'est juste que128Le complément est
00000000000000000000000010000000.

//Code4
#include <stdio.h>
int main()
{
    
	int i = -20;
	unsigned int j = 10;
	printf("%d\n", i + j);
	//Effectuer le calcul sous forme de complément,Enfin formaté en entier signé
	return 0;
}

Résultats de l'exécution du Code:
Insérer la description de l'image ici

Variables i Le complément est:
11111111111111111111111111101100
Variables j Le complément est:
00000000000000000000000000001010
i+jLe complément est:
Insérer la description de l'image ici
i+j Le complément à l'original est
10000000000000000000000000001010
Enfin,%dMode d'impression.

//Code5
#include <stdio.h>
int main()
{
    
	unsigned int i;
	for (i = 9; i >= 0; i--) 
	{
    
		printf("%u\n", i);
	}
	return 0;
}

Le résultat de l'impression de ce code est un cycle mort .
Parce que i - Oui.unsigned intType, C'est un nombre positif de toute façon ,Donc il y a un cycle de mort.

//Code6
#include <stdio.h>
#include <string.h>
int main()
{
    
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
    
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));
	return 0;
}

La sortie de ce code est:
Insérer la description de l'image ici
La première fois que nous sommes entrés dans le cycle ,char a[1000] Le premier élément de ce tableau est :
-1,Et puis-2…
D'un point de vue binaire :
-1Complément à 11111111111111111111111111111111
-2Complément à 11111111111111111111111111111110

On ne peut stocker que les huit derniers chiffres ,Attention ici.,strlenEst de rencontrer\0Et arrête.,Non calculé\0Emplacement,‘\0’égal àchar Ce qui est stocké à l'intérieur 0.
C'est - à - dire que le binaire s'arrêtera ici :
11111111111111111111111100000000
Donc la sortie est255.
Il y a une autre chose que nous avons trouvée ici ,SignécharLa gamme de types est0~127Et-1~-128
Non signéchar La plage de type est 0~255.

//Code7
#include <stdio.h>
unsigned char i = 0;
int main()
{
    
	for (i = 0; i <= 255; i++)
	{
    
		printf("hello world\n");
	}
	return 0;
}

Le résultat de l'exécution de ce code est aussi une boucle morte .
Parce que i - Oui.unsigned charType,Peu importe. i Comment?,Tout est positif.,Donc le cycle de la mort.

3. Stockage en mémoire flottante

Nombre commun de points flottants:

3.14159
1E10
La famille des nombres flottants comprend:: float、double、long double Type.
Plage représentée par un nombre flottant:float.hDéfinition moyenne

3.1 Un exemple

Exemple de stockage en virgule flottante:

#include <stdio.h>
int main()
{
    
	int n = 9;
	float* pFloat = (float*)&n;
	printf("nLa valeur de:%d\n", n);
	printf("*pFloatLa valeur de:%f\n", *pFloat);
	*pFloat = 9.0;
	printf("numLa valeur de:%d\n", n);
	printf("*pFloatLa valeur de:%f\n", *pFloat);
	return 0;
}

Nos résultats sont :
Insérer la description de l'image ici
Les résultats réels ne sont - ils pas très en deçà de nos attentes ?
C'est pour ça que?On regarde en bas:

3.2 Règles de stockage des points flottants

num Et *pFloat C'est exactement le même nombre en mémoire,Pourquoi l'interprétation des nombres flottants et des entiers est - elle si différente?
Pour comprendre ce résultat,Assurez - vous de comprendre comment les nombres flottants sont représentés à l'intérieur de l'ordinateur.
Interprétation détaillée:
Conformément aux normes internationalesIEEE(Institute of Electrical and Electronic Engineering) 754,N'importe quel nombre binaire de points flottantsVPeut être exprimé sous la forme suivante::

(-1)^S * M * 2^E
(-1)^SReprésente un bit de symbole,QuandS=0,VEst un nombre positif;QuandS=1,VEst négatif.
MIndique un nombre valide,Supérieur ou égal à1,Moins de2.
2^EReprésente un bit exponentiel.

Par exemple,:
Décimal5.0,Écrit en binaire oui 101.0 ,équivalent à 1.01×2^2 .
Alors,Suivez les instructions ci - dessus.VFormat de,On peut conclure queS=0,M=1.01,E=2.
Décimal-5.0,Écrit en binaire oui -101.0 ,équivalent à -1.01×2^2 .Alors,S=1,M=1.01,E=2.
IEEE 754Le règlement:
Pour32Nombre de points flottants de bits,Le plus élevé1Les bits sont des bits symboliquess,C'est parti.8Les bits sont des indicesE,Le reste23Bit est un nombre valideM.
Insérer la description de l'image ici
Pour64Nombre de points flottants de bits,Le plus élevé1Les bits sont des bits symboliquesS,C'est parti.11Les bits sont des indicesE,Le reste52Bit est un nombre valideM.
Insérer la description de l'image ici
IEEE 754Pour les chiffres validesMEt indexE,Il existe également des dispositions spéciales.
Comme je l'ai dit, 1≤M<2 ,C'est - à - dire,MPeut être écrit comme 1.xxxxxx Forme,Parmi euxxxxxxxReprésente la partie décimale.
IEEE 754Le règlement,Enregistrer à l'intérieur de l'ordinateurMHeure,Par défaut, le premier chiffre de ce nombre est toujours1,Pour qu'il puisse être abandonné.,Enregistrer uniquement les suivantsxxxxxxSection.Comme la préservation1.01Quand,Enregistrer seulement01,Attendez la lecture.,Encore une fois.1Ajouter.L'objet de cette action,C'est une économie.1Nombre effectif de bits.Par32Exemple de nombre de points flottants,Laisse - le.MSeulement23Bits,Le premier1Après le départ,égal à peut être sauvegardé24Nombre effectif de bits.
En ce qui concerne les indicesE,C'est compliqué..
Tout d'abord,,EEst un entier non signé(unsigned int)
Cela signifie,SiEPour8Bits,Sa plage de valeurs est0 ~ 255;SiEPour11Bits,Sa plage de valeurs est0 ~ 2047.Mais,Nous savons que,Dans le comptage scientifiqueEPeut être négatif,Alors...IEEE 754Le règlement,En mémoireELa valeur réelle de doit être ajoutée à un nombre intermédiaire,Pour8BitwiseE,Ce nombre moyen est127;Pour11BitwiseE,Ce nombre moyen est1023.Par exemple,,2^10DeE- Oui.10,Alors gardez - le.32Bit float,Doit être sauvegardé sous10+127=137,C'est - à - dire:10001001.
Et puis,IndexESortir de la mémoire peut être divisé en trois autres situations:
EPas tout à fait.0Ou pas tous1

À ce moment - là,,Le nombre de points flottants est représenté par les règles suivantes:,C'est - à - dire l'indiceEValeur calculée moins127(Ou1023),Obtenir la valeur réelle,Ensuite, les chiffres validesMAjouter le premier1.
Par exemple,:
0.5(1/2)La Forme binaire de0.1,La partie positive doit être1,Déplacer le point décimal à droite1Bits,Oui.1.0*2^(-1),Son code d'ordre est-1+127=126,Exprimé en
01111110,Et le nombre de queues1.0Supprimer la partie entière comme suit:0,Compléter0À23Bits00000000000000000000000,Sa représentation binaire est:
0 01111110 00000000000000000000000

ETout est0

À ce moment - là,,Indice du nombre de points flottantsEégal à1-127(Ou1-1023)Est la valeur réelle,Nombre effectifMPlus de premier1,Mais revenir à0.xxxxxxLa décimale de.C'est pour montrer±0,Et près de0Un petit nombre.

ETout est1

À ce moment - là,,Si un nombre valideMTout est0,Représentation±Infini(Plus ou moins dépend du BIT de symboles);

C'est comme ça que les données flottantes sont stockées .
Expliquer les questions précédentes:
En bas,Revenons à la question de départ.:Pourquoi 0x00000009 Revenir au nombre de points flottants,C'est tout. 0.000000 ?
Tout d'abord,,Oui. 0x00000009 Split,Obtenir le premier bit de symboles=0,Derrière8Indice des bitsE=00000000 ,Enfin23Nombre valide de bitsM=000 0000 0000 0000 0000 1001.

9 -> 0000 0000 0000 0000 0000 0000 0000 1001

Grâce à l'indiceETout est0,Donc, selon la deuxième situation de la section précédente.Donc,,Nombre de points flottantsVC'est écrit comme suit::

V=(-1)^0 × 0.00000000000000000001001×2^(-126)=1.001×2^(-146)

Apparemment.,VC'est un peu près de0Nombre positif de,Donc, en décimales, c'est0.000000.(%f Imprimez seulement après la décimale 6Nombre de bits)
Voir la deuxième partie de l'exemple.
Excusez - moi, les points flottants9.0,Comment représenter?Qu'est - ce que c'est de revenir à la décimale?
Tout d'abord,,Nombre de points flottants9.0égal à binaire1001.0,C'est - à - dire:1.001×2^3.

9.0 -> 1001.0 ->(-1)^01.0012^3 -> s=0, M=1.001,E=3+127=130

Alors,Le symbole du premier chiffres=0,Nombre effectifMégal à001Plus de20- Oui.0,Remplir23Bits,IndexEégal à3+127=130, C'est - à - dire:10000010.
Alors...,Écrit sous forme binaire,Je crois.s+E+M,C'est - à - dire:

0 10000010 001 0000 0000 0000 0000 0000

C'est32Nombre binaire de bits,Retour à la décimale,Exactement. 1091567616 .

Conclusion

Demandez à votre famille de faire un compliment , Les grands n'ont pas assez d'indications .

原网站

版权声明
本文为[ℓ blanc ℓ noir ℓ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207070330262109.html