- 2.1.2.1.1. 什麼是Function Code功能碼或 Function Character功能字符
- 2.1.2.1.2. ASCII中的Function/Control Code功能字符的詳細含義
- 2.1.2.1.2.1. 0 – NUL – NULl 字符/空字符
- 2.1.2.1.2.2. 1 – SOH – Start Of Heading 標題開始
- 2.1.2.1.2.3. 2 – STX,3 – ETX
- 2.1.2.1.2.4. 4 – EOT – End Of Transmission 傳輸結束
- 2.1.2.1.2.5. 5 – ENQ – ENQuiry 請求
- 2.1.2.1.2.6. 6 – ACK – ACKnowledgment 迴應/響應
- 2.1.2.1.2.7. 7 – BEL – [audible] BELl
- 2.1.2.1.2.8. 8 – BS – BackSpace 退格鍵
- 2.1.2.1.2.9. 9 – HT – Horizontal Tab 水平製表符
- 2.1.2.1.2.10. 10 – LF – Line Feed 換行
- 2.1.2.1.2.11. 11 – VT – Vertical Tab 垂直製表符
- 2.1.2.1.2.12. 12 – FF – Form Feed 換頁
- 2.1.2.1.2.13. 13 – CR – Carriage return 機器的滑動部分/底座 返回 -> 回車
- 2.1.2.1.2.14. 14 – SO,15 – SI
- 2.1.2.1.2.15. 16 – DLE – Data Link Escape 數據鏈路轉義
- 2.1.2.1.2.16. 17 – DC1 – Device Control 1 / XON – Transmission on
- 2.1.2.1.2.17. 18 – DC2 – Device Control 2
- 2.1.2.1.2.18. 19 – DC3 – Device Control 3 / XOFF – Transmission off 傳輸中斷
- 2.1.2.1.2.19. 20 – DC4 – Device Control 4
- 2.1.2.1.2.20. 21 – NAK – Negative AcKnowledgment 負面響應-> 無響應, 非正常響應
- 2.1.2.1.2.21. 22 – SYN – SYNchronous idle
- 2.1.2.1.2.22. 23 – ETB – End of Transmission Block 塊傳輸中止
- 2.1.2.1.2.23. 24 – CAN – CANcel 取消
- 2.1.2.1.2.24. 25 – EM – End of Medium 已到介質末端,介質存儲已滿
- 2.1.2.1.2.25. 26 – SUB – SUBstitute character替補/替換
- 2.1.2.1.2.26. 27 – ESC – ESCape 逃離/取消
- 2.1.2.1.2.27. 28 – FS – File Separator 文件分隔符
- 2.1.2.1.2.28. 29 – GS – Group Separator分組符
- 2.1.2.1.2.29. 30 – RS – Record Separator記錄分隔符
- 2.1.2.1.2.30. 31 – US – Unit Separator 單元分隔符
- 2.1.2.1.2.31. 32 – SP – White SPace 空格鍵
- 2.1.2.1.2.32. 127 – DEL – DELete 刪除
- 2.1.2.1.3. 各種字符的標準的讀法/叫法
ASCII字符集,大家都知道吧,最基本的包含了128個字符。其中前32個,0-31,即0x00-0x1F,都是不可見字符。這些字符,就叫做控制字符。
這些字符沒法打印出來,但是每個字符,都對應着一個特殊的控制功能的字符,簡稱功能字符或功能碼Function Code。
簡言之:ASCII中前32個字符,統稱爲Function Code功能字符。
此外,由於ASCII中的127對應的是Delete,也是不可見的,所以,此處根據筆者的理解,也可以歸爲Function Code。
此類字符,對應不同的“功能”,起到一定的“控制作用”,所以,稱爲控制字符。
關於每個控制字符的控制功能縮寫,參見Table 2.1, “ASCII中的控制字符”
Table 2.1. ASCII中的控制字符
即在C語言中或其他地方如何表示。 |
|
可以通過 “Ctrl+對應字母/按鍵”實現上述控制字符的輸入 下面列舉一些你可能遇到的情況:
|
|
注意此處想要在鍵盤上輸入這三個字符的話,是需要通過Shift加上對應字符才能輸入的:
|
|
32=0x20,對應的是空格(Blank Space)鍵。不需要加Ctrl鍵,即可直接通過鍵盤上的空格鍵輸入。 |
|
127=0x7F=刪除(Delete)鍵;,除了可以用鍵盤上的刪除鍵輸入,也可以用'Ctrl+?'輸入。 |
- 2.1.2.1.2.1. 0 – NUL – NULl 字符/空字符
- 2.1.2.1.2.2. 1 – SOH – Start Of Heading 標題開始
- 2.1.2.1.2.3. 2 – STX,3 – ETX
- 2.1.2.1.2.4. 4 – EOT – End Of Transmission 傳輸結束
- 2.1.2.1.2.5. 5 – ENQ – ENQuiry 請求
- 2.1.2.1.2.6. 6 – ACK – ACKnowledgment 迴應/響應
- 2.1.2.1.2.7. 7 – BEL – [audible] BELl
- 2.1.2.1.2.8. 8 – BS – BackSpace 退格鍵
- 2.1.2.1.2.9. 9 – HT – Horizontal Tab 水平製表符
- 2.1.2.1.2.10. 10 – LF – Line Feed 換行
- 2.1.2.1.2.11. 11 – VT – Vertical Tab 垂直製表符
- 2.1.2.1.2.12. 12 – FF – Form Feed 換頁
- 2.1.2.1.2.13. 13 – CR – Carriage return 機器的滑動部分/底座 返回 -> 回車
- 2.1.2.1.2.14. 14 – SO,15 – SI
- 2.1.2.1.2.15. 16 – DLE – Data Link Escape 數據鏈路轉義
- 2.1.2.1.2.16. 17 – DC1 – Device Control 1 / XON – Transmission on
- 2.1.2.1.2.17. 18 – DC2 – Device Control 2
- 2.1.2.1.2.18. 19 – DC3 – Device Control 3 / XOFF – Transmission off 傳輸中斷
- 2.1.2.1.2.19. 20 – DC4 – Device Control 4
- 2.1.2.1.2.20. 21 – NAK – Negative AcKnowledgment 負面響應-> 無響應, 非正常響應
- 2.1.2.1.2.21. 22 – SYN – SYNchronous idle
- 2.1.2.1.2.22. 23 – ETB – End of Transmission Block 塊傳輸中止
- 2.1.2.1.2.23. 24 – CAN – CANcel 取消
- 2.1.2.1.2.24. 25 – EM – End of Medium 已到介質末端,介質存儲已滿
- 2.1.2.1.2.25. 26 – SUB – SUBstitute character替補/替換
- 2.1.2.1.2.26. 27 – ESC – ESCape 逃離/取消
- 2.1.2.1.2.27. 28 – FS – File Separator 文件分隔符
- 2.1.2.1.2.28. 29 – GS – Group Separator分組符
- 2.1.2.1.2.29. 30 – RS – Record Separator記錄分隔符
- 2.1.2.1.2.30. 31 – US – Unit Separator 單元分隔符
- 2.1.2.1.2.31. 32 – SP – White SPace 空格鍵
- 2.1.2.1.2.32. 127 – DEL – DELete 刪除
ASCII字符集中的空字符,NULL,起初本意可以看作爲NOP(中文意爲空操作,就是啥都不做的意思),此位置可以忽略一個字符。
之所以有這個空字符,主要是用於計算機早期的記錄信息的紙帶,此處留個NUL字符,意思是先佔這個位置,以待後用,比如你哪天想起來了,在這個位置在放一個別的啥字符之類的。
後來呢,NUL字符被用於C語言中,字符串的終結符,當一個字符串中間出現NUL / NULL,代碼裏面表現爲\0,的時候,就意味着這個是一個字符串的結尾了。這樣就方便按照自己需求去定義字符串,多長都行,當然只要你內存放得下,然後最後加一個\0, 即空字符,意思是當前字符串到此結束。
如果信息溝通交流主要以命令和消息的形式的話,SOH就可以用於標記每個消息的開始。
1963年,最開始ASCII標準中,把此字符定義爲Start of Message,後來又改爲現在的Start Of Heading。
現在,這個SOH常見於主從(master-slave)模式的RS232的通信中,一個主設備,以SOH開頭,和從設備進行通信。這樣方便從設備在數據傳輸出現錯誤的時候,在下一次通信之前,去實現重新同步(resynchronize)。如果沒有一個清晰的類似於SOH這樣的標記,去標記每個命令的起始或開頭的話,那麼重新同步,就很難實現了。
2 – STX – Start Of Text 文本開始
3 – ETX – End Of Text 文本結束
通過某種通訊協議去傳輸的一個數據(包),稱爲一幀的話,常會包含一個幀頭,包含了尋址信息,即你是要發給誰,要發送到目的地是哪裏,其後跟着真正要發送的數據內容。
而STX,就用於標記這個數據內容的開始。接下來是要傳輸的數據,最後是ETX,表明數據的結束。
其中,中間具體傳輸的數據內容,ASCII規範並沒有去定義,其和你所用的傳輸協議,具體自己要傳什麼數據有關。
幀頭 | 數據或文本內容 | |||
SOH(表明幀頭開始) | ......(幀頭信息,比如包含了目的地址,表明你發送給誰等等) | STX(表明數據開始) | ......(真正要傳輸的數據) | ETX(表明數據結束 |
不過其中有趣的是,1963年,ASCII標準最初版本的時候,把現在的STX叫做EOA(End Of Address),ETX叫做(End Of Message)。
這是因爲,最早的時候,一個消息中,總是包含一個開始符和一個終止符。現在的新的定義,使得可以去發送一個固定長度的命令,而只用一個SOH表明幀頭開始即可,而不需要再加上一個命令終止符或幀頭結束符。
總結一下:
一般發送一個消息,包含了一個幀頭和後面真正要傳的數據。
而對於幀頭,屬於控制類的信息,這部分之前屬於命令,後面的真實要傳的數據屬於數據。即消息=幀頭+數據。
而之前的命令都要有個開始符和結束符,這樣就是:
消息
= 幀頭 + 要傳的數據
= 幀頭開始+幀頭信息+幀頭結束 + 要傳的數據
而現在新的定義,使得只需要:
消息
= 幀頭 +要傳的數據
= SOH(表明幀頭開始)+幀頭信息+ 要傳的數據
= SOH(表明幀頭開始)+幀頭信息 + STX + 數據內容+ETX
就可以少用一個幀頭結束符。
而如今,在很多協議中,也常見到,一個固定長度的幀頭,後面緊接着就是數據了,而沒有所謂的幀頭結束符之類的東西去區分幀頭和數據。
在ASCII字符集中,BEL,是個比較有意思的東東。
因爲其原先本意不是用來數據編碼的,於此相反,ASCII中的其他字符,都是用於字符編碼(即用什麼字符,代表什麼含義)或者起到控制設備的作用。
BEL用一個可以聽得見的聲音,來吸引人們的注意,其原打算即用於計算機也用於一些設備,比如打印機等。
C語言裏面也支持此BEL,用a來實現這個響鈴。
退格鍵的功能,隨着時間變化,意義也變得不同了。
起初,意思是,在打印機和電傳打字機上,往回移動一格光標,以起到強調該字符的作用。
比如你想要打印一個a,然後加上退格鍵後,就成了aBS^。在機械類打字機上,此方法能夠起到實際的強調字符的作用,但是對於後來的CTR下時期來說,就無法起到對應效果了。
而現代所用的退格鍵,不僅僅表示光標往回移動了一格,同時也刪除了移動後該位置的字符。在C語言中,退格鍵可以用b表示。
ASCII中的HT控制符的作用是用於佈局的。
其控制輸出設備前進到下一個表格去處理。
而製表符Table/Tab的寬度也是靈活不固定的,只不過,多數設備上,製表符Tab的寬度都預定義爲8。
水平製表符HT不僅能減少數據輸入者的工作量,對於格式化好的文字來說,還能夠減少存儲空間,因爲一個Tab鍵,就代替了8個空格,所以說省空間。
對於省空間的優點,我們現在來看,可能會覺得可笑,因爲現在存儲空間已足夠大,一般來說根本不會需要去省那麼點可憐的存儲空間。
但是,實際上在計算機剛發明的時候,存儲空間(主要指的是內存)極其有限也極其昂貴,而且像ZIP等壓縮方法也還沒發明呢,所以對於當時來說,對於存儲空間,那是能夠省一點是一點,省任何一點,都是好的,也都是不容易的,省空間就是省錢啊。
C語言中,用t表示製表符。
LF,直譯爲(給打印機等)喂一行,意思就是所說的,換行。
換行字符,是ASCII字符集中,被誤用的字符中的其中一個。
LF的最原始的含義是,移動打印機的頭到下一行。而另外一個ASCII字符,CR(Carriage Return)纔是將打印機的頭,移到最左邊即一行的開始,行首。很多串口協議和MS-DOS及Windows操作系統,也都是這麼實現的。
而於此不同,對於C語言和Unix操作系統,其重新定義了LF字符的含義爲新行,即LF和CR的組合才能表達出的,回車且換行的意思。
雖然你可以爭論哪種用法是錯的,但是,不可否認,是從程序的角度出發,C語言和Unix對此LF的含義實現顯得就很自然,而MS-DOS的實現更接近於LF的本意。
如果最開始ASCII標準中,及定義 CF也定義newline,那樣意思會清楚,會更好理理解:
LF表示物理上的,設備控制方面的移動到下一行(並沒有移動到行首);
新行(newline)表示邏輯上文本分隔符,即回車換行。
不過呢,現在人們常將LF用做newline新行的功能,而大多數文本編輯軟件也都可以處理單個LF或者CR/LF的組合了。
LF在C語言中,用n表示。
垂直製表符,類似於水平製表符Tab,目的是爲了減少佈局中的工作,同時也減少了格式化字符時所需要存儲字符的空間。VT控制碼用於跳到下一個標記行。
說實話,還真沒看到有些地方需要用這個VT呢,因爲一般在換行的時候,都是用LF代替VT了。
設計換頁鍵,是用來控制打印機行爲的。
當打印機收到此鍵碼的時候,打印機移動到下一頁。
不同的設備的終端對此控制碼所表現的行爲各不同。有些會去清除屏幕,而其他有的只是顯示^L字符或者是隻是新換一行而已。
Shell腳本程序Bash和Tcsh的實現方式是,把FF看作是一個清除屏幕的命令。C語言程序中用f表示FF(換頁)。
CR回車的原意是讓打印頭回到左邊界,並沒有移動到下一行。
隨着時間流逝,後來人把CR的意思弄成了Enter鍵,用於示意輸入完畢。
在數據以屏幕顯示的情況下,人們在Enter的同時,也希望把光標移動到下一行。
因此C語言和Unix操作系統,重新定義了LF的意思,使其表示爲移動到下一行。當輸入CR去存儲數據的時候,軟件也常常隱式地將其轉換爲LF。
14 – SO – Shift Out 不用切換
15 – SI – Shift In 啓用切換
早在1960s年代,定義ASCII字符集的人,就已經懂得了,設計字符集不單單可以用於英文字符集,也要能應用於外文字符集,是很重要的。
定義Shift In 和Shift Out的含義,即考慮到了此點。
最開始,其意爲在西里爾語和拉丁語之間切換。
西里爾ASCII定義中,KOI-7用到了Shift字符。拉丁語用Shift去改變打印機的字體。
在此種用途中,SO用於產生雙倍寬度的字符,而用SI打印壓縮的字體。
有時候,我們需要在正在進行的通信過程中去發送一些控制字符。但是,總有一些情況下,這些控制字符卻被看成了普通的數據流,而沒有起到對應的控制效果。而ASCII標準中,定義DLE來解決這類問題。
如果數據流中檢測到了DLE,數據接收端則對其後面接下來的數據流中的字符,另作處理。
而關於具體如何處理這些字符,ASCII規範中則沒有具體定義,而只是弄了個DLE去打斷正常數據的處理,告訴接下來的數據,要特殊對待。
根據Modem中的Hayes通信協議DLE定義爲“無聲+++無聲”。
以我的觀點,這樣可能會更好:如果Hayes協議沒有把DLE處理爲嵌入通訊的無聲狀態,那樣就符合現存的標準了。
然而Hayes的開發者卻覺得+++用的頻率要遠高於原始的DLE,所以才這麼定義了。
這個ASCII控制字符儘管原先定義爲DC1, 但是現在常表示爲XON,用於串行通信中的軟件流控制。
其主要作用爲,在通信被控制碼XOFF中斷之後,重新開始信息傳輸。
用過串行終端的人應該還記得,當有時候數據出錯了,按Ctrl+Q(等價於XON)有時候可以起到重新傳輸的效果。
這是因爲,此Ctrl+Q鍵盤序列實際上就是產生XON控制碼,其可以將那些由於終端或者主機方面,由於偶爾出現的錯誤的XOFF控制碼而中斷的通信解鎖,使其正常通信。
EM用於,當數據存儲到達串行存儲介質末尾的時候,就像磁帶或磁頭滾動到介質末尾一樣。其用於表述數據的邏輯終點,即不必非要是物理上的達到數據載體的末尾。
字符Escape,是ASCII標準的首創的,由Bob Bemer提議的。用於開始一段控制碼的擴展字符。如此,即可以不必將所有可能想得到的字符都放到ASCII標準中了。
因爲,新的技術可能需要新的控制命令,而ESC可以用作這些字符命令的起始標誌。
ESC廣泛用於打印機和終端,去控制設備設置,比如字體,字符位置和顏色等等。
如果最開始的ASCII標準中,沒有定義ESC,估計ASCII標準早就被其他標準所替代了,因爲其沒有包含這些新出現的字符,所以肯定會有其他新的標準出現,用於表示這些字符的。
即,ESC給開發者提供了,可以根據需要而定義新含義的字符的可能。
文件分隔符是個很有意思的控制字符,因爲其可以讓我們看到1960s年代的時候,計算機技術是如何組織的。
我們現在,習慣於隨即訪問一些存儲介質,比如RAM,磁盤,但是在定義ASCII標準的那個年代,大部分數據還是順序的,串行的,而不是隨機訪問的。此處所說的串行的,不僅僅指的是串行通信,還指的是順序存儲介質,比如穿孔卡片,紙帶,磁帶等。
在串行通信的時代,設計這麼一個用於表示文件分隔符的控制字符,用於分割兩個單獨的文件,是一件很明智的事情。而FS的原因就在於此。
ASCII定義控制字符的原因中,其中一條就是考慮到了數據存儲方面的情況。
大部分情況下,數據庫的建立,都和表有關,包含了對應的記錄。同一個表中的所有的記錄,屬於同一類型。不同的表中的記錄,屬於對應的不同的類型。
而分組符GS就是用來分隔串行數據存儲系統中的不同的組。值得注意的是,當時還沒有使用word的表格,當時ASCII時代的人,把他叫做組。
在ASCII定義中,在數據庫中所存儲的,最小的數據項,叫做Unit單元。而現在我們稱其field域。單元分隔符US用於分割串行數據存儲環境下的不同的域。
現在大部分的數據庫實現,要求大部分類型都擁有固定的長度。
儘管大部分時候可能用不到,但是對於每一個域,卻都要分配足夠大的空間,用於存放最大可能的成員變量。
這樣的做法,佔用了大量的存儲空間,而US控制碼允許域具有可變的長度。在1960s年代,數據存儲空間很有限,用US這個單元分隔符,將不同單元分隔開,這樣就可以實現更高效地存儲那些寶貴的數據。
另一方面,串行存儲的存儲效率,遠低於RAM和磁盤中所實現的表格存儲。我個人無法想象,如果現在的數據,還是存儲在自帶或者帶滾輪的磁帶上,會是何種景象。
也許你會爭論說,空格鍵是否真的能算是一個控制字符?因爲現在在普通文字中使用空格鍵是如此常見。
但是,既然水平製表符和退格鍵在ASCII中,都被叫做控制字符了,那麼我覺得也很自然地,可以把空格鍵(向前的空格)也叫做控制字符,畢竟,其本身並不代表一個真正的可見的字符,而僅僅只是很常用於輸出設備,用於處理位置前向移動一格,清除當前位置的內容而已。
在很多程序中,比如字符處理程序,白空格同樣可能從導致行尾轉到下一行行首,而網絡瀏覽器將多個空格組合成單個空格輸出。
所以,這更加堅定了我的想法,覺得完全可以把空格看成是一個控制字符,而不僅僅是一個很獨特的普通字符。
常見ASCII字符,以及其他非常見的字符,Unicode中的字符,其他特殊字符等等,這些字符的英文叫法,可以去Unicode官方找到:
http://www.unicode.org/charts/#symbols
比如:
ASCII字符/字母的叫法/讀法 如何讀 :