数据的存储(进阶)中

简介: 笔记

习题2

#include <stdio.h>
int main()
{
    char a = -128;
    printf("%u\n",a);
    return 0; 
}

1.png2.png

习题3

 #include <stdio.h>
 int main()
 {
  char a = 128; 
  printf("%u\n", a);
  printf("%d\n", a);
  return 0;
 }

3.png

这个跟前面的题一样都是先发生截断,然后整形提升,然后再打印

习题4  

1. #include <stdio.h>
2. int main()
3. {
4.  int i = -20;
5.  unsigned int j = 10;
6.  printf("%d\n", i + j);
7.  return 0;
8. }


4.png

习题5  unsigned三码习题

1. #include<stdio.h>
2. int main()
3. {
4.  unsigned int i;
5.  for (i = 9; i >= 0; i--)
6.  {
7.    printf("%u\n", i);
8.  }
9.  return 0;
10. }


5.png

我们看到这里9-0都是正常打印但是到-1就出现了问题,具体原因请看下图

0.png6.png

二进制下的32个1,换成十进制为一个特别大的数字,所以会打印4294967295,之后每次i--这个数都会减一


习题6 signed char取值范围问题

#include<stdio.h>
#include<string.h>
int main()
{
  char a[1000];
  int i;
  for (i = 0; i < 1000; i++)
  {
    a[i] = -1 - i;
  }
  printf("%d", strlen(a));
  return 0;
}


7.png

这里把数字放入到数组a中,而a是char类型,范围为-128~127

8.png

这里是-1-i,其实就是上面这个图逆序的走法,从-1~-128~127~0


\0的ASCII码值是0,strlen遇到\0会停下来,所以在遇到0之前,数组里面已经存了128+127个数字了,所以打印255


习题7  无符号char取值范围习题

#include<stdio.h>
unsigned char i = 0;
int main()
{
  for (i = 0; i <= 255; i++)
  {
  printf("hello world\n");
  }
  return 0;
}


9.png

程序运行后会进入死循环,这是因为i是unsigned char类型范围是0~255,前面有说过,i为255之后,i+1,此时i又变为0,陷入死循环


习题8 关于strlen返回值类型的习题

#include<stdio.h>
#include<string.h>
int main()
{
  if (strlen("abc") - strlen("abcdef") >= 0)
  printf(">");
  else
  printf("<");
  return 0;
}

10.png

这里会打印>是因为strlen返回值为unsigned int类型,无论怎样运算结果都>=0.


可点开这个链接,最后面有一道类似的题


浮点型在内存中的存储


浮点数家族包括: float 、 double 、 long double 类型。

浮点数表示的范围: float.h 中定义

11.png

用everything查找float.h然后用VS打开,就可看到浮点数的范围,整形输入litmits.h可查看范围

12.png

浮点数存储规则

根据国际标准 IEEE (电气和电子工程协会) 754 ,任意一个二进制浮点数 V 可以表示成下面的形式:

(-1)^S * M * 2^E

(-1)^S 表示符号位,当 S=0 , V 为正数;当 S=1 , V 为负数。

M 表示有效数字,大于等于 1 ,小于 2 。

2^E 表示指数位。

举例来说:

十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。

那么,按照上面V的格式,可以得出S=0,M=1.01,E=2。

十进制的-5.0,写成二进制是 -101.0 ,相当于 -1.01×2^2 。那么,S=1,M=1.01,E=2。

9.5f其实用二进制表示为:1001.1,这跟权重有关系,因为2^-1为0.5


1001.1=1.0011*2^3


S=0,M=1.0011,e=3


例:9.6f


二进制:1001.XXXXXX,因为这个0.6不好表示,需要一堆0和1,但是如果数字过多就有可能存不下,因此浮点数就产生了精度问题


float 4byte double 8byte


浮点数如何保存

IEEE 754 规定:

对于 32 位的浮点数,最高的 1 位是符号位 s ,接着的 8 位是指数 E ,剩下的 23 位为有效数字 M 。

13.png

特别规定:


前面说过, 1≤M<2 ,也就是说, M 可以写成 1.xxxxxx 的形式,其中 xxxxxx 表示小数部分。

IEEE 754 规定,在计算机内部保存 M 时,默认这个数的第一位总是 1 ,因此可以被舍去,只保存后面的 xxxxxx部分。

比如保存 1.01 的时 候,只保存01 ,等到读取的时候,再把第一位的 1 加上去。

这样做的目的,是节省 1 位有效数字。以 32 位 浮点数为例,留给M 只有 23 位, 将第一位的1 舍去以后,等于可以保存 24 位有效数字。


指数E的存放规则

首先, E 为一个无符号整数( unsigned int),这意味着,如果 E 为 8 位,它的取值范围为 0~255 ;如果 E 为 11 位,它的取值范围为 0~2047 。

如0.5=1.0*2^-1 M=1.0,E=-1,S=0

E为负数不在范围之内,所以 IEEE 754规定,存入内存时 E 的真实值必须再加上一个中间数:

                          对于 8 位的 E(float) ,这个中间数是127。

                           对于 11 位的 E(double) ,这个中间 数是 1023 。

刚才E=-1,按float类型,E+127=126,把126存放到E所在的空间当中(8个bit)


14.png

15.png16.png


相关文章
|
2月前
|
存储
C进阶:数据在内存中的存储(2)
C进阶:数据在内存中的存储(2)
|
2月前
|
存储 编译器 C语言
C进阶:数据在内存中的存储(1)
C进阶:数据在内存中的存储(1)
|
6月前
|
存储 人工智能 编译器
【C进阶】深度剖析数据在内存中的存储
【C进阶】深度剖析数据在内存中的存储
31 0
|
9月前
|
存储 小程序 编译器
【数据的存储】(深度剖析)
带你深度剖析数据在内存中的存储
|
12月前
|
存储 小程序 编译器
C进阶:数据在内存中的存储
这样我们就彻底理解了浮点数在内存中的存储规则。还是开头说的,其实这部分内容真的很难考到,学习这些知识更像是一种修炼内功,让我们理解的更加透彻,拓展我们的知识面,如果遇到这样的现象能够去解释,关于素养的这种实际价值就靠自己体会了。好了,以上就是C进阶数据在内存中的存储内容。
C进阶:数据在内存中的存储
|
12月前
|
存储
数据的存储知识点总结
数据的存储知识点总结
|
存储 机器学习/深度学习 编译器
【C进阶】第十篇——数据在内存中的存储
【C进阶】第十篇——数据在内存中的存储
【C进阶】第十篇——数据在内存中的存储
|
存储 编译器 C语言
|
存储 移动开发 缓存
H5 存储 | 学习笔记
快速学习 H5 存储
H5 存储 | 学习笔记