C语言数据在内存中的存储流程深入分析

 更新时间:2022年10月26日 09:05:04   作者:二月知野  
使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。您可能需要存储各种数据类型的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么

前言

C语言中有char、short、int、long、long long、float和doubole这些数据类型。这些数据类型也叫内置类型。

所占存储空间的大小:

数据类型所占存储空间的大小
char1个字节
int4个字节
short4个字节
long4个字节
long long32位平台下占4个字节 ,64位平台下占8个字节
float4个字节
double8个字节

类型的基本分类

整型

整型一共有char、int、short、long和long long这五种类型。

char类型的数据在内存中存放的是ASCII码值,是整型,所以也被当成整型。

这些整型都分为有符号的整型和无符号的整型,具体可以看下面:

	int a = 5;
	signed int b;//有符号的整型
	unsigned int c;//无符号的整型

signed是有符号的,unsigned是无符号的。

平时我们定义变量时,一般都不会加前面,只是int 变量名 = 数据,其实这就相当于signed int 变量名 = 数据。

注意 \color{#FF0000}{注意} 注意 :但是char这个类型比较特殊,在C语言的标准中,没有定义char到底是有符号的还是无符号的,取决于编译器。

关于无符号和无符号:

前面我们说到了int类型在内存中占4个字节,1个字节就是8个bit。

比特位即bit,是计算机最小的存储单位。以0或1来表示比特位的值(二进制表示)。

10的二进制序列就如图所示,其中第一位是符号位,0代表正数,1代表负数

浮点数

浮点数有float和double,一般用来表示小数。

float的表示精度低,存储数值范围较小。

double的表示精度高,存储数值范围较大。

自定义类型

自定义类型有数组类型、结构体类型、枚举、联合体、指针类型和空类型(void)。在这就不一一详细讲了。

整型在内存中的存储

在了解整型在内存中的存储前,先了解一个计算机的原码、反码、补码。

原码、反码、补码

数值表示形式有:二进制、八进制、十进制和十六进制。

整数的二进制也有三种表达形式:原码、反码、补码。

整数中:

正数的原码反码补码相同

负数的原码反码补码是需要计算的

  • 原码:整数的二进制序列(注意符号位)
  • 反码:符号位不变,其它位按位取反就是反码(0变1,1变0)
  • 补码:反码加1就是补码

整型在内存中存放的是补码

接下来来验证内存中存放的是补码:

我定义了一个a变量,值为-10. 原码反码和补码也给大家了,因为正整数的原码、反码和补码相同,所以不用正整数验证。接下来让我们来用编译器来调试并监视来观察内存,来看看整型在内存中是如何存储的。

看上图,虽然这里面看到的是十六进制,但不要认为是以十六进制存储的,但本质存的还是二进制序列。由此我们可以得出内存中存放的是补码。

大端和小端

我们看到上图a的地址和我们写的十六进制序列是反着的,为什么?这就是大小端的问题了。

大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址

中; 小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地 址中。

如何判断编译器是大端还是小端

int main()
{
	int a = 1;
	if(*(char*)&a == 1)
	{
		printf("小端")
	}
	else
	{
		printf("大端")
	}
}

如果是小端存储存储的顺序应该是01 00 00 00 大端的话是00 00 00 01

我们对a进行取地址,然后强转成char类型的指针然后再进行解引用,因为强制类型转换了,所以只能访问1个字节的地址,如果得到的1就是小端,0就是大端。

浮点数在内存中的存储

根据国际标准IEEE(电气和电子工程协会)754,一个浮点数 (Value) 的表示其实可以这样表示:

也就是浮点数的实际值,等于符号位(sign bit)乘以指数偏移值(exponent bias)再乘以分数值(fraction)。

简单来说就是对于浮点数在内存中的存储,无论是float(32位浮点数)还是double(64)位浮点数(S),都有符号位(Exp),指数位和有效数字位(Fraction)。

对于float这种32位浮点数来说,指数位占8个bite位,有效数字位占23个bite位

对于double这种64位浮点数来说,指数位占11个bite位,有效数字位占52个bite位

符号位都是占1个bite位。

其中因为浮点数的小数部分,用二进制中难以存储,就会存在精度不准的问题。

单精和双精浮点数的有效数字分别是有存储的23和52个位,加上最左手边没有存储的第1个位,即是24和53个位。

由以上的计算,单精和双精浮点数可以保证7位和15位十进制有效数字。

总结

对于数据在内存中的存储,大家还是要重点掌握原码、反码和补码的,要会计算,然后是浮点数的存储方式,可以把它当成一个拓展知识来了解,拓展一下眼界,如果真要熟练掌握浮点数的存储规则是要研究很多东西的,大家感兴趣也可以去看一下国际标准IEEE754。

到此这篇关于C语言数据在内存中的存储流程深入分析的文章就介绍到这了,更多相关C语言数据在内存中的存储内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ 实现读写锁的代码详解

    C++ 实现读写锁的代码详解

    C++读写锁是一种多线程同步机制,它允许多个线程同时读取共享数据,但只允许一个线程写入共享数据,这种锁可以提高程序的并发性和性能,本文给大家介绍了C++ 实现读写锁的代码,需要的朋友可以参考下
    2023-10-10
  • C++ WideCharToMultiByte()函数案例详解

    C++ WideCharToMultiByte()函数案例详解

    这篇文章主要介绍了C++ WideCharToMultiByte()函数案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C语言中send()函数和sendto()函数的使用方法

    C语言中send()函数和sendto()函数的使用方法

    这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C语言动态内存规划详解

    C语言动态内存规划详解

    这篇文章主要介绍了C语言动态内存的规划,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-10-10
  • C++实现学生档案管理系统

    C++实现学生档案管理系统

    这篇文章主要为大家详细介绍了C++实现学生档案管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Linux线程同步之信号C语言实例

    Linux线程同步之信号C语言实例

    这篇文章主要介绍了Linux线程同步之信号C语言实例,本文直接给出代码实例,需要的朋友可以参考下
    2015-04-04
  • C语言 sizeof 函数详情

    C语言 sizeof 函数详情

    这篇文章主要介绍了C语言 sizeof 函数,在 C 语言中,char 字符串也是一种非常重要的数据类型,我们除了使用 sizeof 函数获取字符串长度之外,使用 sizeof 函数同样也可以完成字符串长度的获取,下面文章内容具体描述该内容,需要的朋友可以参考以下
    2021-10-10
  • C语言实现实时钟表

    C语言实现实时钟表

    这篇文章主要为大家详细介绍了C语言实现实时钟表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • C++野指针的具体实现

    C++野指针的具体实现

    野指针就是指针指向的不是一个有效(合法)的地址,本文主要介绍了C++野指针的具体实现,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03
  • C++强制类型转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)

    C++强制类型转换(static_cast、dynamic_cast、const_cast、reinterpret_ca

    本文主要介绍了C++强制类型转换,主要介绍了static_cast、dynamic_cast、const_cast、reinterpret_cast的4种方法,感兴趣的可以了解一下
    2021-08-08

最新评论