[Langage C avancé 1 - stockage de données (1)]


avant-propos

Cet article commence à apprendre le contenu avancé du langage C. Le contenu avancé consiste à développer le contenu de l'étape de base, et certains points de connaissance ont également été appris à l'étape de base. Dans le contenu avancé, l'apprentissage sera compris d'un point de vue plus profond. Le contenu principal de cet article comprend :

  • Détails des types de données
  • Stockage de la mise en forme en mémoire : code original, code inverse, code complément
  • Introduction et jugement de l'ordre des octets gros et petit endian
  • Analyse du stockage de type virgule flottante en mémoire

1. Introduction aux types de données

Les types de base et les tailles d'espace de stockage ont été appris au stade de base.
Connaître la taille de l'espace mémoire ouvert par un certain type (la taille détermine le périmètre d'utilisation).

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

1.1 Classification de base des types

  • Famille plastique
char
	unsigned char//无符号
	signed char//有符号
short
	unsigned short [int]//无符号
	signed short [int]//有符号
int
	unsigned int//无符号
	signed int//有符号
long
	unsigned long [int]//无符号
	signed long [int]//有符号
  • famille à virgule flottante
float
double
  • Type de structure
> 数组类型
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union
  • type de pointeur
int *pi;
char *pc;
float* pf;
void* pv;
  • type vide
void 表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型

2. Stockage de la mise en forme en mémoire

La création d'une variable consiste à libérer de l'espace en mémoire. La taille de l'espace est déterminée par le type de la variable

//举例
int a = 20;
int b = -10;

int est un entier et occupe 4 octets, ce qui suit analysera précisément comment la valeur 20 de la variable a est allouée dans l'espace mémoire

2.1 Code original, code inverse, code complément

Il existe trois méthodes de représentation des nombres entiers dans l'ordinateur, à savoir le code original, le code inverse et le code complémentaire :

  • Code original : traduit directement binaire en binaire sous forme de nombres positifs et négatifs
  • **Code complémentaire : **Conservez le bit de signe du code d'origine inchangé, et les autres bits peuvent être obtenus en inversant les autres bits à leur tour.
  • **Code complément : **Code complément +1 pour obtenir le code complément

Les trois modes de représentation comportent deux parties : bit de signe et bit de valeur :

  • Le bit de signe est 0 pour "positif" et 1 pour "négatif"
  • L'original, l'inverse et le complément des nombres entiers positifs sont les mêmes
  • Les trois représentations des entiers négatifs sont différentes

Notez que l' entier stocké dans la mémoire est le complément , l'objet de l'opérateur est le complément et le code original est imprimé à la fin .

Donnez un exemple pour illustrer le code d'origine, le code inverse et le code complémentaire de la valeur,

//
int main()
{
    
    
	int a = 10;//正数
	00000000 00000000 00000000 00001010 原码
	00000000 00000000 00000000 00001010 反码
	00000000 00000000 00000000 00001010 补码
	a在内存中的存储形式 00 00 00 0a
	int b = -10;//负数
	10000000 00000000 00000000 00001010 原码
	11111111 11111111 11111111 11110101 反码
	11111111 11111111 11111111 11110110 补码=反码+1
	b在内存中存储的数值 ff ff ff f6
	return 0;
}

La forme de stockage de la valeur de a
insérez la description de l'image ici
dans la mémoire : La forme de stockage de la valeur de b dans la mémoire :
insérez la description de l'image ici
Dans le système informatique, la valeur est toujours représentée et stockée dans le complément . 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 ;

Étant donné que la CPU n'a qu'un additionneur , l'addition et la soustraction peuvent également être traitées de manière uniforme.De plus, le code complémentaire et le code d'origine sont convertis l'un à l'autre, et le processus de fonctionnement est le même, et aucun circuit matériel supplémentaire n'est requis.

Ce qui suit illustrera que l'opération sur les données en mémoire est effectuée en utilisant le code complémentaire au lieu du code d'origine :

