当前位置 博文首页 > 小白元的博客:整形数据在内存中的存储
整型数据在内存中的存储,是一个值得细细体会的问题,千万不要把它忽视了!!!下面我们来详细谈一谈:
什么是整形?
整形有: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? ? ? ? ? ? ?
好,现在我们来看看具体类型的范围,注意:下面带括号意思是书写的时候可以省略,系统会自动默认有
(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;
}
#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? ??直接打印
下面我们进入实战演练环节:
#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;
}
我们来分析一下:
?
?
?
cs