字元相關知識 轉

2022-08-11 01:51:11 字數 3796 閱讀 8744

字元是書寫的最基本構建單元。字元可以表示字母、數字、標點、表意符號(比如漢字)、數學符號,或者其他的書寫基本單元。

不能把字元和字形相混淆。字元是唯一的,抽象的語言「原子」。字形是畫出每個符號時使用的特定方式。只有當用一種字形替代另一種字形,文字的意思發生了改變,才把這些字形看成是不同的字元。否則,這些字形就是同乙個字元的不同風格的表示形式。

比如上圖中的九個字形,雖然形狀各異,但一看就知道是小寫字母a,所以這九個字形代表的是小寫字母a這同乙個字元。

2.編碼後的字符集(coded character set

編碼後的字符集將整數對映到字元。編碼後的字符集經常用陣列來實現,通過**數值來進行索引。陣列的元素就是字元。下面舉例說明一些常見的編碼後字符集。

1)us-ascii

ascii表示「美國標準資訊交換**」(american standard code for information interchange)。ascii是最著名的編碼後字符集,早在2023年就由ansi進行了標準化。ascii的**值範圍是0到127(用十六進製制表示是0x00到0x7f),因此只需7個二進位製碼就可以覆蓋整個**空間。ascii的推薦名稱是us-ascii,這樣可以和那些7位字符集的一些國際化變體進行區分。http報文(首部、uri等)使用的字符集是us-ascii。

iso-8859字符集標準是us-ascii的8位超集,使用二進位製碼的高位增加了一些國際化書面字元。有額外的二進位製碼增加的空間(多了128個**,從0x80到0xff)還不夠大,甚至還不夠所有的歐洲字元使用,更不用說亞洲字元了。因此iso-8859為不同地區定製了不同的字符集。其中最著名的就是iso-8859-1,用於表示西歐語言(英語、法語等)。iso-8859-1的別名是latin1,是html的預設字符集。

3)ucs

ucs(universal character set)把全世界的所有字元都整合到了單一的編碼後字符集中。ucs由iso 10646定義。unicode是遵循ucs標準的商業化聯合組織。

在ucs標準中,**空間被分成了17個平面(planes),每個平面有65536(2的16次方)個**點(code points),所以總共有1,114,112個**點。這個數字很奇怪,因為它不是2的冪。這其實是utf-16編碼方案的設計所造成的結果。

在utf-16中,用兩個**單元(共四個位元組)組成的「**對」(surrogate pair)來編碼1到16平面中的2^20個**點(2^4個平面乘以每個平面2^16個**點),而對0平面進行編碼只需要乙個**單元(兩個位元組)。2^20 + 2^16 = 1024^2 + 65536 = 1114112。

ucs中的第乙個平面,0平面,也叫「基本多語種平面」(basic multilingual plane,bmp)。這個平面是到目前為止大部分字元所在的地方。而bmp中的大部分**點都被用於對中日韓的字元進行編碼。上圖中淺灰色區域中,0xd800到0xdfff(8 * 2^8 = 2^11 = 2048)這個區域(倒數第三行後半部分)不對應任何字元,而是被保留用於在utf-16編碼方案中對**對進行編碼。

3.字元編碼方案(character encoding scheme

字元編碼方案(character encoding scheme)和編碼後的字符集(coded character set)不是乙個概念。字符集給所包含的每個字元分配乙個整數編號,而編碼方案規定如何把字元的**數字打包裝入二進位制的位元資料中,以及如何在另一端將其解包回字元**。

字元編碼方案主要有以下3種型別。

ÿ固定寬度

固定寬度方式的編碼用固定數量的位元表示每個編碼後的字元。它們能被快速處理,但可能會浪費空間。

ÿ可變寬度

可變寬度方式的編碼對不同的字元**數字採用不同數量的位元。對於常用字元,這樣可以減少所需的位數,而且還能在允許使用多位元組來表示國際性字元的同時,保持對傳統8位字符集的相容性。

可變寬度(有模態)

有模態的編碼使用特殊的「轉義」模式在不同的模態之間進行切換。例如,可以用有模態的編碼在文字中使用多個互相重疊的字符集。有模態的編碼處理起來比較複雜,但可以有效地支援複雜的書寫系統。

1)8位編碼

iso-8859字符集家族系列使用的是8位的恒等編碼。這種編碼把每個字元**直接編碼為相應的8位二進位制數值。這種編碼方式只支援**範圍包含256個字元的字符集。

2)utf-8

utf-8是一種流行的為ucs設計的字元編碼方案,utf表示ucs變換格式(ucs transformation format)。utf-8為字元**值使用的是無模態的變寬編碼。第乙個位元組的高位表示編碼後字元所用的位元組數,後續每個位元組都固定包含6位的**值。

如果編碼後的第乙個位元組的最高位是0,則編碼長度就是乙個位元組,剩餘的7位就包含字元的**。這樣一來就美妙地達到了與ascii的相容(但和iso-8856系列不相容)。

例如字元**90(ascii的「z」)在0到127的範圍內,故只需乙個位元組進行編碼(90 = 64 + 16 + 8 + 2 = 2^6 + 2^4 + 2^3 + 2,編碼為0,101,1010)。而**5073需要13位二進位制數(1,001111,010001),會被編碼為3個位元組(見上圖第三行):

11100001100011111001001

注意utf-8的最大編碼值是31位,能編碼2^31個**值,這遠遠大於ucs的**範圍(相當於2^15,即32768個平面)。

3)utf-16

utf-16編碼方案能夠對ucs中的1,112,064個**點進行編碼(1,114,112減去從u+d800到u+dfff這2048個用於**對的**點)。utf-16編碼長度要麼是兩個位元組(對於從u+0000到u+d7ff,以及從u+e000到u+ffff的基本平面**點),要麼是4個位元組(對於從u+1,0000到u+10,ffff的16個輔助平面中的**點)。

輔助平面中的**點長度超過兩個位元組,用兩個16位的**單元(稱為乙個**對)來進行編碼,具體編碼方式如下:

從這裡就能看出為什麼要保留0xd800到0xdfff這個範圍了,因為0xdfff – 0xd800 + 1等於0x800,等於2 * 2^10,即切成兩半,每一半可以**表示2^10個數,組合起來正好可以**表示2^20個輔助平面中的**點(2^10 * 2^10 = 2^20)。

思考一下為什麼要用**對來進行編碼,而不是用4個位元組直接表示輔助平面中**點的值?

字串相關知識

1.字串長度 strlen 求字串長度時,遇到 0 就停下,前面所經過的字元數,就是字串的長度,不包括 0 注意 該函式的返回值為無符號整數。例子 int main else return 0 上述 輸出為什麼呢?因為返回值無符號數,無符號數 無符號數永遠是大於等於0的,所以輸出了if分支的語句。2...

字串相關知識

可不使用new方式 當從字串池中查詢,沒有時,則需要字串建立 例子 string prompt hello,world 使用後new建立方式 每次建立乙個新物件 例子 string prompt new string hello,world 字串相等比較 equals 字元名稱.equalsigno...

字元陣列的相關知識

關於gets函式的用法 函式原型 函式只有乙個引數,引數型別為char 型別,str可以是指標型別變數名,也可以是字元陣列的名字 include char gets char str gets 函式的功能是從輸入緩衝區中讀取乙個字串儲存到字元指標變數 str 所指向的記憶體空間。gets函式與sca...