【维生素C语言】第九章 - 数据的存储(一)

简介: 本章将学习C语言数据的存储,对数据类型进行详细的介绍。正式讲解原码、反码、补码,以及大小端等知识,还会对浮点数的存储进行一个探讨,介绍IEEE754规定。


9f85917a8f7021b22dcd0921bff9bd49_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png

前言


本章将学习C语言数据的存储,对数据类型进行详细的介绍。正式讲解原码、反码、补码,以及大小端等知识,还会对浮点数的存储进行一个探讨,介绍IEEE754规定。


一、数据类型介绍


0x00 内置类型

936c56538e5ec6f243df3b61ad3e11cf_2021060916174152.png

0x01 类型的意义

📚 意义:


     ① 类型决定开辟内存空间的大小(大小决定了使用的范围)


     ② 类型决定了看待内存空间的视角


二、类型的基本归类


0x00 整型家族

b15cc6b6841a00a00c6a2afbbc660b1a_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png

❓ 为什么 char 算整型:


因为字符类型底层存储的是 ASCII 码值,而ASCII码值也是整数,所以在归类的时候会把 char 类型归结到整型家族里去。( ASCII码:美国信息交换标准代码 )


(有符号类型和无符号类型本文后续会详细讲解)


0x01 浮点型家族

896c42e6db0fbe77c1982a8929aa56f3_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png

0x02 构造类型

2fbf7fcec07eadf6ef01d08e911e0216_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png

📚 定义:构造类型又叫自定义类型,是我们自己创建的类型;


📌 注意事项:他们都是整型数组,但是他们的类型完全不一样


int arr[10]; 👉 类型为:int[10]
int arr2[5]; 👉 类型为:int[5]

0x03 指针类型

7281027b14821b2cc3242d1441811620_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png

0x04 空类型

004624fb376f86639bfcb187fe5a7815_20210610082454152.png

📚 void 表示空类型(无类型),通常应用于函数的返回类型、函数的参数、指针类型


💬 void 定义函数返回类型和函数参数:


void test(void) // 不需要返回值的函數
{
    printf("hehe\n");
}
int main(void)
{
    test(); // test(100) error 函数内声明的是无参
    return 0;
}

💬 void 定义空指针:


void* p

三、整型在内存中的存储


0x00 引入

266cc72d0d68f1ad8ceef1960aaaebf2_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png

📚 数据在内存中以2进制的形式存储:


     ① 对于整数来说,内存中存储的二进制有3种表示形式:原码、反码、补码


     ② 正整数:原码、反码、补码相同


     ③ 负整数:原码、反码、补码要进行计算


0x01 原码

📚 原码:按照数据的数值直接写出的二进制序列就是原码

767a25c17c09adf5605bead3999e8062_20210610092619788.png

❗   符号位:最高位1表示负数,最高位0表示正数


0x02 反码

📚 反码:原码的符号位不变,其他位按位取反,即为反码

96aa334ea10ccbaa2b3e3f844fb3f987_20210610093123153.png

0x03 补码

📚 补码:反码 +1,得到的就是补码

ae99bb308e8f03da43b190b7ad269f32_20210610093420145.png

0x04 内存中为何存放补码

此时我们再看前面引入里提到的:


📚 虽然整数的二进制表示形式有三种,但是内存中存储的是补码

1e2052ea73144090a0625fc9854da9b0_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png


🔺 结论:整数在内存中存储的是补码


❓  为什么在内存中存的是补码呢:


在计算机系统中,整数数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数字域统一处理;同时,加法和减法也可以统一处理( CPU只有加法器 )。此外,补码与补码相互转换,其运算过程是相同的,不需要额外的硬件电路。


相关文章
|
存储 程序员 编译器
C 语言中的数据类型转换:连接不同数据世界的桥梁
C语言中的数据类型转换是程序设计中不可或缺的一部分,它如同连接不同数据世界的桥梁,使得不同类型的变量之间能够互相传递和转换,确保了程序的灵活性与兼容性。通过强制类型转换或自动类型转换,C语言允许开发者在保证数据完整性的前提下,实现复杂的数据处理逻辑。
|
存储 编译器 C语言
C语言存储类详解
在 C 语言中,存储类定义了变量的生命周期、作用域和可见性。主要包括:`auto`(默认存储类,块级作用域),`register`(建议存储在寄存器中,作用域同 `auto`,不可取地址),`static`(生命周期贯穿整个程序,局部静态变量在函数间保持值,全局静态变量限于本文件),`extern`(声明变量在其他文件中定义,允许跨文件访问)。此外,`typedef` 用于定义新数据类型名称,提升代码可读性。 示例代码展示了不同存储类变量的使用方式,通过两次调用 `function()` 函数,观察静态变量 `b` 的变化。合理选择存储类可以优化程序性能和内存使用。
427 82
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
509 12
|
存储 数据管理 C语言
C 语言中的文件操作:数据持久化的关键桥梁
C语言中的文件操作是实现数据持久化的重要手段,通过 fopen、fclose、fread、fwrite 等函数,可以实现对文件的创建、读写和关闭,构建程序与外部数据存储之间的桥梁。
|
存储 数据建模 程序员
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
|
存储 C语言 C++
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
173 0
深入C语言,发现多样的数据之枚举和联合体
|
存储 C语言
C语言中的浮点数存储:深入探讨
C语言中的浮点数存储:深入探讨
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储
241 0
|
C语言
回溯入门题,数据所有排列方式(c语言)
回溯入门题,数据所有排列方式(c语言)
178 0
|
存储 程序员 C语言
程序员之路:C语言中存储类别
程序员之路:C语言中存储类别
197 0