整形数据在内存中的存储

整型数据在内存中的存储,是一个值得细细体会的问题,千万不要把它忽视了!!!下面我们来详细谈一谈:

什么是整形?

整形有:char     short      int       long       long long  

各种整形又分为:signed  (有符号型,没有写 signed 这个关键字的类型默认是有符号类型:例如上一行的类型都是有符号类型)

                             unsigned(无符号类型)

各种类型的范围:

认识类型范围前先看看两个密诀:1000 0000    1后面7个0,则表示:2的7 次方  即128

                                                       0111 1111     0后面7个1,则表示:2的7次方减1  即128-1=127

同时请记住边缘数据:2^7 = 128                 2^15 = 32768               2^31 = 2147483648

                                    2^8 = 256                 2^16 =  65536              2^32 = 4294967296

                                    2^10 = 1024             

扫描二维码关注公众号,回复: 4308498 查看本文章

好,现在我们来看看具体类型的范围,注意:下面带括号意思是书写的时候可以省略,系统会自动默认有

(signed)  char  (有符号char整形, 32位机器占一个字节8bit位) 

最小值 1000 0000   [2^7](-128) 每个类型的这种形式都是有符号数的最小值

最大值  0111 1111   [2^7-1] (127)    此时最大值要是再加一,结果就是-128

unsigned char (无符号char整形, 32机器占一个字节8bit位) 

最小值 0000 0000 (0) 

最大值  1111 1111   [2^8-1] (255)    此时最大值要是再加一,结果就是0

(signed)  short  (有符号短整形, 32位机器占两个字节16bit位) 

最小值 1000 0000 0000 0000   [2^15](-32768) 每个类型的这种形式都是有符号数的最小值

最大值  0111 1111  1111 1111    [2^15-1] (32767)    此时最大值要是再加一,结果就是-32768

unsigned short (无符号短整形, 32机器占两个字节16bit位) 

最小值 0000 0000 0000 0000(0) 

最大值  1111 1111  1111 1111    [2^16-1] (65535)    此时最大值要是再加一,结果就是0

(signed)  int  (有符号整形, 32位机器占四个字节32bit位) 

最小值 1000 0000 0000 0000  0000 0000 0000 0000 [2^31](- 2147483648) 每个类型的这种形式都是有符号数的最小值

最大值  0111 1111  1111 1111   1111  1111  1111  1111 [2^31-1] (2147483647)    此时最大值要是再加一,结果就

是-2147483648

unsigned int (无符号整形, 32机器占四个字节32bit位) 

最小值 0000 0000 0000 0000 0000 0000 0000 0000(0) 

最大值  1111 1111  1111 1111   1111 1111  1111  1111 [2^32-1] (4294967296)    此时最大值要是再加一,结果就是0

此时附加一个内容,数据在内存中的存储是大端还是小端?

小端:数据的低位  存放在内存的低地址  称为小端存储方式   :简称小(低位)小(低地址)小(小端)

 大端:数据的高位  存放在内存的高地址  称为大端存储方式

上一张图来解释清楚:

 

看一下具体内存的存储方式(下图是小端存储)

现在让我们来看看关于大小端的笔试题:

//方法一

#include <stdio.h>
#include <windows.h>

int check_sys()
{
	int i = 1;  //内存中 :00 00 00 01  或  01  00  00  00
	return (*(char *)&i);//int型数据地址类型是  int * ,所以现在要强转成char * ,
	                    //因为解引用时我们要按照 char 类型读取1个字节。
}

int main()
{
	int ret = check_sys();//直接用一个函数判断
	if (ret == 1)
	{
	    printf("小端存储\n");
	}
	else
	{
	    printf("大端存储\n");
	}
	system("pause");
	return 0;
}

//方法二(利用联合体enum)

#include <stdio.h>
#include <windows.h>

int check_sys()
{
	union
	{
	    int i;
	    char c;
	}un;//声明并定义
	un.i = 1;
	return un.c;
}

int main()
{
	int ret = check_sys();//直接用一个函数判断
	if (ret == 1)
	{
	    printf("小端存储\n");
	}
	else
	{
	    printf("大端存储\n");
	}
	system("pause");
	return 0;
}

现在我们来总结一下三个结论!!!重要结论!!!

1   往内存中存数据时,直接按照类型大小把数据的 "补码" 存进内存。(正数原码==反码==补码,负数原码取反加1 == 补码)

2   CPU去内存取数据时,遇到整形提升时,看原来数据的类型:有符号数则全部添加符号位,无符号数全加 0

3    打印的时候,输出到屏幕上时,%d 是输出有符号数十进制, 看CPU符号位,正数直接打印,负数符号位不变,其余                                                                   位减1再取反

                                                        %u 是输出无符号数十进制    CPU符号位是0    直接打印

下面我们进入实战演练环节:

1  

#include <stdio.h>
#include <windows.h>

int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a = %d b = %d c = %d\n", a, b, c);
	system("pause");
	return 0;
}

我们来分析一下:


猜你喜欢

转载自blog.csdn.net/qq_42080151/article/details/83472830
今日推荐