天天看點

「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生

作者:oeasy

換行字元

回憶上次内容

  • struct包可以讓我們使用封包格式
    • 把數字封包到位元組裡
      • pack函數負責封包
      • unpack函數負責解封
    • 我們通過封到不同的位元組狀态
      • 周遊了一次ascii碼
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 還是有那片黑色的區域
    • 好像是一片黑暗森林!
    • 那裡面到底有些什麼秘密?
  • 我們這次向黑暗森林區域進發!!
  • 整理行裝
  • 出發!

chr

  • 先看看"oeasy"這個字元串是如何存在的
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 字元都對應着一個數字
    • 數字在計算機上究竟是如何存儲的呢?
    • 用二進制形式存儲在位元組中的
  • 可以看看這個二進制形式麼?

chr

  • 8bit 構成 byte
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 上圖的位元組為
    • (0011 0101)2
    • (35)16
    • 對應着字元'5'
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 那字母呢?
  • abcd在記憶體裡長什麼樣子?

檔案編碼

  • 編寫一個檔案
    • 寫下 abcd
    • 用 :%!xxd
    • :%!xxd -r 變回來
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 可以看到檔案是用 2進制 方式存儲的
    • 0x61 - a
    • 0x62 - b
    • 0x63 - c
    • 0x64 - d
  • 不論是記憶體、硬碟還是網絡傳輸
    • a 對應
      • (0x61)16
      • (0b01100001)2
  • 圖中最後的那個 0x0a 對應什麼字元???

善用函數

  • 使用chr得到相關字元
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 0x0a對應的是'\n'這個字元
  • 這個字元好像在哪裡見過?

回到最初

  • 想要了解這個'\n'
    • 我們還得回到最初
  • 我們回到開始的時候
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 前面介紹過
    • BWK寫的 c 語言的第一個程式

\n

  • 注意到hello world後面的\n了麼?
    • 注意到hello world後面的\n了麼?
    • 特别注意斜杠的方向
      • 這個方向\叫反斜杠
        • 鍵盤位置在Enter鍵附近
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 那\n到底是什麼??

輸出"\n"

  • \n 是一個整體
    • 占一個位元組
    • 算一個字元
    • 序号是(10)10進制
    • 也就是(0x0a)16進制
    • 這就是在開篇時的abcd後面的字元
    • \n在記憶體裡顯示為一個.
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 我們直接把他輸出看看

輸出

  • 輸出
#輸出\n
print("\n")
#直接print
print()
#檢視序号
ord("\n")
#檢視十六進制的序号
hex(ord("\n"))           
  • 輸出結果
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 好像換了 2 行
    • 如果沒\n的話,隻換 1 行
    • 如果有\n的話, 就換 2 行
  • 我們看看ascii碼表是如何定義的這第10個字元的

找到位置

  • 我們已經身在在黑暗森林中
    • 找到了一個落腳點
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 十進制的10 就是 十六進制的 0x0A
    • 這個數值在 ascii 碼表中意思是 LF
  • 啥意思?

搜尋

  • 搜尋\n得到的結果是這樣的
    • LF 意味着 Line Feed
    • 喂行
    • 喂一行紙
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 那我真的可以用這個\n在字元中間換行嘛?

嘗試換行

#輸出字元串中帶有\n
print("Hello\nWorld")           
  • 在遊樂場中嘗試
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 中途換行成功!
  • 可以多來幾個換行符嗎?

多來幾個

  • 就往裡面加\n
#輸出字元串中帶有\n
print("He\nllo\nWor\nld")           
  • 顯然這個 \n 就是一個換行
    • 字元串裡面有個 \n 就意味着需要換 1 行
    • 他的英文是 Line Feed
    • 意思就是 新換1行
    • 這個東西其實比 ascii 的曆史還要悠久
    • 從打字機的時代就有了
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 為什麼要有換行符呢?

換行符

  • 最最開始的時候分段落
    • 都是靠打字機輸出空格完成換行
    • 自從有了這個LineFeed
    • 一個鍵就直接換行了
    • 是以LineFeed 極大地提高了效率
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 兩個換行符就換兩行
  • 可以使用chr函數麼?

使用序号得到換行符

#輸出ascii值為10的字元
chr(10)
#把這個字元放在print裡面輸出
print("hello"+chr(10)+"world")           
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 純文字中也會有回車符麼?
  • 我們去看看純文字檔案

打開文本文檔

https://github.com/overmind1980/oeasy-python-tutorial.git
vi oeasy-python-tutorial/samples/000016/anderson_fairy_tales.txt           
  • 首先下載下傳這個倉庫
  • 然後找到其中的安德森仙話這個本書
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 我們發現這個東西是318K
  • 那他有多少字元呢?

字元數量

  • 1個英文字元占一個位元組
    • 318k大概有318000個位元組
    • 大概是31.8萬個字元
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 這就是文本檔案的形式
  • 第一行的Andersen後面有應該有兩個換行符
  • 是不是呢真有換行符呢?

