整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          功能強(qiáng)大的串口工具,抓緊收藏!

          開(kāi)源精選》是我們分享Github、Gitee等開(kāi)源社區(qū)中優(yōu)質(zhì)項(xiàng)目的欄目,包括技術(shù)、學(xué)習(xí)、實(shí)用與各種有趣的內(nèi)容。本期推薦的是一個(gè)功能強(qiáng)大的串口工具。支持Lua自動(dòng)化處理、串口調(diào)試、串口監(jiān)聽(tīng)、串口曲線、TCP測(cè)試、MQTT測(cè)試、編碼轉(zhuǎn)換、亂碼恢復(fù)等功能。

          功能列表

          • 其他串口調(diào)試功能具有的功能
          • 收發(fā)日志清晰明了,可同時(shí)顯示HEX值與實(shí)際字符串
          • 自動(dòng)保存串口與Lua腳本日志,并附帶時(shí)間
          • 串口斷開(kāi)后,如果再次連接,會(huì)自動(dòng)重連
          • 發(fā)送的數(shù)據(jù)可被用戶自定義的Lua腳本提前處理
          • 右側(cè)快捷發(fā)送欄,快捷發(fā)送條目數(shù)量不限制
          • 右側(cè)快捷發(fā)送欄,支持10頁(yè)數(shù)據(jù),互相獨(dú)立
          • 可獨(dú)立運(yùn)行Lua腳本,并擁有定時(shí)器與協(xié)程任務(wù)特性(移植自合宙Luat Task架構(gòu))
          • 可選文字編碼格式
          • 終端功能,直接敲鍵盤(pán)發(fā)送數(shù)據(jù)(包含ctrl+字母鍵)
          • 可單獨(dú)隱藏發(fā)送數(shù)據(jù)
          • 集成TCP、UDP、SSL測(cè)試服務(wù)端/客戶端功能,并且支持IPV6
          • 集成各種編碼互轉(zhuǎn)功能
          • 集成亂碼恢復(fù)功能
          • 集成mqtt測(cè)試功能
          • 集成串口監(jiān)聽(tīng)功能,可監(jiān)聽(tīng)其他軟件的串口通信數(shù)據(jù)

          特色功能示范

          使用Lua腳本提前處理待發(fā)送的數(shù)據(jù)

          • 結(jié)尾加上換行回車(chē)
          return uartData.."\r\n"
          • 發(fā)送16進(jìn)制數(shù)據(jù)
          return uartData:fromHex()

          此腳本可將形如30313233發(fā)送數(shù)據(jù),處理為0123的結(jié)果

          • 更多玩法等你發(fā)現(xiàn)
          json = require("JSON")
          t = uartData:split(",")
          return json:encode({
              key1 = t[1],
              key2 = t[2],
              key3 = t[3],
          })

          此腳本可將形如a,b,c發(fā)送數(shù)據(jù),處理為{"key1":"a","key2":"b","key3":"c"}的結(jié)果。

          獨(dú)立的Lua腳本自動(dòng)處理串口收發(fā)

          右側(cè)的Lua腳本調(diào)試區(qū)域,可直接運(yùn)行你寫(xiě)的串口測(cè)試腳本,如軟件自帶的:

          --注冊(cè)串口接收函數(shù)
          uartReceive = function (data)
              log.info("uartReceive",data)
              sys.publish("UART",data)--發(fā)布消息
          end
          
          --新建任務(wù),等待接收到消息再繼續(xù)運(yùn)行
          sys.taskInit(function()
              while true do
                  local _,udata = sys.waitUntil("UART")--等待消息
                  log.info("task waitUntil",udata)
                  local sendResult = apiSendUartData("ok!")--發(fā)送串口消息
                  log.info("uart send",sendResult)
              end
          end)
          
          --新建任務(wù),每休眠1000ms繼續(xù)一次
          sys.taskInit(function()
              while true do
                  sys.wait(1000)--等待1000ms
                  log.info("task wait",os.time())
              end
          end)
          
          --1000ms循環(huán)定時(shí)器
          sys.timerLoopStart(log.info,1000,"timer test")

          甚至你可以利用xlua框架的特性,調(diào)用C#接口完成任何你想做的事情

          request = CS.System.Net.WebRequest.Create("http://example.com")
          request.ContentType = "text/html;charset=UTF-8";
          request.Timeout = 5000;--超時(shí)時(shí)間
          request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37";
          
          response = request:GetResponse():GetResponseStream()
          
          myStreamReader = CS.System.IO.StreamReader(response, CS.System.Text.Encoding.UTF8);
          
          print(myStreamReader:ReadToEnd())--打印獲取的body內(nèi)容
          
          myStreamReader:Close()
          response:Close()

          使用此功能,你可以完成大部分的自動(dòng)化串口調(diào)試操作。

          示例圖


          -END-

          開(kāi)源協(xié)議:Apache-2.0

          開(kāi)源地址:https://gitee.com/chenxuuu/llcom


          TML(HyperText Markup Language)是一種用于創(chuàng)建網(wǎng)頁(yè)的標(biāo)準(zhǔn)標(biāo)記語(yǔ)言。在HTML中,"元素"和"標(biāo)簽"是構(gòu)建網(wǎng)頁(yè)的基本組成部分,它們一起定義了網(wǎng)頁(yè)的結(jié)構(gòu)和內(nèi)容。HTML標(biāo)簽是用來(lái)定義HTML元素的開(kāi)始和結(jié)束的,而HTML元素是由標(biāo)簽及其包含的內(nèi)容組成的。


          參考文檔:https://www.cjavapy.com/article/3303/


          1、HTML 元素


          HTML元素指的是從開(kāi)始標(biāo)簽到結(jié)束標(biāo)簽的所有內(nèi)容。它們是HTML文檔的構(gòu)建塊,用于創(chuàng)建和組織網(wǎng)頁(yè)內(nèi)容。HTML元素可以包含文本、圖片、鏈接、表格等多種類(lèi)型的數(shù)據(jù)。元素可能包括一個(gè)開(kāi)始標(biāo)簽和一個(gè)結(jié)束標(biāo)簽,也可能只有一個(gè)標(biāo)簽(在自閉合元素的情況下)。


          1) <!DOCTYPE> 聲明


          用于定義文檔類(lèi)型,告訴瀏覽器此文檔使用哪個(gè)HTML版本。


          <!DOCTYPE html>


          2) <html>


          根元素,包含整個(gè)HTML文檔。


          <html lang="en">
          </html>


          3) <head>


          包含文檔的元數(shù)據(jù),如標(biāo)題、字符集聲明和鏈接到樣式表。


          <head>
            <title>頁(yè)面標(biāo)題</title>
            <meta charset="UTF-8">
          </head>


          4)<title>


          定義文檔的標(biāo)題,顯示在瀏覽器的標(biāo)題欄或頁(yè)面的標(biāo)簽頁(yè)上。


          <title>這是文檔的標(biāo)題</title>


          5)<body>


          包含文檔的所有可見(jiàn)內(nèi)容,如文本、圖片、鏈接和其他多媒體元素。


          <body>
            <h1>這是一個(gè)主標(biāo)題</h1>
            <p>這是一個(gè)段落。</p>
          </body>


          6) <header>


          定義一個(gè)區(qū)域或頁(yè)面的頭部,通常包含標(biāo)題和導(dǎo)航鏈接。


          <header>
            <h1>網(wǎng)站標(biāo)題</h1>
            <nav>
              <ul>
                <li><a href="#">首頁(yè)</a></li>
                <li><a href="#">關(guān)于</a></li>
              </ul>
            </nav>
          </header>


          7) <footer>


          定義頁(yè)面或區(qū)域的頁(yè)腳部分,通常包含版權(quán)信息、聯(lián)系信息等。


          <footer>
            <p>版權(quán)所有 ? 2024</p>
          </footer>


          8) <nav>


          定義導(dǎo)航鏈接的部分,用于頁(yè)面內(nèi)或頁(yè)面間的導(dǎo)航。


          <nav>
            <ul>
              <li><a href="#">首頁(yè)</a></li>
              <li><a href="#">新聞</a></li>
            </ul>
          </nav>


          9)<section>


          定義文檔中的一個(gè)獨(dú)立部分,通常與標(biāo)題一起使用。


          <section>
            <h2>章節(jié)標(biāo)題</h2>
            <p>這是該章節(jié)的一些內(nèi)容。</p>
          </section>


          10. <article>


          定義可以獨(dú)立于內(nèi)容其余部分的完整自包含內(nèi)容,例如博客帖子或新聞文章。


          <article>
            <h2>文章標(biāo)題</h2>
            <p>文章內(nèi)容...</p>
          </article>


          11. <aside>


          定義與周?chē)鷥?nèi)容稍微分離的內(nèi)容,如側(cè)邊欄或廣告欄。


          <aside>
            <p>這是一些附加信息。</p>
          </aside>


          12. <figure> 和 <figcaption>


          <figure> 定義獨(dú)立的流內(nèi)容(如圖表、圖像、代碼示例等),<figcaption> 提供該內(nèi)容的標(biāo)題。


          <figure>
            <img src="image.jpg" alt="描述性文本">
            <figcaption>圖像標(biāo)題</figcaption>
          </figure>


          2、HTML 標(biāo)簽


          HTML標(biāo)簽是HTML元素的一部分,用于從邏輯上開(kāi)始或結(jié)束一個(gè)元素。標(biāo)簽通常成對(duì)出現(xiàn),包括一個(gè)開(kāi)始標(biāo)簽和一個(gè)對(duì)應(yīng)的結(jié)束標(biāo)簽,結(jié)束標(biāo)簽的名稱前會(huì)有一個(gè)斜線(/)作為區(qū)分。有些HTML標(biāo)簽是自閉合的,意味著它們不需要結(jié)束標(biāo)簽,如圖像標(biāo)簽(<img />)和換行標(biāo)簽(<br />)。


          標(biāo)簽

          說(shuō)明

          <!DOCTYPE>

          聲明文檔類(lèi)型和HTML版本。

          <html>

          標(biāo)識(shí)一個(gè)HTML文檔的根元素。

          <head>

          包含了文檔的元數(shù)據(jù)。

          <title>

          指定文檔的標(biāo)題。

          <body>

          包含了可見(jiàn)的頁(yè)面內(nèi)容。

          <h1> - <h6>

          定義標(biāo)題,從

          <h1> 到 <h6> 重要性遞減。

          <p>

          定義段落。

          <br>

          插入一個(gè)換行符。

          <hr>

          在頁(yè)面上繪制一條水平線。

          <b>

          定義粗體文本。

          <i>

          定義斜體文本。

          <u>

          定義下劃線文本。

          <strong>

          定義重要文本。

          <em>

          定義強(qiáng)調(diào)文本。

          <mark>

          定義被標(biāo)記或高亮的文本。

          <small>

          定義小號(hào)文本。

          <sub>

          定義下標(biāo)文本。

          <sup>

          定義上標(biāo)文本。

          <a>

          定義超鏈接。

          <img>

          在頁(yè)面中嵌入圖像。

          <ul>

          定義無(wú)序列表。

          <ol>

          定義有序列表。

          <li>

          定義列表項(xiàng)。

          <table>

          定義表格。

          <th>

          定義表格的表頭單元格。

          <tr>

          定義表格的行。

          <td>

          定義表格單元。

          <form>

          定義HTML表單。

          <input>

          定義輸入控件。

          <textarea>

          定義多行文本輸入控件。

          <button>

          定義按鈕。

          <select>

          定義下拉列表。

          <option>

          定義下拉列表中的選項(xiàng)。

          <article>

          定義文章。

          <section>

          定義文檔中的一個(gè)區(qū)域(或節(jié))。

          <header>

          定義介紹性內(nèi)容或?qū)Ш芥溄拥娜萜鳌?/p>

          <footer>

          定義注腳或文檔的頁(yè)腳。

          <nav>

          定義導(dǎo)航鏈接的部分。

          <aside>

          定義側(cè)邊欄內(nèi)容。


          使用示例:


          <!DOCTYPE html>
          使用示例:
          <!DOCTYPE html>
          <html>
          <head>
              <meta charset="UTF-8">
              <title>HTML標(biāo)簽使用示例</title>
          </head>
          <body>
          <header>
              <h1>歡迎來(lái)到我的網(wǎng)頁(yè)</h1>
              <nav>
                  <a href="#content">主要內(nèi)容</a> |
                  <a href="#contact-form">聯(lián)系表單</a>
              </nav>
          </header>
          <section id="content">
              <article>
                  <h2>HTML基礎(chǔ)</h2>
                  <p>HTML是構(gòu)建網(wǎng)頁(yè)的基石。<strong>標(biāo)簽</strong>是它的核心組成部分。<mark>本文</mark>介紹了一些最常用的HTML標(biāo)簽。</p>
              </article>
              <aside>
                  <h3>注意</h3>
                  <p>記得檢查HTML5的新特性和標(biāo)簽。</p>
              </aside>
              <ul>
                  <li>文本標(biāo)簽</li>
                  <li>列表</li>
                  <li>表格</li>
                  <li>表單</li>
              </ul>
              <ol>
                  <li>先介紹基礎(chǔ)</li>
                  <li>然后是進(jìn)階</li>
              </ol>
              <table>
                  <tr>
                      <th>標(biāo)簽</th>
                      <th>描述</th>
                  </tr>
                  <tr>
                      <td><p></td>
                      <td>段落標(biāo)簽</td>
                  </tr>
                  <tr>
                      <td><a></td>
                      <td>鏈接標(biāo)簽</td>
                  </tr>
              </table>
          </section>
          <section id="images">
              <h2>圖片</h2>
              <img src="example.jpg" alt="示例圖片">
          </section>
          <footer>
              <section id="contact-form">
                  <h2>聯(lián)系我們</h2>
                  <form>
                      <label for="name">姓名:</label>
                      <input type="text" id="name" name="name"><br>
                      <label for="email">電子郵件:</label>
                      <input type="email" id="email" name="email"><br>
                      <input type="submit" value="提交">
                  </form>
              </section>
              <p>? 2024 HTML標(biāo)簽示例</p>
          </footer>
          </body>
          </html>


          參考文檔:Hhttps://www.cjavapy.com/article/3303/

          者:李彥鋒,騰訊 IEG 運(yùn)營(yíng)開(kāi)發(fā)工程師

          一直想寫(xiě)一篇關(guān)于C語(yǔ)言的文章,里面包含C語(yǔ)言的發(fā)展史、創(chuàng)始人等相關(guān)事跡。但是卻遲遲未寫(xiě),主要原因是因?yàn)椋涸谖铱磥?lái),這個(gè)語(yǔ)言太過(guò)于偉大、耀眼。作為一個(gè)僅僅使用過(guò)C語(yǔ)言的普通開(kāi)發(fā)來(lái)說(shuō),完全沒(méi)資格去寫(xiě)。但是,最近在看過(guò)一篇丹尼斯.里奇寫(xiě)的《C語(yǔ)言發(fā)展史》之后,堅(jiān)定了我寫(xiě)這篇文章的決心。不是歌功頌德,僅僅是以一種客觀的視角去欣賞。

          1. C語(yǔ)言發(fā)展史

          任何一種新事物的出現(xiàn)都不是來(lái)自于偶然,而是時(shí)代所驅(qū)使的必然結(jié)果。

          1.1 C語(yǔ)言有多偉大

          如果你問(wèn)我:C語(yǔ)言有多偉大。那么,我可能會(huì)想一下,說(shuō):多偉大我不知道,但是我知道很偉大。

          這里,我想說(shuō)一句可能有點(diǎn)片面的話,就是:如今這世界上,凡是帶電的地方,可能都會(huì)有她(C語(yǔ)言)或者她的子孫的影子。

          任何比C語(yǔ)言更低級(jí)的語(yǔ)言,都不足以完整地抽象一個(gè)計(jì)算機(jī)系統(tǒng);任何比C高級(jí)的語(yǔ)言,都可以用C來(lái)實(shí)現(xiàn)。

          1.2 C語(yǔ)言之父

          Ritchie 貝爾實(shí)驗(yàn)室的個(gè)人主頁(yè)地址 https://www.bell-labs.com/usr/dmr/www/index.html

          丹尼斯·麥卡利斯泰爾·里奇(英語(yǔ):Dennis MacAlistair Ritchie,1941年9月9日-2011年10月12日),美國(guó)計(jì)算機(jī)科學(xué)家。黑客圈子通常稱他為“dmr”。他是C語(yǔ)言的創(chuàng)造者、Unix操作系統(tǒng)的關(guān)鍵開(kāi)發(fā)者,對(duì)計(jì)算機(jī)領(lǐng)域產(chǎn)生了深遠(yuǎn)影響,并肯·湯普遜同為1983年圖靈獎(jiǎng)得主。

          丹尼斯.里奇 生平時(shí)間線

          麻省理工大學(xué)計(jì)算機(jī)系的馬丁教授評(píng)價(jià)說(shuō):"如果說(shuō),喬布斯是可視化產(chǎn)品中的國(guó)王,那么里奇就是不可見(jiàn)王國(guó)中的君主。喬布斯的貢獻(xiàn)在于,他如此了解用戶的需求和渴求,以至于創(chuàng)造出了讓當(dāng)代人樂(lè)不思蜀的科技產(chǎn)品。然而,卻是里奇先生為這些產(chǎn)品提供了最核心的部件,人們看不到這些部件,卻每天都在使用著。"

          克尼漢評(píng)價(jià)道:牛頓說(shuō)他是站在巨人的肩膀上,如今,我們都站在里奇的肩膀上。

          1.3 C語(yǔ)言的先輩

          為了簡(jiǎn)潔起見(jiàn),我(Dennis M.Ritchie)省略了對(duì)C本身,其父級(jí)B [Johnson 73]和其祖父母BCPL [Richards 79]的完整描述,而只關(guān)注每種語(yǔ)言的特征元素以及它們?nèi)绾窝葑儭?/span>

          This paper is about the development of the C programming language, the influences on it, and the conditions under which it was created. For the sake of brevity, I omit full descriptions of C itself, its parent B [Johnson 73] and its grandparent BCPL [Richards 79], and instead concentrate on characteristic elements of each language and how they evolved.

          https://www.bell-labs.com/usr/dmr/www/chist.html

          這段文字出自C語(yǔ)言之父丹尼斯.M.里奇所寫(xiě)的一篇關(guān)于《C語(yǔ)言發(fā)展史》的文章,文中明確指出C語(yǔ)言源自于B、BCPL兩種語(yǔ)言。可以把C語(yǔ)言看做是站在巨人的肩上,順應(yīng)時(shí)代潮流的后浪。

          1.3.1 BCPL語(yǔ)言之父

          Martin Richards

          Martin Richards's BCPL Reference Manual, 1967 https://web.archive.org/web/20080622171914/http://cm.bell-labs.com/cm/cs/who/dmr/bcpl.html

          馬丁·理查德(英語(yǔ):Martin Richards,1940年7月21日-),生于英國(guó),計(jì)算機(jī)科學(xué)家,為BCPL編程語(yǔ)言的發(fā)明者,發(fā)展了TRIPOS操作系統(tǒng)。

          1966年,馬丁·理查德在劍橋大學(xué),以CPL編程語(yǔ)言為基礎(chǔ),發(fā)明了BCPL編程語(yǔ)言。

          1.3.2 B語(yǔ)言之父

          Kenneth Lane Thompson

          肯尼斯·蘭·湯普遜(英語(yǔ):Kenneth Lane Thompson,1943年2月4日-)小名肯·湯普遜(英語(yǔ):Ken Thompson),美國(guó)計(jì)算機(jī)科學(xué)學(xué)者和工程師。黑客文化圈子通常稱他為“ken”。在貝爾實(shí)驗(yàn)室工作期間,湯普遜設(shè)計(jì)和實(shí)現(xiàn)了Unix操作系統(tǒng)。他創(chuàng)造了B語(yǔ)言(基于BCPL) — C語(yǔ)言的前身,而且是Plan 9操作系統(tǒng)的創(chuàng)造者和開(kāi)發(fā)者之一。與丹尼斯·里奇同為1983年圖靈獎(jiǎng)得主。

          2006年,湯普遜進(jìn)入Google公司工作,與他人共同設(shè)計(jì)了Go語(yǔ)言。

          1.3.3 一組Ken與Dennis的照片

          日益精進(jìn)

          站在巨人的肩上

          坐著的是Ken 站著的是Dennis

          與優(yōu)秀之人為伍

          不畏得失,做有趣的事

          左Ken 右Dennis | 右上角:Unix標(biāo)識(shí)牌

          言傳身教

          感謝丹尼斯.里奇留給了這世界一本“C語(yǔ)言圣經(jīng)”

          可惜的是,當(dāng)年筆者大學(xué)學(xué)的是譚浩強(qiáng)譚老師的C語(yǔ)言


          Dennis與《The C Programming Language》

          互相成就

          終成正果

          你做了什么,最終會(huì)被世人看到

          1999年獲得美國(guó)國(guó)家技術(shù)獎(jiǎng) [左一:Ken | 左二:Dennis | 右一:克林頓]

          從這些老照片中,我隱隱約約看到了幾行小字,寫(xiě)著:

          1.與優(yōu)秀之人為伍

          2.互相成就

          試想,有多么重要?

          1.4 C語(yǔ)言時(shí)間線

          Computer Languages History https://www.levenez.com/lang/

          從圖中時(shí)間線,可以明顯的看出C語(yǔ)言的起源以及時(shí)間節(jié)點(diǎn)。

          有時(shí)候不得不說(shuō)時(shí)勢(shì)造英雄,在1969~1971年之間著名的操作系統(tǒng)Unix從肯.湯普遜手中誕生,作為一種大型的系統(tǒng)性軟件來(lái)說(shuō),極其需要一種可靠的高級(jí)語(yǔ)言的出現(xiàn)(當(dāng)時(shí)的低級(jí)語(yǔ)言指的是匯編,因?yàn)橹暗牟僮飨到y(tǒng)是用匯編寫(xiě)的)。這個(gè)時(shí)候的丹尼斯.里奇也沒(méi)閑著,在對(duì)B語(yǔ)言改良之后,就誕生了帶有類(lèi)型的C語(yǔ)言(據(jù)里奇自己說(shuō),有一段時(shí)間稱這種改良的語(yǔ)言為NB。即:new B。不過(guò),在我們這些吃瓜群眾眼中看來(lái)也確實(shí)NB)。

          In 1971 I began to extend the B language by adding a character type and also rewrote its compiler to generate PDP-11 machine instructions instead of threaded code. Thus the transition from B to C was contemporaneous with the creation of a compiler capable of producing programs fast and small enough to compete with assembly language. I called the slightly-extended language NB, for `new B.'

          1.5 unix時(shí)間線

          Unix的誕生與C語(yǔ)言被廣泛的傳播、使用,有著密切的聯(lián)系。

          上圖時(shí)間線只顯示前幾個(gè)與C語(yǔ)言在相同時(shí)間段內(nèi)誕生的Unix版本(當(dāng)然,感興趣的話,可以查詢Unix相關(guān)發(fā)展史,絕對(duì)會(huì)讓你大吃一驚。其中最著名的幾個(gè)分支:BSD、minix、Linux...)。

          下面,通過(guò)在網(wǎng)上找得到的部分Unix內(nèi)核源碼,來(lái)追溯一下C語(yǔ)言出現(xiàn)的時(shí)機(jī)。

          1.5.1 PDP-Unix

          PDP-Unix系統(tǒng)內(nèi)核代碼文件

          PDP-7 Unix https://minnie.tuhs.org/cgi-bin/utree.pl?file=PDP7-Unix

          可以看到基本都是用匯編寫(xiě)的(文件名后綴.s)。為什么用基本這個(gè)詞呢?因?yàn)椋谙到y(tǒng)里面有一部分命令是用B語(yǔ)言寫(xiě)的。

          1.5.2 First Edition Unix

          First Edition Unix系統(tǒng)內(nèi)核代碼文件

          https://minnie.tuhs.org/cgi-bin/utree.pl?file=V1

          可以看到,還是用匯編寫(xiě)的(文件名后綴.s)。

          1.5.3 Second Edition Unix

          Second Edition Unix系統(tǒng)內(nèi)核代碼文件

          Second Edition Unix The second edition of Unix was developed for the PDP-11 at Bell Labs by Ken Thompson, Dennis Ritchie and others. It extended the First Edition with more system calls and more commands. This edition also saw the beginning of the C language, which was used to write some of the commands.

          https://minnie.tuhs.org/cgi-bin/utree.pl?file=V2

          到這個(gè)版本,已經(jīng)可以看到C語(yǔ)言的身影了。

          1.5.4 Unix與C語(yǔ)言

          從C語(yǔ)言在Unix V2版本出現(xiàn)之后,Unix的V3版本開(kāi)始,已經(jīng)可以在Unix內(nèi)核中見(jiàn)到大量C語(yǔ)言編寫(xiě)的代碼。

          據(jù)里奇所說(shuō):到1973年初,現(xiàn)代C的基本知識(shí)已經(jīng)完成。C語(yǔ)言和編譯器強(qiáng)大到,足以讓我們?cè)诋?dāng)年夏天用C重寫(xiě)PDP-11的Unix內(nèi)核 (也就是Unix的V3版本)。

          By early 1973, the essentials of modern C were complete. The language and compiler were strong enough to permit us to rewrite the Unix kernel for the PDP-11 in C during the summer of that year.

          到了這個(gè)時(shí)間節(jié)點(diǎn),基本可以肯定的是C語(yǔ)言、Unix的大部分核心都已經(jīng)完善。剩下要做的就是,可移植性、標(biāo)準(zhǔn)化。

          后面的故事,大家可能也聽(tīng)說(shuō)過(guò):后來(lái)學(xué)術(shù)和政府組織中都在使用Unix,也正是由于Unix的風(fēng)靡與興盛,帶動(dòng)了C語(yǔ)言被廣泛的傳播、使用。

          在1980年代,C語(yǔ)言的使用廣泛傳播,并且?guī)缀跛袡C(jī)器體系結(jié)構(gòu)和操作系統(tǒng)都可以使用編譯器。尤其是,它已成為個(gè)人計(jì)算機(jī)的編程工具,無(wú)論是用于這些機(jī)器的商業(yè)軟件制造商,還是對(duì)編程感興趣的最終用戶,都非常受歡迎。

          During the 1980s the use of the C language spread widely, and compilers became available on nearly every machine architecture and operating system; in particular it became popular as a programming tool for personal computers, both for manufacturers of commercial software for these machines, and for end-users interested in programming.

          這也就是所謂的互相成就。

          一句話概括就是:不畏得失、日漸精進(jìn),最終互相成就。

          1.6 第一個(gè)C語(yǔ)言編譯器是怎樣編寫(xiě)的?

          不知道你有沒(méi)有想過(guò),大家都用C語(yǔ)言或基于C語(yǔ)言的語(yǔ)言來(lái)寫(xiě)編譯器,那么世界上第一個(gè)C語(yǔ)言編譯器又是怎么編寫(xiě)的呢?這不是一個(gè)“雞和蛋”的問(wèn)題……

          回顧一下C語(yǔ)言歷史:Tomphson在BCPL的基礎(chǔ)上開(kāi)發(fā)了B語(yǔ)言,Ritchie又在B語(yǔ)言的基礎(chǔ)上成功開(kāi)發(fā)出了現(xiàn)在的C語(yǔ)言。在C語(yǔ)言被用作系統(tǒng)編程語(yǔ)言之前,Tomphson也用過(guò)B語(yǔ)言編寫(xiě)過(guò)操作系統(tǒng)。可見(jiàn)在C語(yǔ)言實(shí)現(xiàn)以前,B語(yǔ)言已經(jīng)可以投入使用了。因此第一個(gè)C語(yǔ)言編譯器的原型完全可能是用B語(yǔ)言或者混合B語(yǔ)言與PDP匯編語(yǔ)言編寫(xiě)的。

          我們現(xiàn)在都知道,B語(yǔ)言的執(zhí)行效率比較低,但是如果全部用匯編語(yǔ)言來(lái)編寫(xiě),不僅開(kāi)發(fā)周期長(zhǎng)、維護(hù)難度大,更可怕的是失去了高級(jí)程序設(shè)計(jì)語(yǔ)言必需的移植性。

          所以早期的C語(yǔ)言編譯器就采取了一個(gè)取巧的辦法:先用匯編語(yǔ)言編寫(xiě)一個(gè)C語(yǔ)言的一個(gè)子集的編譯器,再通過(guò)這個(gè)子集去遞推,進(jìn)而完成完整的C語(yǔ)言編譯器。

          詳細(xì)的過(guò)程如下:先創(chuàng)造一個(gè)只有C語(yǔ)言最基本功能的子集,記作C0語(yǔ)言,C0語(yǔ)言已經(jīng)足夠簡(jiǎn)單了,可以直接用匯編語(yǔ)言編寫(xiě)出C0的編譯器。依靠C0已有的功能,設(shè)計(jì)比C0復(fù)雜,但仍然不完整的C語(yǔ)言的又一個(gè)子集C1語(yǔ)言,其中C0屬于C1,C1屬于C,用C0開(kāi)發(fā)出C1語(yǔ)言的編譯器。在C1的基礎(chǔ)上設(shè)計(jì)C語(yǔ)言的又一個(gè)子集C2語(yǔ)言,C2語(yǔ)言比C1復(fù)雜,但是仍然不是完整的C語(yǔ)言,開(kāi)發(fā)出C2語(yǔ)言的編譯器 …… 如此直到CN,CN已經(jīng)足夠強(qiáng)大了,這時(shí)候就足夠開(kāi)發(fā)出完整的C語(yǔ)言編譯器的實(shí)現(xiàn)了。至于這里的N是多少,這取決于你的目標(biāo)語(yǔ)言(這里是C語(yǔ)言)的復(fù)雜程度和程序員的編程能力。簡(jiǎn)單地說(shuō),如果到了某個(gè)子集階段,可以很方便地利用現(xiàn)有功能實(shí)現(xiàn)C語(yǔ)言時(shí),那么你就找到N了。下面的圖說(shuō)明了這個(gè)抽象過(guò)程:

          https://kknews.cc/tech/bx2r3j.html 介紹一個(gè)概念,“自編譯”Self-Compile,也就是對(duì)于某些具有明顯自舉性質(zhì)的強(qiáng)類(lèi)型(所謂強(qiáng)類(lèi)型就是程序中的每個(gè)變量必須聲明類(lèi)型后才能使用,比如C語(yǔ)言,相反有些腳本語(yǔ)言則根本沒(méi)有類(lèi)型這一說(shuō)法)編程語(yǔ)言,可以借助它們的一個(gè)有限小子集,通過(guò)有限次數(shù)的遞推來(lái)實(shí)現(xiàn)對(duì)它們自身的表述,這樣的語(yǔ)言有C、Pascal、Ada等等,至于為什么可以自編譯,可以參見(jiàn)清華大學(xué)出版社的《編譯原理》,書(shū)中實(shí)現(xiàn)了一個(gè)Pascal的子集的編譯器。

          https://zhuanlan.zhihu.com/p/136102461

          而這個(gè)過(guò)程也在Unix V2版本中找到了證據(jù)。

          肯恩·湯普森,丹尼斯·里奇和其他人在貝爾實(shí)驗(yàn)室為PDP-11開(kāi)發(fā)了Unix的第二版。它通過(guò)更多的系統(tǒng)調(diào)用和更多的命令擴(kuò)展了第一版。此版本還看到了C語(yǔ)言的開(kāi)始,該語(yǔ)言用于編寫(xiě)一些命令。

          此處的代碼僅是某些命令,某些庫(kù)函數(shù)和C編譯器的源代碼。c /中的文件來(lái)自 last1120c.tar.gz 磁帶,并構(gòu)成了第二版Unix的有效C編譯器。

          下載地址:http://minnie.tuhs.org/Archive/Applications/Early_C_Compilers/last1120c.tar.gz

          The second edition of Unix was developed for the PDP-11 at Bell Labs by Ken Thompson, Dennis Ritchie and others. It extended the First Edition with more system calls and more commands. This edition also saw the beginning of the C language, which was used to write some of the commands.

          The code here is only the source to some of the commands, some of the library functions, and the C compiler. The files in c/ come from the last1120c.tar.gz tape, and form a working C compiler for Second Edition Unix.

          https://minnie.tuhs.org/cgi-bin/utree.pl?file=V2

          下載源碼解壓縮之后,目錄結(jié)構(gòu)如下:



          感興趣的小伙伴可以下載下來(lái)研究一下。

          2. BCPL、B、C語(yǔ)言比較

          如果想要找到一種好的方式,來(lái)進(jìn)行編程語(yǔ)言之間比較的話,那么非代碼莫屬。

          2.1 3種語(yǔ)言代碼示例

          下面分別使用BCPL、B、C三種語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的程序:程序?qū)⑷齻€(gè)數(shù)字a、b、c相加,并將結(jié)果賦值給sum,最后打印總和。

          2.1.1 BCPL語(yǔ)言示例

          BCPL https://zh.wikipedia.org/wiki/BCPL

          GET "libhdr"
          
          LET start() = VALOF
          { LET a, b, c = 1, 2, ,3
          
              sum := a + b + c
              writen(sum)
          }
          
          • LET 聲明變量
          • := 符號(hào)為賦值符號(hào) Go中也有該符號(hào),表示函數(shù)內(nèi)部局部變量。這里感覺(jué)很有意思的一點(diǎn)是:最初B語(yǔ)言之父肯.湯普遜把:=符號(hào)改成了=符號(hào)。現(xiàn)在,也作為Go語(yǔ)言之父之一,又把:=符號(hào)請(qǐng)回來(lái)了(冥冥之中的命運(yùn)~)。

          從BCPL到B的過(guò)渡中,決定使用單個(gè)字符 = 代替賦值 :=

          Other fiddles in the transition from BCPL to B were introduced as a matter of taste, and some remain controversial, for example the decision to use the single character = for assignment instead of :=. Similarly, B uses /**/ to enclose comments, where BCPL uses //, to ignore text up to the end of the line. The legacy of PL/I is evident here. (C++ has resurrected the BCPL comment convention.) Fortran influenced the syntax of declarations: B declarations begin with a specifier like auto or static, followed by a list of names, and C not only followed this style but ornamented it by placing its type keywords at the start of declarations.

          https://www.bell-labs.com/usr/dmr/www/chist.html

          2.1.2 B語(yǔ)言示例

          A TUTORIAL INTRODUCTION TO THE LANGUAGE B https://web.archive.org/web/20070807110157/http://cm.bell-labs.com/cm/cs/who/dmr/btut.html

          B語(yǔ)言的語(yǔ)言結(jié)構(gòu)

          main() {
              -- statements --
          }
          
          newfunc(arg1, arg2) {
              -- statements --
          }
          
          fun3(arg) {
              -- more statements --
          }
          

          B語(yǔ)言代碼示例

          main() {
            auto a, b, c, sum;
          
            a = 1; b = 2; c = 3;
            sum = a+b+c;
            putnumb(sum);
          }
          
          • 語(yǔ)句auto ...是一個(gè)聲明。即,它定義了要在函數(shù)內(nèi)使用的局部變量
          • putnumb 是一個(gè)帶參數(shù)的庫(kù)函數(shù),它將在終端上打印一個(gè)數(shù)字

          2.1.3 C語(yǔ)言示例

          #include <stdio.h>
          
          void main(){
            int a,b,c,sum;
            
            a=1; b=2; c=3;
            sum = a+b+c;
            printf("%d", sum);
          }
          

          2.2 示例代碼中三者的區(qū)別

          通過(guò)上面例子可以三者的區(qū)別:

          1. C語(yǔ)言寫(xiě)法更接近于B語(yǔ)言
          2. BCPL、B語(yǔ)言都是無(wú)類(lèi)型的語(yǔ)言,用word/cell表示一個(gè)固定長(zhǎng)度的bit。C語(yǔ)言是有類(lèi)型的

          有一些地方,你可能感興趣:

          • ++、-- 符號(hào)是Thompson發(fā)明的
          • &&、|| 是在C語(yǔ)言引入的

          說(shuō)明:

          1. 查了好久只找到了BCPL、B語(yǔ)言的部分代碼片段,至于能不能跑起來(lái),我也不知道 ^_^
          2. 如果想要知曉三者的具體區(qū)別的話,建議閱讀丹尼斯.里奇關(guān)于《C語(yǔ)言發(fā)展史》的文章
          3. BCPL、B語(yǔ)言也有經(jīng)歷過(guò)若干次版本迭代 (因?yàn)椋W(wǎng)上找到的代碼片段有很多寫(xiě)法不一樣的地方。比如說(shuō),維基百科中找到的B代碼片段,與在Unix內(nèi)核前幾個(gè)版本中找到的B代碼片段寫(xiě)法就不一樣。個(gè)人推測(cè)是版本問(wèn)題,不同的版本不同的寫(xiě)法)
          4. C語(yǔ)言更接近與B語(yǔ)言,或者說(shuō)是在B的基礎(chǔ)上不斷的添加了很多新特性 (拋出2個(gè)問(wèn)題:1.里奇起名字時(shí)為什么不像C++一樣,起名叫B++ ? 2.為什么C++用了2個(gè)加號(hào),而不是一個(gè)加號(hào),叫C+ ? 歡迎腦洞夠大的同學(xué)在評(píng)論留言!)
          5. 如果有高手覺(jué)得上面的代碼片段有問(wèn)題或者知道怎么跑起來(lái)的話,可以私下交流

          3. 歷史為什么選擇C語(yǔ)言

          1960s年代后期,貝爾實(shí)驗(yàn)室對(duì)計(jì)算機(jī)系統(tǒng)的研究進(jìn)入繁盛時(shí)期。MIT、General Electric、Bell實(shí)驗(yàn)室合作的Mutlics項(xiàng)目以失敗而告終(1969年左右)。就是在這個(gè)時(shí)期,Ken Tompson開(kāi)始寫(xiě)Mutlics的替代品,他希望按照自己的設(shè)計(jì)構(gòu)造一個(gè)令人舒服的計(jì)算系統(tǒng)(也就是Unix)。后來(lái)在寫(xiě)出第一個(gè)版本的Unix時(shí),覺(jué)得Unix上需要一個(gè)新的系統(tǒng)編程語(yǔ)言,他創(chuàng)造了一個(gè)B語(yǔ)言。B語(yǔ)言是沒(méi)有類(lèi)型的C,準(zhǔn)確說(shuō)B語(yǔ)言是Tompson把BCPL擠進(jìn)8K內(nèi)存,被其個(gè)人大腦過(guò)濾后的產(chǎn)生的語(yǔ)言。

          由于B語(yǔ)言存在的一些問(wèn)題,導(dǎo)致其只是被用來(lái)寫(xiě)一些命令工具使用。恰好在這個(gè)時(shí)期,Ritchie在B語(yǔ)言的基礎(chǔ)上,進(jìn)行了重新的設(shè)計(jì)改良,從而誕生了C語(yǔ)言。

          1973年,C語(yǔ)言基本上已經(jīng)完備,從語(yǔ)言和編譯器層面已經(jīng)足夠讓Tompson和Ritchie使用C語(yǔ)言重寫(xiě)Unix內(nèi)核。后來(lái),Unix在一些研究機(jī)構(gòu)、大學(xué)、政府機(jī)關(guān)開(kāi)始慢慢流行起來(lái),進(jìn)而帶動(dòng)了C語(yǔ)言的發(fā)展。

          1978年,K&R編寫(xiě)的《The C Programming Language》出版,進(jìn)一步推動(dòng)了C語(yǔ)言的普及。

          用一句話總結(jié)就是:對(duì)的時(shí)間、對(duì)的地點(diǎn),出現(xiàn)了對(duì)的人以及工具 (Unix與C語(yǔ)言的關(guān)系,有點(diǎn)像GNU與Linux kernel的關(guān)系,都是互相成就)。

          4. 標(biāo)準(zhǔn)C庫(kù)及代碼

          C語(yǔ)言及其標(biāo)準(zhǔn)經(jīng)過(guò)若干次迭代之后,就成了今天大家看到的樣子。其標(biāo)準(zhǔn)中指定了很多C標(biāo)準(zhǔn)庫(kù),而不同的系統(tǒng)都有自己不同的代碼實(shí)現(xiàn)。

          當(dāng)然,Linux內(nèi)核中也有實(shí)現(xiàn)了標(biāo)準(zhǔn)C庫(kù)的代碼,下面一起欣賞她的美。

          4.1 標(biāo)準(zhǔn)C庫(kù)

          ANSI C共包括15個(gè)頭文件。1995年,Normative Addendum 1(NA1)批準(zhǔn)了3個(gè)頭文件(iso646.h、wchar.h和wctype.h)增加到C標(biāo)準(zhǔn)函數(shù)庫(kù)中。C99標(biāo)準(zhǔn)增加6個(gè)頭文件(complex.h、fenv.h、inttypes.h、stdbool.h、stdint.h和tgmath.h)。C11標(biāo)準(zhǔn)中又新增了5個(gè)頭文件(stdalign.h、stdatomic.h、stdnoreturn.h、threads.h和uchar.h)。

          至此,C標(biāo)準(zhǔn)函數(shù)庫(kù)共有29個(gè)頭文件:

          https://www.wikiwand.com/zh-sg/C%E6%A8%99%E6%BA%96%E5%87%BD%E5%BC%8F%E5%BA%AB#/%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE

          4.2 linux/lib/string.c

          linux kernel版本:4.18.13

          lnux kernel 地址 https://www.kernel.org/

          下面列出3個(gè)字符串處理函數(shù) strcpy()、strncpy()、strncat()。代碼出自Linus Benedict Torvalds之手,為什么這么說(shuō)?看代碼頭部注釋?zhuān)€是那個(gè)熟悉的味道stupid。看過(guò)git源代碼的人應(yīng)該也會(huì)知道,git源碼中也有類(lèi)似注釋。

          // SPDX-License-Identifier: GPL-2.0
          /*
           *  linux/lib/string.c
           *
           *  Copyright (C) 1991, 1992  Linus Torvalds
           */
          
          /*
           * stupid library routines.. The optimized versions should generally be found
           * as inline code in <asm-xx/string.h>
           *
           * These are buggy as well..
           *
           * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
           * -  Added strsep() which will replace strtok() soon (because strsep() is
           *    reentrant and should be faster). Use only strsep() in new code, please.
           *
           * * Sat Feb 09 2002, Jason Thomas <jason@topic.com.au>,
           *                    Matthew Hawkins <matt@mh.dropbear.id.au>
           * -  Kissed strtok() goodbye
           */
          
          // .......omit other......
          // ...... here is my love code  .....
          
          #ifndef __HAVE_ARCH_STRCPY
          /**
           * strcpy - Copy a %NUL terminated string
           * @dest: Where to copy the string to
           * @src: Where to copy the string from
           */
          #undef strcpy
          char *strcpy(char *dest, const char *src)
          {
           char *tmp = dest;
          
           while ((*dest++ = *src++) != '\0')
            /* nothing */;
           return tmp;
          }
          EXPORT_SYMBOL(strcpy);
          #endif
          
          #ifndef __HAVE_ARCH_STRNCPY
          /**
           * strncpy - Copy a length-limited, C-string
           * @dest: Where to copy the string to
           * @src: Where to copy the string from
           * @count: The maximum number of bytes to copy
           *
           * The result is not %NUL-terminated if the source exceeds
           * @count bytes.
           *
           * In the case where the length of @src is less than  that  of
           * count, the remainder of @dest will be padded with %NUL.
           *
           */
          char *strncpy(char *dest, const char *src, size_t count)
          {
           char *tmp = dest;
          
           while (count) {
            if ((*tmp = *src) != 0)
             src++;
            tmp++;
            count--;
           }
           return dest;
          }
          EXPORT_SYMBOL(strncpy);
          #endif
          
          #ifndef __HAVE_ARCH_STRLCPY
          
          #ifndef __HAVE_ARCH_STRNCAT
          /**
           * strncat - Append a length-limited, C-string to another
           * @dest: The string to be appended to
           * @src: The string to append to it
           * @count: The maximum numbers of bytes to copy
           *
           * Note that in contrast to strncpy(), strncat() ensures the result is
           * terminated.
           */
          char *strncat(char *dest, const char *src, size_t count)
          {
           char *tmp = dest;
          
           if (count) {
            while (*dest)
             dest++;
            while ((*dest++ = *src++) != 0) {
             if (--count == 0) {
              *dest = '\0';
              break;
             }
            }
           }
           return tmp;
          }
          EXPORT_SYMBOL(strncat);
          #endif
          
          #ifndef __HAVE_ARCH_STRLCAT
          
          // .......omit other......
          // ...... here is my love code  .....
          

          第一次跟同學(xué)一起看這些代碼的時(shí)候,他說(shuō)了一句話:這才叫代碼,其他的都是s-h-X-t。現(xiàn)在回想起,自己在實(shí)現(xiàn)這些代碼時(shí),寫(xiě)了一坨不知道是什么的東西。哎,代碼比代碼要扔~

          閱讀他人代碼, 也是一種進(jìn)步、成長(zhǎng)

          5. 廉頗老矣, 尚能飯否?

          《史記·廉頗藺相如列傳》記載,廉頗被免職后,跑到魏國(guó),趙王想再用他,派人去看他的身體情況,廉頗之仇郭開(kāi)賄賂使者,使者看到廉頗,廉頗為之米飯一斗,肉十斤,被甲上馬,以示尚可用。使者回來(lái)報(bào)告趙王說(shuō):"廉頗將軍雖老,尚善飯,然與臣坐,頃之三遺矢(通假字,即屎)矣。"趙王以為廉頗已老,遂不用。

          經(jīng)歷過(guò)幾十年的風(fēng)雨洗禮,C語(yǔ)言可謂風(fēng)光無(wú)數(shù),這世界上隨處可見(jiàn)它的身影。但是,同時(shí)在一些人眼里,可能覺(jué)得C語(yǔ)言已是暮年(將近50歲)、老矣。如同下圖:


          如果你真這樣想,那你就錯(cuò)了。

          TIOBE Index for September 2020

          https://www.tiobe.com/tiobe-index/

          TIOBE 2020-09 編程語(yǔ)言排行榜告訴你,C語(yǔ)言寶刀未老,還是那個(gè)風(fēng)采耀眼的少年。


          個(gè)人想說(shuō)的是,只要計(jì)算機(jī)還是基于馮諾依曼體系結(jié)構(gòu),芯片還是基于物理制程。那么,都會(huì)有一片C的天空。因?yàn)椋酪粋€(gè)最接近天空的地方(C是最接近匯編、機(jī)器語(yǔ)言的高級(jí)語(yǔ)言之一)。

          任他上層應(yīng)用改朝換代,我(C語(yǔ)言)自然不動(dòng)。這就是C,我心中的C語(yǔ)言。

          總結(jié)

          猛然間發(fā)現(xiàn)已經(jīng)到了總結(jié),但是還覺(jué)得仍舊意猶未盡,這并不是我心目中最真實(shí)的那個(gè)她。但是,我還是希望你看完本文之后,能夠多少了解與熟悉C的美與真實(shí)。



          最后想說(shuō)的是:縱使千言萬(wàn)語(yǔ)也說(shuō)不盡C語(yǔ)言的重要性,這些文字也僅僅只是冰山一角。

          鑒于個(gè)人能力有限,如有問(wèn)題或者缺陷,歡迎指正。

          參考資料

          在整理的過(guò)程中,部分參考、引用下面鏈接地址內(nèi)容:

          [1] https://www.bell-labs.com/usr/dmr/www/index.html 里奇貝爾實(shí)驗(yàn)室主頁(yè)

          [2] https://www.bell-labs.com/usr/dmr/www/chist.html C語(yǔ)言發(fā)展史

          [3] https://www.bell-labs.com/usr/dmr/www/1stEdman.html Unix Programmer's Manual

          [4] https://www.bell-labs.com/usr/dmr/www/bcpl.html Martin Richards's BCPL Manual

          [5] https://www.levenez.com/lang/ Computer Languages History

          [6] https://www.levenez.com/unix/ Unix History

          [7] https://minnie.tuhs.org/cgi-bin/utree.pl The Unix Tree(可以看到很多老系統(tǒng)的源代碼)

          [8] https://zh.wikipedia.org/wiki/丹尼斯·里奇

          [9] https://www.tiobe.com/tiobe-index/ TIOBE

          [10] http://web.eah-jena.de/~kleine/history/ Historic Documents in Computer Science


          主站蜘蛛池模板: 国产成人精品亚洲一区| 无码人妻少妇色欲AV一区二区| 美女视频一区二区| 视频一区视频二区在线观看| 免费一区二区无码视频在线播放| 国产成人一区二区三区高清| 日本高清不卡一区| 国产乱子伦一区二区三区| 无码人妻一区二区三区在线视频 | 国产一区二区三区免费在线观看| 精品天海翼一区二区| 色噜噜狠狠一区二区| 国产激情无码一区二区| 亚洲AV无码国产一区二区三区| 成人精品视频一区二区三区| 国产品无码一区二区三区在线| 日本精品高清一区二区| 国产SUV精品一区二区88L| 91精品一区二区三区久久久久| 老湿机一区午夜精品免费福利| 国产一区二区三区免费观在线 | 亚洲国产av一区二区三区| 内射女校花一区二区三区| 无码人妻精品一区二区三18禁| 亚洲AV无码一区东京热| 成人乱码一区二区三区av| av无码人妻一区二区三区牛牛 | 精品国产区一区二区三区在线观看| 成人区人妻精品一区二区不卡| 无码人妻一区二区三区免费| 波多野结衣一区二区三区88| 无码8090精品久久一区| 色婷婷AV一区二区三区浪潮| 无码精品人妻一区二区三区中| 在线视频精品一区| 伊人精品视频一区二区三区| 精品国产一区二区三区| 一本大道东京热无码一区| 成人一区二区三区视频在线观看| 精品视频午夜一区二区| 亚洲日本乱码一区二区在线二产线 |