当前位置:网站首页>[C language advanced] The first in-depth analysis of the storage of integer data in memory (1)

[C language advanced] The first in-depth analysis of the storage of integer data in memory (1)

2022-08-11 05:45:00 Xiaolu's road to programming

在这里插入图片描述

前言

Integer data introduction

数据类型介绍

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

unsigned 和signed

Before we talk about integer data types, let's talk about these two keywords
unsigned:无符号 signed:有符号
There is a lot of data in our life,The data are also divided into positive and negative numbers ,such as some numbers,有正数,没有负数(身高)
有些数值 ,有正数也有负数(温度)
比如温度-5 和+15,This is the size of the data we want to use symbols to distinguish,There needs to be positive and negative to describe the data,I will use it thenunsigned和signed来描述.

Integer data family

charunsigned char ,signed char
shortunsigned short, signed short
intunsigned int,signed int
longunsigned long ,signed long
long longunsigned long long ,signed long long

指针类型

int *pa;
char *pb;
float *pc;
void *pd;

void 表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型

Storage of integer data in memory

原码,反码,补码

计算机中的整数有三种2进制表示方法,即原码、反码和补码.
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位
正数的原、反、补码都相同.
负整数的三种表示方法各不相同.

原码 反码 Two's complement conversion method:

原码
直接将数值按照正负数的形式翻译成二进制就可以得到原码.
反码
将原码的符号位不变,其他位依次按位取反就可以得到反码.
补码
反码+1就得到补码.

代码演示:

#include<stdio.h>
int main()
{
    
	int a = 20;//4byte(字节)=32bit
	//00000000000000000000000000010100 20原码
	//00000000000000000000000000010100 20反码
	//00000000000000000000000000010100 20补码
	//20是正整数,所以原码,补码,反码相同


	int b = -20;
	//10000000000000000000000000010100 原码
	//11111111111111111111111111101011 反码
	//11111111111111111111111111111100 补码
	return 0;

}

到这里,我们可看出,对于整形来说:数据存放内存中其实存放的是补码.
Below we a code snippet to explain

在这里插入图片描述
bConvert the binary to hexadecimal,is the same as the hex stored in memory.所以由此可以得出::数据存放内存中其实存放的是补码.

Why memory storage is two's complement

使用补码,可以将符号位和数值域统
一处理;同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路.

代码演示

You can think about what the result of this code is,Maybe you will say it directly-1 -1 -1;But the results were different,Listen to my explanation below.

#include<stdio.h>
int main()
{
    
	char a = -1;
    //10000000000000000000000000000001 原码
	//11111111111111111111111111111110 反码
	//11111111111111111111111111111111 补码 
	//上面我们已经说了,内存中存储的是补码,但是charThe size in memory is one section
	//只能存储8个bit位,所以这里会发生截断
	//截断后存储在a中
	//11111111 -a
	//这里是%d形式打印,然而a的类型为char,So here it will be shaped and improved,So fill up high.
	//这里a是有符号,Complement with the sign bit
	//11111111111111111111111111111111 after replacementa
	//The data printed out is the original code,So we're going to place the parts behinda,转换成原码
	//11111111111111111111111111111110 反码
	//10000000000000000000000000000001 原码,得出结果为-1,Same as print value.

	signed char b = -1;
	//11111111111111111111111111111111 补码 
	//11111111 -b
	//This is also the same as the above method


	unsigned char c = -1;
	//11111111111111111111111111111111 补码 
	//11111111 -c
	//There is a slight change hereunsigned,unsignedUnsigned role
	//截断后存储在c中
	//11111111 -c unsigned忽略符号位,高位补0.
	//00000000000000000000000011111111 after replacementc
	//符号位为0,是正整数
	//所以原码,补码,反码相同
	//00000000000000000000000011111111 原码

	printf("a=%d,b=%d,c=%d", a, b, c);
	return 0;
}

打印结果:
在这里插入图片描述

图片解读:
在这里插入图片描述
Let's have a better understanding of the above knowledge in another code
代码演示:

%uis to print an unsigned integer,It is considered that the complement stored in memory corresponds to an unsigned number
%dis a signed integer that prints,It is considered that the complement stored in memory corresponds to a signed number

#include<stdio.h>
int main()
{
    
	char a = -128;
	//10000000000000000000000010000000 原码
	//11111111111111111111111101111111 反码
	//11111111111111111111111110000000 补码
	//10000000 -a Truncated binary
	//11111111111111111111111110000000 Sign bit high-order complement
	//%u打印无符号整形,So we consider his inverse 补码 原码相同.


	char  b = -128;
	//10000000000000000000000010000000 原码
	//11111111111111111111111101111111 反码
	//11111111111111111111111110000000 补码
	//10000000 -a Truncated binary
	//11111111111111111111111110000000 Sign bit high-order complement
	//%dPrint signed integer,So we have to replace the complement code with the original code.
	//11111111111111111111111101111111 反码
	//10000000000000000000000010000000 原码

	printf("%u\n %d\n", a,b);
	return 0;

打印结果:
在这里插入图片描述

Unsigned and signed ranges

图解:
以char型为例
在这里插入图片描述

以signed为例,It can be found that its corresponding range is a circular loop.
在这里插入图片描述

大小端

什么是大小端

大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址
中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地
址中

图解以字节为单位存储
在这里插入图片描述
为什么会有大小端之分呢?

这是因为在计算机系统中,我们是以字节为单位的,每个地址单元
都对应着一个字节,一个字节为8 bit.但是在C语言中除了8 bit的char之外,还有16 bit的short型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题.因此就导致了大端存储模式和小端存储模式

判断当前机器的字节序(大小端之分)

代码实现

#include<stdio.h>
int main()
{
    
	int a = 1;
	char* p = (char*)&a;
	if (*p == 1)
		printf("小端\n");
	else
		printf("大端\n");
	return 0;
}

图解
在这里插入图片描述
分析:
We take the first byte from little endian01,Take out the first byte in big endian00,这样就能判断
是小端还是大端. 用char的指针来访问第一个字节,charpDereferencing accesses a byte,&aTake out the address to cast intochartype and then paycharpa的指针,对paDereference can access the content of a byte.

总结

码文不易,给个三连,谢谢

在这里插入图片描述

原网站

版权声明
本文为[Xiaolu's road to programming]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/223/202208110512530652.html