程序 = 算法 + 數(shù)據(jù)結(jié)構(gòu)。對(duì)應(yīng)硬件器一,算法就是計(jì)算機(jī)指令课锌,數(shù)據(jù)結(jié)構(gòu)就對(duì)應(yīng)二進(jìn)制數(shù)據(jù)。
計(jì)算機(jī)都是用 0 和 1 組成的二進(jìn)制祈秕,表示所有信息渺贤。指令用到的機(jī)器碼也是二進(jìn)制表示;內(nèi)存里字符串请毛、整數(shù)志鞍、浮點(diǎn)數(shù)也是。
快速瀏覽一遍整數(shù)方仿、文本字符串的二進(jìn)制表示固棚。遇到亂碼是怎么回事兒、Unicode 和 UTF-8 之間有什么關(guān)系仙蚜。
一此洲、理解二進(jìn)制的“逢二進(jìn)一”
十進(jìn)制整數(shù),都能通過二進(jìn)制表示出來委粉。二進(jìn)制對(duì)應(yīng)到十進(jìn)制呜师,比如 0011?=3
把 13 這個(gè)十進(jìn)制數(shù),用短除法轉(zhuǎn)化成二進(jìn)制贾节,=?1101
負(fù)數(shù):最左側(cè)的一位汁汗,當(dāng)成是對(duì)應(yīng)的正負(fù)號(hào),比如 0 為正數(shù)栗涂,1 為負(fù)數(shù)
0011 = +3知牌。補(bǔ)碼1011 = -3。整數(shù)的原碼表示法戴差。缺點(diǎn)1000 代表 0送爸, 0000 也代表 0。
另一種表示法=-5:
最高位1必然是負(fù),最高位 0必然是正袭厂。 0000 表示 0墨吓,1000 表示 -8。4 位二進(jìn)制數(shù)纹磺,可從 -8 到 7 這 16 個(gè)整數(shù)帖烘,不會(huì)浪費(fèi)一位。
?-5 + 1 = -4橄杨,-5 + 6 = 1秘症。
字符串的表示,從編碼到數(shù)字式矫,都可用二進(jìn)制表示乡摹。
二、ASCII 碼
8 位二進(jìn)制,表示需要所有字符(American Standard Code for Information Interchange,美國信息交換標(biāo)準(zhǔn)代碼)饥悴。
ASCII 碼就好比字典, 128 個(gè)不同數(shù)(8 位二進(jìn)制)映射到 128 個(gè)不同字符里板熊。a 在 ASCII 里是第 97 個(gè),二進(jìn)制 0110 0001察绷,十六進(jìn)制 61干签。A第 65 個(gè),二進(jìn)制0100 0001拆撼,十六進(jìn)制41容劳。
ASCII ,9 不是 0000 1001情萤,而是 0011 1001鸭蛙。15 不是用 0000 1111,兩個(gè)字符 1 和 5 連續(xù)放在一起筋岛,就是 0011 0001 和 0011 0101娶视,用兩個(gè) 8 位表示。
最大的 32 位整數(shù)睁宰,2147483647肪获。用整數(shù)只需 32 位。用字符串(多占空間)有 10 個(gè)字符柒傻,每個(gè)字符用 8 位的話孝赫,需要整整 80 位。
存儲(chǔ)數(shù)據(jù)用二進(jìn)制序列化红符,不是簡單地把數(shù)據(jù)通過 CSV 或者 JSON進(jìn)行序列化青柄。不管是整數(shù)也好伐债,浮點(diǎn)數(shù)也好,采用二進(jìn)制序列化會(huì)比存儲(chǔ)文本省下不少空間致开。
ASCII 碼只表示了 128 個(gè)字符不太夠用峰锁。于是創(chuàng)建了對(duì)應(yīng)的字符集(Charset)和字符編碼(Character Encoding)。
字符集双戳,字符的集合虹蒋。比如“中文(《新華字典》里面出現(xiàn)的所有漢字)”就是一個(gè)字符集,“”飒货, Unicode是字符集魄衅,150 種語言14 萬個(gè)不同的字符。
字符編碼:字符(字符集里)用二進(jìn)制表示的字典塘辅。 Unicode可用 UTF-8晃虫、UTF-16編碼存儲(chǔ)成二進(jìn)制。有了 Unicode可用不止 UTF-8 一種編碼形式扣墩,知道編碼規(guī)則傲茄,可以正常傳輸、顯示代碼沮榜。
同樣文本不同編碼存儲(chǔ)。另一個(gè)程序喻粹,不同的編碼方式來進(jìn)行解碼和展示蟆融,就會(huì)亂碼。就像密語通信守呜,用錯(cuò)密碼本不知所云型酥。
搜索郵件歷史出現(xiàn)了“錕斤拷”
想要 Unicode 編碼記錄文本,但這些字符在 Unicode 中并不存在查乒。Unicode 統(tǒng)一記錄為 U+FFFD 編碼弥喉。如果用 UTF-8 的格式存儲(chǔ)下來,就是\xef\xbf\xbd玛迄。如果連續(xù)兩個(gè)這樣的字符放在一起由境,\xef\xbf\xbd\xef\xbf\xbd,這個(gè)時(shí)候蓖议,如果程序把這個(gè)字符虏杰,用 GB2312 的方式進(jìn)行 decode,就會(huì)變成“錕斤拷”勒虾。這就好比我們用 GB2312 這本密碼本纺阔,去解密別人用 UTF-8 加密的信息,自然沒辦法讀出有用的信息修然。
而“燙燙燙”笛钝,則是因?yàn)槿绻阌昧?Visual Studio 的調(diào)試器质况,默認(rèn)使用 MBCS 字符集〔C遥“燙”在里面是由 0xCCCC 來表示的结榄,而 0xCC 又恰好是未初始化的內(nèi)存的賦值。于是啃奴,在讀到沒有賦值的內(nèi)存地址或者變量時(shí)潭陪,電腦就開始大叫“燙燙燙”了。
課后思考
負(fù)數(shù)是原碼表示最蕾,應(yīng)該如何處理依溯?如果是補(bǔ)碼表示的呢?請你用二進(jìn)制加法試著算一算瘟则,-5+4=-1黎炉,通過原碼和補(bǔ)碼是如何進(jìn)行的?
[-5+4]補(bǔ)=[-5]補(bǔ)+[4]補(bǔ)=[1011+0100]補(bǔ)=[1111]補(bǔ)? 原碼1001