C语言基础-数据的存储

C语言基础-数据的存储,第1张

数据的存储 数据类型
  • 意义:

    • ①:数据类型决定了系统为其开辟内存空间的大小
    • ②:决定了系统如何解析内存中的值
数据在内存中的存储方式
  • 大端字节序

    • 数据的低位保存在内存的高地址中,数据的高位保存在内存的低地址中。
  • 小端字节序

    • 数据的低位保存在内存的低地址中,数据的高位保存在内存的高地址中
整型在内存中的存储
  • char 符号类型

    • 可以存储的范围是:-128-127
      • 其中,char类型下 127+1 的结果是-128
      • char类型下 -128 -1 的结果是 127
由于char类型进行算术运算时需要整形提升,下面省略整形提升步骤。
需了解整形提升可参考该文档
[C语言基础-隐式类型转换(整形提升)](https://blog.csdn.net/qq_41854797/article/details/124501756?spm=1001.2014.3001.5502)
-128
1111 1111 1111 1111 1111 1111 1000 0000 原码
1000 0000 0000 0000 0000 0000 0111 1111 反码
1000 0000 0000 0000 0000 0000 1000 0000 补码

-128-1 相当于 -128 +-1-1 的补码:
1111 1111 1111 1111 1111 1111 1111 1111

-128 +-1):
   1000 0000 0000 0000 0000 0000 1000 0000 
+  1111 1111 1111 1111 1111 1111 1111 1111
------------------------------------------
= 11000 0000 0000 0000 0000 0000 0111 1111
因为 变量需强转char类型,只能存储1个字节,
所以需要从结果中截取一个字节(8个比特位)的数据作为其结果。
也就是:0111 1111 = 127
  • unsigned int
  • unsigned char
浮点型在内存中的存储及解析
  • 二进制浮点数表现及存储的形式:

    • 公式:

      • (-1)^S * M * 2^E
    • (-1)^S表示符号位,当S=0,V为正数;
      当S=1,V为负数

    • M表示有效数字,大于1且小于2

      • IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此社区,只保存后面的XXXXXXX部分。比如保存1.01时,只保存01,等到读取的时候,再把第一位1加上去,这样做的目的是节省1一位有效数字。
    • 2^E 表示指数位

      • E为一个无符号整型

      • E要存储到内存中要加上一个中间值,
        然后和再转为二进制

        • 32位(float类型)

          • 要加上127
        • 64位(double类型)

          • 要加上1023
    • 如何计算并存储:

      • float a = 9.5;
      • ①:因为9.0是正数,所以(-1)^0
      • ②:求出9和0.5的二进制位数
        10001.1
      • ③:求出E
        10001.1 小数点向左移动四位 E = 4
      • ⑤:合起来为:
        0 * 00010000 00000000 0000000 * 10000011
      • ⑥:在内存中存储的方式
        符号位(首位)指数位(8位)小数点后的小数(23位)
        0 10000011 00010000 00000000 0000000
      • 注意:32位下,符号位长度为1,指数位为8位,小数点后的小数为23位。
        64位,符号长度不变,指数位为11位,小数位为52位。
  • 二进制浮点数解析(32位):

    • 十六进制存储:00 00 10 41
      转换为二进制:0 10000011 00010000 00000000 0000000
      0为符号位,10000011 为指数位 剩下的为小数位

    • M为1+剩下的为小数位
      E为10000011 - 127
      解析为: 1.0001 * 2^4 = 10001
      还原为10进制: 9

    • 指数E从内存中取出
      还可再分三种情况:

      • ①:E不全为1或不全为0

        • 这时,浮点数采用指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位1。比如:0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0*2^(-1),其阶码为-1+127=126,表示0111 1110,二位数1.0去掉整数部分为0,补齐0到23位,则二进制表示为:0 01111110 00000000000000000000000
      • ②:E全为0

        • 这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位1,而是还原为0.xxxxxx的小数,这样做是为了表示±0,以及无限接近与0的数字
      • ③:E全为1

        • 这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位S)
  • 例题

 float a = 9.0;
 在内存中存如何存放:

  int n = 9;
   //9的二进制
   //00000000 00000000 00000000 00010001
   // 9  以 float在内存中存储方式。
   
   //(-1)^0 * 1.0001 *2^4 (32位)
   //0 10000011 00010000 00000000 0000000
   //00000000101011001000000000000000
   float *p = &n;
   printf("%d\n",n);
   //此时按照float拿的数据为, 0 00000000 0000000 00000000 00010001
   //当E 全为0时,M不在加上第一位的1,而是还原小数0.xxx的小数,这样做为了表示正负0,以及接近0很小的数字。
   printf("%lf\n",*p);
  
   *p = 9.0;
   // 9  以 float在内存中存储方式。
  
   //(-1)^0 * 1.0001 *2^4 (32位)
   //0 10000011 00010000 00000000 0000000
   //0 10000011 00010000 00000000 0000000
	   //n的值为:1099431936
  printf("%d\n", n);
   //p为9.0
   printf("%lf\n", *p);

运行结果截图:

大小端字节序的介绍及判断
  • 介绍

    • 大端字节序

      • 数据的低位保存在内存的高地址中,数据的高位保存在内存的低地址中。
    • 小端字节序

      • 数据的低位保存在内存的低地址中,数据的高位保存在内存的高地址中
  • 判断系统是大端还是小端

    • 例题:
判断系统是大端还是小端:

int test1(){

	int num = 1;
/*
  思路:
	看下图:
*/
	return *(char*)#


}

void main(){
	if (test1()){
		printf("小端");
	}else{
		printf("大端");
	}
}

运行结果:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/789218.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存