C语言----数据在内存中的存储(2)

简介: C语言----数据在内存中的存储

C语言----数据在内存中的存储(1)https://developer.aliyun.com/article/1544437

#include <stdio.h>
int main()
{
    char a[1000];
    int i;
    for (i = 0; i < 1000; i++)
    {
        a[i] = -1 - i;
    }
    printf("%d", strlen(a));//255
    return 0;
}
/*
因为这是一个char类型的数组,取值范围是-128~127的
-1 -2 -3 -4 ……………………-128 127 ……3 2 1 0 -1 -2 -3
-1到128是128个人元素,127到1是127个元素
那么总共就是255个元素了
 
 
因为strlen统计的是字符串中元素的个数,
并且检查的是'\0'之前的数
所以这个字符串数组内存在255个元素
*/
#include <stdio.h>
unsigned char i = 0;//全局变量
//因为这个char是unsigned char,无符号的char类型
int main()
{
    for (i = 0; i <= 255; i++)
    {
        printf("hello world\n");//打印无限个
    }
    return 0;
}
//因为前面有一个全局变量范围是0~255
//而循环的范围是i<=255,那么这个循环的条件恒成立,可以一直循环
//那么对于打印来说就是无限进行打印操作
//无限循环
#include <stdio.h>
int main()
{
    unsigned int i;//无符号整型,最小值是0
    //对于这个循环来说,i>=0就恒成立了,这个循环就一直进行
    for (i = 9; i >= 0; i--)
    {
        printf("%u\n", i);
        Sleep(100);
    }
    return 0;
}
 
/*
9
8
7
6
5
4
3
2
1
0
----------
0-1就变成-1了,-1被%u打印的时候将是一个非常大的数字
4294967295
 
…………………………下面就是非常大的数字了
 
*/
#include <stdio.h>
//X86环境 ⼩端字节序
int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int* ptr1 = (int*)(&a + 1);
    //&a+1就是跳过一整个数组,指向这个数组的末尾
    //
    // 将这个地址强制类型转换为int*赋值给ptr1,那么ptr1指向的就是这个数组的末尾
    // ptr1[-1]---->*(ptr1-1)
    // 因为ptr1是整型指针,那么-1就是指向了4的位置,那么解引用得到的就是4
    // 
    // 那么4用16进制打印得到的还是4
    //
 
    int* ptr2 = (int*)((int)a + 1);
    /*
    这里的a是数组首元素的地址,那么被强制类型转换为整数类型,
    那么(int)a+1就是+1
    a是占4个字节的,但是被转换为整型了并且+1,那么现在就离开始的位置相差1个字节了
    所以ptr2指向就是离首元素地址差1个字节的地址的位置
    因为ptr2是整型指针,那么就是4个字节,从那个位置开始向后访问4个字节
 
    01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
 
    所以就是从第2个00开始访问到02
    00 00 00 02--因为这个地址在内存中是小端存在的,
    所以原始的就是02 00 00 00
    换成16进制的就是0x02 00 00 00
    所以打印出来的就是2000000,最前面的0x0是不打印的
    */
 
 
    printf("%x,%x", ptr1[-1], *ptr2);//4,2000000
 
    //%x是16进制的形式打印的
 
    return 0;
}

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

#include <stdio.h>
int main()
{
    int n = 9;//原反补相同
    //00000000  00000000  00000000  00001001-----9
    //
    //
    float* pFloat = (float*)&n;
    //取出n的地址并强制类型转换为float*类型的指针
    //再赋值给pFloat,那么pFloat指向的就是二进制的起始位置
 
 
 
    printf("n的值为:%d\n", n);//9
 
 
 
    printf("*pFloat的值为:%f\n", *pFloat);//0.000000
    //这个pFloat是浮点型指针,
    //站在*pFloat的角度上看,他会认为内存中存的是浮点数
    // 那么这次就是以浮点数的形式取出这个值
    // 因为整数和浮点数在内存中的存储形式不同
    // 所以我们将二进制转换为S M E类型的进行读
    // 0   00000000    00000000000000000001001
//    S      E            M     
//  他会认为这个数是以S E M类型存在的  
    //E为全0的时候,那么是E+127=0,所以E就是-127
    //那么这个数最后算出来就是一个正负无穷接近于0的数字
 
    //那么打印出来的数是0.000000 
 
    *pFloat = 9.0;
    //1001.0---小数点向左移动3位,所以下面的科学计数法就是乘2的3次方
    // 加上正负的处理的话(-1)^0
    //科学计数法的形式:(-1)^0 * 1.001 * 2^3
    //
    // S=0
    // M=1.001
    // E=3
    // S=0    E=127+3=130    M--小数点后面的是001,还要满23个比特位,所以补上20个0
    // 0      10000010       00100000000000000000000
// 所以9.0在内存中的二进制序列是01000001000100000000000000000000
    // 其实是放到n的位置空间内了,因为pFloat指向的是n的起始位置
    //
 
    /*
    站在n的角度上,我们得到的科学计数法的数是补码
    那么我们就要把原码算出来 
    因为高位是0,所以是正数,正数的原码补码反码相同
 
    所以这个二进制换算的十进制的数就是1091567616
    */
    printf("num的值为:%d\n", n);//1091567616
    printf("*pFloat的值为:%f\n", *pFloat);//9.000000
    return 0;
}
 
 
/*
我们要清楚我们是以什么形式放进去的,怎么形式取出来的,
 
我以整数的形式放进去的,我以整数的视角取出来,那么就按照整数的视角计算原反补
我以浮点数的形式放进去的,我以浮点数的视角取出来,那么我们就按S M E相关的东西进行计算
 
不理解就看代码
*/
 