int main()使用补码计算,打印的是原码
{
    
    
	1-1//CPU只有加法器
	1+(-1)
	第一步:
	00000000 00000000 00000000 00000001  1补码
	第二步:
	10000000 00000000 00000000 00000001  -1原码
	11111111 11111111 11111111 11111110  -1反码
	11111111 11111111 11111111 11111111  -1补码
	第三步:补码相加
	00000000 00000000 00000000 00000001  1补码
	11111111 11111111 11111111 11111111  -1补码
	结果是33位,超出范围
   100000000 00000000 00000000 00000000 
	00000000 00000000 00000000 00000000   截断32位为0

	如果使用原码计算,结果是错误的
	00000000000000000000000000000001  1补码
	10000000000000000000000000000001  -1原码
	10000000000000000000000000000010  -2
}

2.2 Introduction au Big et Little Endian

2.2.1 Qu'est-ce que le gros et le petit endian

  • Le mode big-endian (stockage) signifie que les bits de poids faible des données sont stockés à l'adresse haute de la mémoire et que les bits de poids fort des données sont stockés à l'adresse basse de la mémoire.
  • Le mode Little-endian (stockage) signifie que les bits de poids faible des données sont stockés à l'adresse basse de la mémoire et que les bits de poids fort des données sont stockés à l'adresse haute de la mémoire.

2.2.2 Significations big-endian et little-endian

  • Parce que dans les systèmes informatiques, nous utilisons les octets comme une unité, chaque unité d'adresse correspond à un octet, et un octet est de 8 bits
  • Mais en langage C, en plus du caractère 8 bits, il existe un type court 16 bits et un type long 32 bits (selon le compilateur spécifique)
  • De plus, pour les processeurs de plus de 8 bits, tels que les processeurs 16 bits ou 32 bits, étant donné que la largeur de registre est supérieure à un octet, il doit y avoir un problème d'organisation de plusieurs octets. Par conséquent, cela conduit au mode de stockage big endian et au mode de stockage little endian.

Exemple pour illustrer la fin de la taille, par exemple : un type court de 16 bits x, l'adresse en mémoire est 0x0010, la valeur de x est 0x1122, puis 0x11 est l'
octet de poids fort et 0x22 est l'octet de poids faible.

  • Pour le mode big endian, mettez 0x11 dans l'adresse basse, c'est-à-dire 0x0010, et 0x22 dans l'adresse haute, c'est-à-dire 0x0011
  • Pour le mode little endian, c'est tout le contraire

Notre structure X86 couramment utilisée est en mode petit-boutiste, tandis que KEIL C51 est en mode gros-boutiste. De nombreux ARM et DSP sont en mode little-endian. Certains processeurs ARM peuvent également être sélectionnés par le matériel pour être big-endian ou little-endian.

int main()
{
    
    
	int a = 0x11223344;
	return 0;
}

L'octet bas 0x44 est dans l'adresse basse, donc c'est little endian :

insérez la description de l'image ici
insérez la description de l'image ici

2.2.3 Écrire un programme pour juger de l'endianness

Concevoir un petit programme pour déterminer l'endianité de la machine actuelle

int checksys()
{
    
    
	int a = 1;//00 00 00 01
	char* ch = (char*)&a;//char* 截断字节,指针指向低地址数据 
	return *ch;//解引用,返回低地址数据
	//return *(char*)&a;//上面两行代码也可写成一行代码
}
int main()
{
    
    
	int a = checksys();
	if (a==1)//如果低地址保存的数据是1,即0x01,就是低字节
	{
    
    
		printf("小端\n");
	}
	else
	{
    
    
		printf("大端\n");
	}
	return 0;
}

insérez la description de l'image ici


Résumer

L'apprentissage du stockage des données n'est pas encore terminé.

Continuez à apprendre les points de connaissance liés au stockage de données dans le prochain article.

Je suppose que tu aimes

Origine blog.csdn.net/taibudong1991/article/details/124028866
conseillé
Classement