一、前言
在编程语言中,一个非常重要的概念是变量,变量又会分为很多类型,比如C/C++中有非常多的类型:int
、double
、char
等等,其它语言也是一样,比如rust中的i8
、i32
、i64
。
从本质上来说,这些所谓的数据类型并没有任何区别,在计算机眼中都是一堆二进制数据而已。
非要说区别的话,那就是占用内存大小、和对其的解释方式不同而已。
解释方式很简单,比如数字:65
,如果你将其赋值为int
变量,那就会输出65
这个数字,可如果你复制给char
变量,那输出的就是65
这个数字在ASCII码表中所对应的字母,也就是字母A
。
同样一个数字,在不同情况下就被解释成了不同的形式,其它类型也均是如此。
本文主要探讨的是数据大小这个问题,这个我认为才是不同数据类型间最根本的区别。
二、位(bit)
首先是位这个概念,英文用bit
表示,一个基本事实是,计算机是以二进制的形式储存数据的,进制这个概念属于数学上的概念了,初中应该就已经学过了,这里不过多介绍。
二进制的精髓在于:逢2进1、只能存在数字0、1。
比如一个下面是1-5的二进制表示方法:
1 //1
10 //本应为1+1=2,但逢2进1,所以就是10
11 //10+1
100 //本应为11+1=12,逢2进一为20,再逢二进一为100
101 //100+1=101
这就是二进制中的1-5这五个数字表示方法,看起来可能你会觉得有点奇怪,因为如果直接这样写的话,别人其实是很难将其与十进制数字区分开的。
所以一般我在程序中会给它添加一个前缀:0b
0b1 //1
0b10 //本应为1+1=2,但逢2进1,所以就是10
0b11 //10+1
0b100 //本应为11+1=12,逢2进一为20,再逢二进一为100
0b101 //100+1=101
这样就能识别出这是一个二进制数据了,而我们所探讨的位,就是数据所占用二进制的位。
比如上面的数字5
,二进制为0b101
,也就是占3位,那么我们就可以说它占了3
位大小的内存。
位是计算机中最小的内存表示单位。
三、字节(byte)
虽然位是最小的内存表示单位,但也正因为它太小了,用起来非常的不方便,所以就有了更大一点的单位:字节,英文中用byte
表示。
1
字节等于8
位,也就是C/C++
中char
类型的大小。
这个8位并不是空穴来风,它是一个很有意义的数字,比如英文常用字符有100多个,也就是ASCII码表上面的字符,127个,它等于27-1,也就是至少需要7位二进制才能存下。
比如1位二进制可以表示0、1,也就是21=2个数字,7位可以表示27=128位数字。
但同时要考虑到以后可能会添加新的字符,同时也是为了效率考虑,便使用了8位大小作为一个字节。
通常来说,大多数时候字节才是我们编程中用到的最小单位。
四、字(WORD)、双字(DWORD)、四字(qword)
这里的字不是我们平常说的汉字,它代表着两个字节的大小,也就是16
位二进制。
比如C/C++中的short
类型就是一个字的大小,英文中用WORD
表示,现在用的比较少了。
而双字也就是两个字(double word
缩写为DWORD
),4个字节大小,也就是32位二进制,这就用的比较多了。
比如C/C++中的int
数据类型就是一个双字大小的数据类型。
我们常常能听到的32
位平台、x86
架构,指的其实就是计算机CPU支持处理的位数为32位。
更深入的来说,指的是最大支持寻址位数,也就是指针的大小为32位,或者说CPU最大同时处理的位数。
在进一步,那就是四字了,也就是64位,同时也是目前大部分电脑的配置。
qword
是quad word
的缩写,在C/C++中有数据类型:long long
、double
与之对应。
五、简单总结
上面所有的数据类型大部分时候你可能都是看不到的,因为它们都被语言自己所定义的数据类型给封装了。
可如果你研究windows逆向的话,就会发现在逆向工具中,这些常常出现:word
、dword
、qword
。
有兴趣的可以看看本站逆向相关的文章:逆向入门
了解这个的目的也是为了让你能够更加清晰的明白,数据类型之间只有两个区别:告诉计算机这个变量占用多少位的内存、以及程序如何解释执行这个变量。
所以相对来说我就很喜欢rust中的数据类型表达方式,它直接用数字表示数据类型占用多少位。
比如i32
、i64
就分别等价于C/C++中的int
、long long
,也就是占用32位、占用64位大小内存。
这么一看,是不是就觉得rust中的数据类型表达方式要直观的多?