位元組形式

  • 所有行轉化為位元組形式
    • %!xxd
  • 查找0a
    • /0a
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 确實能夠找到那兩個換行符(0a)
  • 這可以和純文字方式對應起來嗎?

純文字方式

  • 文本中的換行
    • 其實就是換行符的效果
  • 在文本觀看模式下是換行
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 在位元組觀看模式下是0a
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 這本書後來被翻譯成安徒生童話

安徒生童話

  • 裡面有很多耳熟能詳的故事
    • 《皇帝的新裝》
    • 《海的女兒》
    • 《醜小鴨》
    • 《紅舞鞋》
    • 《賣火柴的小女孩》
    • 《拇指姑娘》
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 在安徒生所處的時代(1805-1875)
    • 丹麥仍是一個君主專制主義社會
    • 20年代經濟衰退
    • 童話用兒童視角透視複雜生活
    • 萬物有靈
    • 風趣幽默
  • Jean Hersholt
    • 将160個故事從丹麥文翻譯成英文
  • 劉半農 1914年
    • 翻譯了《皇帝的新衣》開始
  • 葉君健 1944年到1949年
    • 翻譯了 安徒生童話全集
  • 網際網路時代
    • 英文版安徒生童話被谷騰堡項目所收錄

落實

  • 文檔當中就是用0和1來表示字元的
  • 如下圖所示
    • 文字是藍色的
    • 位元組是黑色的
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 為什麼\n會用來表示換行(Line-Feed)呢?

追溯曆史

  • c語言 中的 \n 來自于什麼呢?
    • 來自于 B語言
    • B語言 是裡奇和湯普遜最早開發 unix 的語言
    • B語言 1969 年 就 運作在bell實驗室 的 PDP-8 上
  • 1971 年裡奇和湯普遜開始對于 B語言 進行改造
    • 在新買的 PDP-11 上用 B語言 給 B語言 寫擴充,稱之為 NewB
    • 1973 年 NewB 基本主體完成
      • 改名叫 c語言
    • 是以 c 其實是 NewB
  • 他們用手頭的編譯器和c語言給 PDP-11 重寫了一個 Unix Kernel
    • 機器語言和彙編語言本來不具有移植性
    • 就像x86的二進制程式不能直接運作在arm上
    • 需要移植
  • c語言 程式卻可以在 很多架構 的處理器上編譯運作
    • 隻要那種架構的處理器具有對應的 c語言編譯器和庫
    • 那就能順利編譯成針對該處理器架構的二進制程式
    • 甚至能實作跨平台編譯
      • 也就是今天所說的交叉編譯
    • 這就是 c語言 在當時能夠發展的原因
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • c語言 源自 B語言
  • B語言 也不是憑空創造的
    • 源自什麼呢?

Basic Combined Programming Language(BCPL)

  • B語言 源自BCPL(Basic Combined Programming Language)
    • 1967 年由劍橋大學的 Matin Richards 制作
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 在同樣由劍橋大學開發的 CPL語言 上改進而來
    • BCPL 最早被用做牛津大學的 OS6作業系統 上面的開發工具
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 後來通過美國貝爾實驗室的改進和推廣成為了 UNIX 上的常用開發語言
    • 最早 BCPL 語言的樣子就有個類似于l(ine)f(eed)的符号
    • 這是關于換行符表示法 最早的記錄
    • 當時的換行符長什麼樣呢?

BCPL的換行符

  • 當時的換行符長成這樣
    • !*n
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 上述程式的目是
    • 輸出 hello,world
    • 然後再來個回車
  • 是以hello world
    • 并不是c語言的發明
    • 而是從c語言的爺爺bcpl那時候就有了
    • 并且從bcpl時代就已經作為迷因(meme)開始傳播
  • python虛拟機的可執行檔案
  • 也就是pyc檔案是如何了解換行符的呢?

反彙編(disassemble)

  • 觀察一下
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • \n出現在字元串常量中
  • 能在pyc中找到這個常量麼?

先編譯

  • 将py檔案編譯成pyc檔案
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 再觀察

pyc檔案

  • 打開pyc檔案
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 确實能夠找到a和s之間的\n
  • 也就是(0a)16進制
  • 任務完成!!!

總結

  • \n 就是換行符号
    • 換行符對應着 ascii 字元的代碼是(10)10進制
    • 換行符的英文是 LF
    • 意思是Line Feed
  • 我們可以在《安徒生童話》的文本中
    • 找到每個字元對應的位元組形态
「oeasy」python0020換行字元_feed_line_lf_反斜杠n_B語言_安徒生
  • 不光txt檔案是檔案
    • 我們的python遊樂場本質上也是一個二進制可執行的檔案
    • 這個檔案在哪?
  • 我們可以讀懂這個可執行檔案嗎?
  • 我們下次再說!
  • 藍橋->https://www.lanqiao.cn/teacher/3584
  • github->https://github.com/overmind1980/oeasy-python-tutorial
  • gitee->https://gitee.com/overmind1980/oeasypython
  • 視訊->https://www.bilibili.com/video/BV1CU4y1Z7gQ 作者:oeasy