zoukankan      html  css  js  c++  java
  • 类型的本质:对变量、类型、指针的理解

    核心观点:类型约定了对数据的解释方式

    信息和数据

    来自 wikipedia 的定义

    https://en.wikipedia.org/wiki/Information

    https://en.wikipedia.org/wiki/Data

    wikipedia 上的定义真的是太晦涩了

    在我的理解中,数据就是不带有任何属性的数字。例如一个数字1,就是一个单纯的数据。

    仅通过一个数字 1,你是无法得到任何信息的,因为你不知道这个1到底代表什么意思。只有结合具体的语境,你才能从中获得有用的信息。

    例如1本书、1个人、1头猪等等

    上面的书、人、猪实际上就是对数据的解释方式。他们分别将 1 解释为书的数量、人的数量、猪的数量。

    因此为了获取信息,除了知道数据本身外,你还得需要知道对数据的解释方式。

    所以,信息 = 数据 + 数据的解释方式

    想一想谍战片子里面的电报机,电报机所发送的实际上是一些长短不一的摩尔斯电码,这些摩尔斯电码就是数据,外部人员不知道这些电码代表的是啥,但是专业的谍报人员对其翻译后,就可以从其中获取到有用的信息。这里的翻译实际上就是在对数据进行解释。翻译工作可能是依靠一个密码本来进行的,密码本上约定了数据的解释方式。

    例子
    l i v e
    

    这四个字母,如果用从左至右的方式来解释,将是 live,如果用从右至左的方式来解释,将是 evil。

    1 0 1 1
    

    这四个数字,如果每两个一组进行解释,将会得到

    10 11
    

    如果每四个一组进行解释,将会得到

    1011
    

    同样的数据,使用不同的解释方式,就能得到不一样的信息。

    类型约定了对数据的解释方式

    c 语言中有如下一些基础数据类型,摘自https://www.runoob.com/cprogramming/c-data-types.html

    整数类型

    类型 存储大小 值范围
    char 1 字节 -128 到 127 或 0 到 255
    unsigned char 1 字节 0 到 255
    signed char 1 字节 -128 到 127
    int 2 或 4 字节 -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
    unsigned int 2 或 4 字节 0 到 65,535 或 0 到 4,294,967,295
    short 2 字节 -32,768 到 32,767
    unsigned short 2 字节 0 到 65,535
    long 4 字节 -2,147,483,648 到 2,147,483,647
    unsigned long 4 字节 0 到 4,294,967,295

    浮点类型

    类型 存储大小 值范围 精度
    float 4 字节 1.2E-38 到 3.4E+38 6 位小数
    double 8 字节 2.3E-308 到 1.7E+308 15 位小数
    long double 16 字节 3.4E-4932 到 1.1E+4932 19 位小数

    再回顾一下我的核心观点:类型约定了对数据的解释方式

    在这里我就取 char 类型和 short 类型来解释。char 类型的大小是 1 字节,short 类型的大小是 2 字节。一字节 byte 等于 8 bit,一个 bit 就是一个二进制位,值为 0 或 1。实际上 char 约定了以 8 个 bit 为一组来解释,而 short 则约束了以 16 个 bit 为一组来解释。

    现在有一个 16 个 bit 大小的空间,空间里的内容为:

    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
    

    如果用 char (每 8 个 bit 为一组)来解释,则可以解释为两个 char,char0 = 00000000 = 0,char1 = 00000001 = 1。

    如果用 short (每 16 个 bit 为一组)来解释,则可以解释为 1 个 short,short0 = 0000000000000001 = 1。

    变量(variable) = 地址(address) + 类型(type)

    一个变量由两个要素组成,分别是变量的地址,以及变量的类型。

    address 确定了存放变量的字面值的空间位置

    type 约定了如何解释这段空间

    在 c 语言中,初始化一个变量的方式是:

    char a = 1;
    

    例如在这里,

    • 变量 a 的 address 是 &a
    • 类型是 char,它决定了将会以 8 个 bit 为单位解释 address 中的内容
    • a 的字面值是 1,字面值是通过 address 和 char 通过得到的

    在 address 处存放了数据本体,利用 type 来解释数据,最终得到字面值这个信息。

    对变量的访问是通过访问该变量的地址来完成的

    在 c 语言中,对于变量的访问实际上都是通过访问该变量的地址来完成的。但是只有地址还不够,如何解释这篇地址的内容,是以 8 个 bit 为单位亦或者是以 16 个 bit 为单位,这就需要用到类型了。

    变量在初始化时,会被分配一个地址。这个地址就是变量的家,变量的地址是不会发生改变的,它一辈子只会有一个家,不会搬家。

    变量的初始化
    char c = 1;
    

    在这行代码里,实际上会有如下两步操作:

    1. 为变量 c 分配一个空间,这个空间就是 c 的家,假设 c 住在地球一号村,二号楼0号房间吧,就用 0x120 来表示 c 的地址吧。

    2. 将 0x120 ~ 0x128 这 8 个 bit 的空间里的内容初始化为 1(其实 c 里面地址的单位是 1 个 byte,而非 bit),变成下面这个样子:

      image

      为何是 8 个 bit 而不是其他数字的 bit?这是 c 的类型所决定的,因为类型是 char,所以是 8 个 bit。

    对 c 的修改
    c = 2
    

    实际上还是分为两步:

    1. 第一步还是先得到 c 的地址,之前说过变量的地址是不会发送改变的,因此这里变量 c 的地址也就是 0x120

    2. 将 0x120 ~ 0x128 这 8 个 bit 的空间里的内容初始化为 2,变成了下面这样:

      image

    对 c 的访问
    char i = c;
    
    1. 得到 c 的地址 0x120
    2. 对 0x120 ~ 0x128 这 8 个 bit 大小的空间进行解释。类型约定了对数据的解释方式,而这里的类型是 char,所以用 8 个 bit 的方式来解释。
    3. 对 i 的操作也是类似的...

    指针

    指针变量本质和普通的变量没有太大区别,依旧由值和类型组成,同样也会被分配一个地址。

    但是它相比普通变量多了一个 * (dereference) 操作。dereference 是指针变量所特有的操作,普通的变量是无法进行 dereference 操作的,否则会发生编译错误。

    定义一个指针变量
    char* p = 0x120;
    

    p 的值是 0x120 ,p 的类型是 char* (指向 char 类型的指针)。

    char* = char + *
    * 表明这个变量是一个指针,因此有 dereference 能力
    char 约定了在 dereference 时,它将会以 8 个 bit为 单位来解释
    
    deference

    通过 dereference ,可以对地址中的内容进行操作。

    *p = 1
    

    这句代码将会把 0x120 ~ 0x128 这 8 个 bit 的空间里的内容置为 1。

    image

    对指针变量的修改
    p = 2
    

    与上面所说的变量的修改过程是一样。

    一些具体的例子

    基本原则
    1. 变量 = address + type
    2. 变量会被分配一个地址,且这个地址是固定的
    3. 对变量的访问是通过访问变量的地址来完成的,变量的类型约定了对地址中内容的解释方式
    例子1:通过指针来修改变量的值
    char c = 1;			// 为 c 分配地址,假设 c 的地址是 0x120,c 的值是 1,0x120 ~ 0x128 这 8 个 bit 的内容是 1
    char* pc = &c;		// pc 是一个指针,它的值是 c 的地址,则 pc 的值是 0x120
    *pc = 2;			// dereference 操作,将 0x120 ~ 0x128 这 8 个 bit 的内容设置为 2
    printf("%d",c);		// 取 0x120 ~ 0x128 这 8 个 bit 的内容进行解释,得到 2,因此输出 2
    
    例子2:指向指针的指针
    char* pc = null;	// 为 pc 分配地址,假设 pc 的地址是 0x1200,pc 的值是 0,0x1200 ~ 0x1220 这 32 个 bit 的内容是 0(在 32 为环境下,指针的大小是 32 bit)
    char** ppc = &pc;  // ppc 的值为 0x1200
    char c = 1;		   // 为 c 分配地址,假设 c 的地址是 0x120,c 的值是 1,0x120 ~ 0x128 这 8 个 bit 的内容是 1
    *ppc = &c;		   // 将 0x1200 ~ 0x1220 这 32 个 bit(char*) 的内容设置为 0x120,此时 pc 的值为 0x120 了
    *pc = 2;		   // 取 0x120 ~ 0x128 这 8 个 bit(char) 的内容设置为 2, 此时 c 的值变成 2 了
    
  • 相关阅读:
    Arduino语法-变量和常量
    Arduino-函数库和程序架构介绍
    第十章浮力题汇总
    pyqt5-按钮基类-QAbstractButton
    在Windows上安装Arduino-IDE
    Arduino-接口图
    python-文件及文件夹操作
    Qt WebRTC demo
    多线程使用信号量sem_init,sem_wait,sem_post
    华为公司内部培训资料_介绍RTSP的消息、信令等
  • 原文地址:https://www.cnblogs.com/XiaoXiaoShuai-/p/14903578.html
Copyright © 2011-2022 走看看