首页 > 科普 > > 详情

非常规入门C语言:2、初始数据类型|世界最新

来源:哔哩哔哩 2023-06-13 23:10:18

日常生活中,在我们周围充斥着各种各样的数据。这些数据有着不同的形式,且分布在不同的载体上。

但有些数据是有意义的,如费用余额、学号、身份证号、姓名、年龄等;而有些数据是无意义的,如......

而计算机被发明以来,天生就是服务于科学计算的,即:一切计算机问题都是数学问题


(资料图)

上一章中,计算机底层的计算方式是通过二进制来确定的。同时为了能够方便地使数据参与运算,还引出最小处理宽度(宽度就二进制位数)和控制指令。

那我们可以把哪些数据放在计算机“里面”呢?

理论上,所有数据都可以。但首先我们解决数据从哪里来的问题,即信息的数字化。

首先,和数值相关的东西,我们可以很方便存储在计算机中,剩下的问题就是精度和宽度的问题。

其次,我们还需要解决非数值信息的数字化问题。

那么我们先解决哪个问题呢?

为了避免问题的延伸,我们先解决宽度的问题,即给不同的数据分配一个确定的类型,即数据类型。

首先,我们能确定的第一个数据类型就是计算机的最小处理宽度,无论是哪种机器,无论它的最小处理宽度是多大,我们都称之为“字”,字的宽度称之为“字宽”。那么为了和二进制搭上关系,我们采用倍数增长的方式,扩大数据类型的表示范围。

字->双字->四字->八字->16字->32字->64字......

你想扩大多少倍都可以,但必须是前一个数值的2倍。因为这样的处理方式的难度是最低的。

于是,基于“字”概念的数据类型就出现了。但是它本身并不具有通用性和实际意义,因为“无论它的最小处理宽度是多大,我们都称之为‘字’”。

这时,我们应该想到貌似有一个8位的数据。没错,在上一章中,我们使用8位二进制的数据完整表示了控制字符(如换行等)、大小写字母数字常用标点符号。那么,干脆就用8位作为最小处理宽度。

那么,给个名字,把8位宽度的称为“字节”,同时将“字节”确定为通用的基本字宽。

这时,我们得到了一些较为原始的数据类型:字节、双字节、四字节......

我们能有多大的数呢。。。这是一个问题。因为需要看CPU能处理多大的数。32位的CPU最大一次性处理32位,64位CPU最大一次性处理64位。为啥是一次性呢?理论上来说,只要你能提供足够的存储空间,数字多大都没问题,但是运算是一部分一部分来的,极端情况也有可能是一位一位来计算的。这种由CPU确定的最大一次性处理宽度,称之为“数据宽度”。

早期计算机的数据类型就是这样。。。很枯燥,很直白,但也很简约。

但这不是我们的目标,我们的目标是“星辰大海”。

1 + 1 = 2

1 - 2 = ?

当你在计算时有没有想到这样一个问题:正整数可以直接表示,但负整数和小数没办法直接在计算机中表示。

因为计算机中没有负号和小数点的概念。解决办法也是相当简单粗暴:用正整数来表示不就好了?

举个例子

使用字节来控制字宽。那最长就是8位,表示的范围就是0到255(即0000 0000 ~ 1111 1111)。

首先我们先确定一下正数与负数的交界点,那就是0。那我们就可以确定,0加上1就是正数,0减掉1就是负数。

如果我们需要表达-2,那就是0000 0000 - 0000 0010就等于1111 1110,因为0减1不足,向前借2。

那么,教科书里是怎样教的呢?

嬴寒隐约记得,取反码再加1。。其实很简单,根本用不着反码。所谓反码,只是计算机的一种取反运算而已,因为相比加减运算,取反的操作,那简直是太快了,瞬时就可以完成。

为什么是瞬时呢?因为只需要对前面的位进行取反,最低位根本不用管就可以完成一个负数的完整表达。根本不可能使用加减运算。但作为人类,我们有时有必要理解计算机的运算方式,但有时又没有必要。而像这种特别基础,基础到对后面的知识没有什么太大影响的东西,我们只需要理解最人性化的思路就可以了。

但是教科书却用计算机运算的方式来介绍负数的表示原理,无疑是给刚接触的小伙伴带来了沉痛的负担。

各位小伙伴可能已经发现,在计算机中,处于最高位的0是一个非常神奇的存在。我们通过它能够辨别是正数还是负数,也能够通过它,来判断一个数据是不是正确的(就是低位数据的每一位运算的结果,称为校验)。其实我们还可以利用0来确定真假值,比如0为真,非0为假,我们称之为“布尔值”。

刚刚我们找到了负数的表示方案,此时,我们就需要找到非整数的表示方法了。那么如何利用整数来表示非整数呢?

一种方式是直接规定第多少位开始是小数部分,当然这种方式没人会喜欢,而且灵活性也很差。

其实这里我们就考虑到了小数点的变动问题:小数点是不动(小数位数固定)还是变化的(小数位数不定)。显然,两种形式各有优劣。

既然整数的表达最方便,那能否让小数和整数直接挂钩呢?可以。

我们以科学计数法再举个例子

使用二进制表示259.56,如果将其转换为科学计数法就是2.5956*10^2。

但很显然我们还是没办法直接表示,既然缩小不行,那就尝试放大。于是我们可到等价的值25956*10^-2。这时其中所有相关的数值我们都是在计算机方便的表示:25956、10和-2。

但是不要忘了,计算机是基于二进制的,并非十进制,那就意味着,必须将这仨兄弟都转换成二进制就可以了。

可是,好像不太容易啊。因为我们一直是按照十进制来处理,但换成二进制中,小数点的变动就不一样了。

所以我们将259.56拆成两部分,使用常规方案表示整数部分259,使用小数表示法表示小数部分0.56。

在十进制的世界中,1是1*10^0,10是1*10^1,0.1是1*10^-1。

在二进制中也是基本一致的,1是1*2^0,2是1*2^1。

也就是说,我们需要表达某个大数,就是让这个数除以基数,十进制的基数就是10,那么二进制的基数就是2;反之,如果我们需要表达一个凑不整基数的小数,就需要让这个数乘以基数。

例如:256就是200+50+6=2*100 +5*10+6*1,表达逻辑是让原来的数缩小,让基数增大。

再如:0.25就是0.2+0.05=2*10^-1+5*10^-2,表达逻辑是原来的数变大,让基数减小。(说法不是很严谨,因为不是让基数本身发生变化,而是权值,或者说是指数部分)

那么,0.56表示成二进制就是让这个数一直乘以2,直到小数部分没有值为止。

0.56 * 2 = 1.12 -> 取 1

0.12 * 2 = 0.24 -> 取 0

0.24 * 2 = 0.48 -> 取 0

0.48 * 2 = 0.96 -> 取 0

0.96 * 2 = 1.92 -> 取 1

……

很长很长:.100 0111 1010 1110 0001 0100 0111 1010 1110 0001 0100 0111 1011

所以就涉及到精度问题。。。因为我们不可能把所有精力和空间全浪费在小数的处理上。除非。。。有东西能够帮我们自动完成这件事。

那么,上面的259.56就可以分成三部分了,整数部分、小数部分、小数点位数。

当然,这只是一个示例。并不一定是现代计算机中用到的表达方式。

至此,我们已经利用计算机中原有的东西实现了一些类型,如:数值、字符、布尔值,暂且称他们为“初始数据类型”吧。

分享至:

上一篇:世界微资讯!微信上怎样群发_在微信里怎么群发 下一篇 :最后一页
x

推荐阅读

更多推荐