/*
总之,就是浮点数和整数在内存中的存储方式是不同的
 
浮点数是S M E 
我们可以利用二进制序列来得到这三个数据,进而得到我们浮点数在内存中的存储形式
 
 
*/

常见的浮点数:3.14159、1E10--科学计数法

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

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

整数和浮点数在内存中的存储方式是有区别的

10进制:5.5

2进制:101.1

5.5=(-1)^011.011*2^2

S=0

M=1.011

E=2

E是无符号的数

小数点后面的1就是表示2的负几次方,从-1开始

浮点数的存储,存储的就是S、M、E相关的值

对于32位的浮点数,最高的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M

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

1<M<2

在计算机内部保存M的时候,默认这个数的第一位总是1,因此可以被舍去,只保留后面的xxxx部分,xxxx部分表示小数部分

所以我们在存M的时候,一般存的都是小数点后面的位

10进制的0.5

2进制的0.1

科学计数法:1.0*2^-1

在存储E的时候还会添加中间值.float添加127

double添加1023

再将得到的值存在E的内存中

之前已经说过浮点数的存储,存储的就是S、M、E相关的值

取出来的三种情况:

1.正常存E的时候是E+中间值(127/1023),那么将这个取出来减去中间值就得到了E,对于M,将M取出+1就是我们要的M----这里的E不全为0或者不全为1

2.E为全0,那么取出来的E为-127,表示的就是正负无穷接近于0的数字

3.E为全1,如果全是1的话,那么刚好8个比特位,就是8个1,就是255

E+中间值(127)=255,那么E就是128

那么这个数也是一个正负无穷大的数字

int main()
{
    float f = 5.5f;
    //S=0;
    //E=2
    //M=1.011
    //0    10000001            01100000000000000000000
    //S   E--129=(127+2)       M--存的是小数点后面的-总共有23个比特位,那么剩下的20位补0
    //0100  0000  1011  0000  0000  0000  0000  0000
    //              11在16进制就是b
    // 4      0     b    0     0      0    0      0
    // 0x40b00000--最后得到的数据--浮点数5.5在内存中得到的形式
    //得到的二进制数每4个二进制位就能换一个16进制数
 
 
 
    return 0;
}
相关文章
|
3天前
|
存储 C语言
数据在内存中的储存
数据在内存中的储存
8 3
|
3天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
11 2
|
6天前
|
存储
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)
|
2天前
|
存储 C语言
【海贼王编程冒险 - C语言海上篇】C语言中的数据类型有哪些?又是如何存储?
【海贼王编程冒险 - C语言海上篇】C语言中的数据类型有哪些?又是如何存储?
5 0
|
2天前
|
存储 C语言
【C语言进阶篇】整数在内存的存储——原码、反码、补码
【C语言进阶篇】整数在内存的存储——原码、反码、补码
|
11天前
|
消息中间件 存储 Kafka
实时计算 Flink版产品使用问题之 从Kafka读取数据,并与两个仅在任务启动时读取一次的维度表进行内连接(inner join)时,如果没有匹配到的数据会被直接丢弃还是会被存储在内存中
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
7天前
|
存储
数据在内存中的存储(2)
数据在内存中的存储(2)
21 5
|
7天前
|
存储 小程序 编译器
数据在内存中的存储(1)
数据在内存中的存储(1)
25 5
|
7天前
|
存储 安全 Java
SpringSecurity6从入门到实战之初始用户如何存储到内存
Spring Security 在 SpringBoot 应用中默认使用 `UserDetailsServiceAutoConfiguration` 类将用户信息存储到内存中。当classpath有`AuthenticationManager`、存在`ObjectPostProcessor`实例且无特定安全bean时,此配置生效。`inMemoryUserDetailsManager()`方法创建内存用户,通过`UserDetails`对象填充`InMemoryUserDetailsManager`的内部map。若要持久化到数据库,需自定义`UserDetailsService`接口实
|
6天前
|
存储 编译器 C语言
数据在内存中的存储
数据在内存中的存储
14 2