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;
}
相关文章
|
9天前
|
存储 程序员 编译器
C 语言中的数据类型转换:连接不同数据世界的桥梁
C语言中的数据类型转换是程序设计中不可或缺的一部分,它如同连接不同数据世界的桥梁,使得不同类型的变量之间能够互相传递和转换,确保了程序的灵活性与兼容性。通过强制类型转换或自动类型转换,C语言允许开发者在保证数据完整性的前提下,实现复杂的数据处理逻辑。
|
12天前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
34 6
|
13天前
|
存储 数据建模 程序员
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
|
19天前
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
45 11
|
2月前
|
监控 算法 应用服务中间件
“四两拨千斤” —— 1.2MB 数据如何吃掉 10GB 内存
一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。
|
1月前
|
C语言
【c语言】动态内存管理
本文介绍了C语言中的动态内存管理,包括其必要性及相关的四个函数:`malloc`、``calloc``、`realloc`和`free`。`malloc`用于申请内存,`calloc`申请并初始化内存,`realloc`调整内存大小,`free`释放内存。文章还列举了常见的动态内存管理错误,如空指针解引用、越界访问、错误释放等,并提供了示例代码帮助理解。
46 3
|
2月前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
80 1
|
2月前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
2月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
32 0
|
4月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
399 0