当前位置 博文首页 > 小白元的博客:整形数据在内存中的存储

    小白元的博客:整形数据在内存中的存储

    作者:[db:作者] 时间:2021-09-20 13:56

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

    什么是整形?

    整形有: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;
    }

    //方法二(利用联合体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;
    }

    我们来分析一下:

    ?


    ?

    ?

    cs