C语言数据的存储(下)

简介: C语言数据的存储(上)

5.输出是什么?

int main() {
  unsigned int i;
  for (i = 9; i >= 0; i--)
  {
    printf("%u\n", i);
  }
}

结果在不断的往下打印:

注意unsigned无符号数都是>=0的,unsigned int能放下的最大二进制序列是

11111111 11111111 11111111 11111111

对应的十进制数字是4294967295

当i=0时,0-1=-1

-1的原码

10000000 00000000 00000000 00000001

反码

11111111 11111111 11111111 111111110

补码

11111111 11111111 11111111 11111111

✨如果-1存到一个无符号数的变量里面去,这个时候的最高位不是符号位,被当成一个无符号数来打印

✨在打印的时候,i是一个无符号型的变量,所以虽然里面放的是-1这样的一个值,但是站在i的角度,i里面不会放-1,他认为里面的每一个位都是有效位,是一个很大的数字,这个数字>=0.所以-1放到i这个变量里面,他不会认为是-1,而认为它是一个很大的数字.接下来再不停-1,就会出现很多数字

所以不管i里面放的是什么数,这个数恒>=0,for循环会进入死循环

5.变形(如果以%d打印,结果会怎么样)

✨也会一直死循环,但是可以打印出-1

✨因为在for循环的判断条件,i是无符号类型,所有的位都是有效位,i>=0条件恒成立会进入死循环

✨可以打印出-1是因为打印的时候以%d有符号数的形式打印

6.输出是什么?

int main()
{
  char a[1000];
  int i;
  for (i = 0; i < 1000; i++)
  {
    a[i] = -1 - i;
  }
  printf("%d", strlen(a));
  return 0;
}

详解:

这个循环肯定循环1000次

strlen统计的是\0前字符出现的个数

但是要注意的是✨✨✨

a数组里面的每个元素都是char类型,char的取值范围是-128~127,那么数组元素可以放-1000这样的数字吗?

当a[i]是-128时,二进制序列再-1的时候,就会变成127,不会是-129(如上图箭头的指向)

7.输出是什么?

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

注意:

循环变量用无符号数控制的时候要小心注意啦!

详解:

3.浮点型在内存中的存储

常见的浮点数

3.14159 字面浮点数

1E10 科学计数法表示的浮点数,意思是1.0*10^10

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

整型家族的类型的取值范围:

limits.h中定义

查看limits.h文件:

浮点数表示的范围

float.h中定义

3.1 浮点型存储的例子

int main()
{
int n = 9;
float *pFloat = (float *)&n;
printf("n的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
*pFloat = 9.0;
printf("num的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
return 0;
}

详解:

3.2 浮点数存储规则

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

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

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

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

✨2^E中的E表示指数位。

10进制的5.5转换成二进制数字是多少?

是101.1

这个数字用科学计数法表示,小数点向左移动

1.011*2^2

第一个2是因为二进制的权重是2,第二个2是因为移动了两位

V=5.5

=1.011* 2^2

=(-1)* 0 *1.011 * 2^2

这里的S=0,M=1.011,E=2

所以只需要把S,M,E这三个数字存起来,就能把原来的浮点数还原出来

浮点型二进制序列空间划分

float 32位的浮点数

double 64位的浮点数

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

浮点数数据具体是怎么存进去的呢?

有效数字M

有效数字M,实际上在存储的时候,只存小数点后面的位.当往出拿的时候,拿出小数点后面的位,在小数点前面补个1就能还原出M真实的值.

单精度浮点数,双精度浮点数中的精度表示小数点之后的位存的更多,精度更高.(小数点后存的位是二进制位)

✨当存小数的小数点后面的部分时,二进制位可能会为了凑够小数部分而不断的向后扩张,那么对于可以存放23位小数部分的单精度,可以存放52位小数部分的双精度真的够吗?

🤞可能会不够,所以说也有一些浮点数在内存中是不能够精确保存的.

指数E

首先,E为一个无符号整数(unsigned int)

1.这意味着,如果E为8位,它的取值范围为0~ 255;如果E为11位,它的取值范围为0~2047。

2.但是,我们知道,科学计数法中的E是可以出
现负数的
所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数

3.

对于8位的E,这个中间数是127;

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

比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001

(所以即使我的E是负的,经过修复之后变成正的值,这个时候就可以存到E里面去了)

举例说明

打开内存验证一下浮点数f在内存中存的是什么

解决疑惑

如果E是-130,+127之后认识负数怎么办呢?

🤞float也是有它的取值范围的,就不会让真实的E是-130的.

🤞如果E=-130的话,已经超出float能够表示的最大值和最小值了.所以在能够讨论的范围内讨论.

浮点数怎么从内存中取出来呢?

指数E取出来,分为三种情况:

(1)E的部分不全为1或者不全为0

这是一种常规情况,怎么放进去就怎么倒着拿出来

(2)E全为0

E全为0,说明原来的E加上127之后为0,原来的E是-127,原来的浮点型数据是一个非常小的数据

这个数据是 ± 1.xxx *2^(-127)

这个数据是接近于0的非常小的数字

(3)E全为1

8个比特位全为1的话就是255,这是加了127之后,原来的E是255-127=128

1.xxx*2^128 z这将是一个非常大的数字

在加上最前面的符号位±,表示的就是±无穷大的数字

3.3 分析3.1中的例题

详解


总结

数据的存储内容全部总结到这里啦,如果对小伙伴们有所帮助的话,可以点赞收藏博客,关注后续的C语言学习内容哦~😉👻👻

相关文章
|
2月前
|
存储 C语言
C语言第二十九弹---浮点数在内存中的存储
C语言第二十九弹---浮点数在内存中的存储
|
2月前
|
机器学习/深度学习 编译器 C语言
【C语言】数据输出的域宽控制(如何在输出数据时控制0占位)(如何输出前导0)(保留几位小数)(乘法口诀表打印不齐)等问题
【C语言】数据输出的域宽控制(如何在输出数据时控制0占位)(如何输出前导0)(保留几位小数)(乘法口诀表打印不齐)等问题
28 0
|
1天前
|
存储 编译器 程序员
C语言:数据在内存中的存储
C语言:数据在内存中的存储
8 2
|
15天前
|
存储 编译器 C语言
C语言基础知识:数据在内存中的存储解析(整数,浮点数)
C语言基础知识:数据在内存中的存储解析(整数,浮点数)
|
17天前
|
存储 C语言
C语言动态存储方式与静态存储方式
C语言动态存储方式与静态存储方式
9 0
|
17天前
|
C语言
深入理解C语言中的printf函数及数据输出
深入理解C语言中的printf函数及数据输出
16 0
|
24天前
|
C语言
多组数据的输入方法(c语言实现)
多组数据的输入方法(c语言实现)
|
29天前
|
存储 编译器 C语言
爱上C语言:整型和浮点型在内存中的存储(进制转换,原码,反码,补码以及大小端)
爱上C语言:整型和浮点型在内存中的存储(进制转换,原码,反码,补码以及大小端)
|
2月前
|
存储 编译器 程序员
【C语言】整形数据和浮点型数据在内存中的存储
【C语言】整形数据和浮点型数据在内存中的存储
17 0
|
2月前
|
存储 人工智能 小程序
C语言第二十八弹---整数在内存中的存储
C语言第二十八弹---整数在内存中的存储