<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 注釋符 `#`?符號是行注釋符。不過,與我們所熟悉的注釋文本不同,m4 的注釋文本會被發送到輸出流。例如: ~~~ define(`VERSION',`A1') VERSION # VERSION `quote' unmatched` ~~~ 會被展開為: ~~~ A1 # VERSION `quote' unmatched` ~~~ 可以用?`changecom`?宏修改 m4 默認的注釋符,例如 ~~~ changecom(`@@') ~~~ 這樣,`@@`?就變成了注釋符。 如果你需要塊注釋符,也可以做到,例如: ~~~ changecom(/*,*/) ~~~ 如果不向?`changecom`?提供任何參數,其他 m4 實現會恢復默認的注釋符,但是 GNU m4 不會恢復默認的注釋符,而是關閉m4 的注釋功能。如果要恢復默認的注釋符,必須這樣: ~~~ changecom(`#') ~~~ 如果不希望 m4 回顯注釋文本,可以用?`dnl`?宏替換注釋符,例如: ~~~ define(`VERSION',`A1') VERSION dnl VERSION `quote' unmatched` ~~~ `dnl`?會將其后的內容一直連同行尾的換行符統統干掉。 如果讓塊注釋文本不回顯,需要基于條件語句進行一些 hack。不過,由于注釋這種東西并沒有存在的必要,所以就不再理睬它了。之所以說,注釋不重要,是因為我們有更強大的注釋機制——[文式編程](http://segmentfault.com/a/1190000004011686)! ## 引號,逃逸以及非 ASCII 字符 m4 有一個不足之處,它沒有專用的逃逸符。對于非引號字符的字符,引號總是可以作為逃逸符使用。但是,怎么對引號本身進行逃逸呢?畢竟很多場合需要左引號字符作為普通字符出現。 > 事實上,這篇文檔是用 Markdown 標記寫的,我也無法將左引號符號以 Markdown 行內代碼標記表現出來。 雖然可以在引號的外層再封裝一層引號從而將前者變為普通字符,例如: ~~~ I said, ``Quote me.'' # -> I said, `Quote me.' ~~~ 但是,有些時候你只想以普通文本的形式顯示左引號,不希望出現一個與之配對的右引號。對于這個問題,可以使用`changequote`?宏修改 m4 默認的引號定界符,例如: ~~~ changequote(<!,!>) a `quoted string ~~~ m4 會將其處理為: ~~~ a `quoted string ~~~ 因為此時,真正的引號是?`<!`?與?`!>`。 如果不向?`changequote`?提供任何參數,就恢復了默認的引號定界符。例如: ~~~ changequote(<!,!>)dnl a `quoted string changequote`'dnl a `quoted string' ~~~ m4 的處理結果為: ~~~ a `quoted string a quoted string ~~~ 一般情況下,應該避免使用?`changequote`,而是將引號字符定義為宏: ~~~ define(`LQ', `changequote(<,>)`dnl' changequote`'') define(`RQ',`changequote(<,>)dnl` 'changequote`'') ~~~ m4 遇到?`LQ`?宏將其展開為「`」字符,遇到?`RQ`?宏就將其展開為「'」字符。這兩個宏的定義所體現的技巧是,臨時的改變 m4 默認的引號定界符,然后再改回來。 不過,有時候需要全局性的修改 m4 的默認引號定界符,例如有些鍵盤上沒有「`」字符,或者 m4 要處理的文本必須將「`」字符視為普通字符。使用?`changequote`?一定要小心陷阱:GNU m4 提供的?`changequote`?與其早期版本以及 m4 的其他實現有區別。 為了可移植,要么向?`changequote`?提供 2 個參數來調用它,要么就不提供任何參數,例如: ~~~ changequote ~~~ `changequoe`?會改變宏的定義,例如: ~~~ define(x,``xyz'') x # -> xyz changequote({,}) x # -> `xyz' ~~~ 不要用同樣的字符作為引號的定界符,這樣做,就無法進行引號的嵌套了。 > Markdown 用于格式化行內代碼的標記用的就是相同的『左引號』與『右引號』……這樣的錯誤,誕生于上個世紀 70 年代的 m4 沒有犯。 不要將引號定界符更改為以字母、下劃線或數字開頭的字符。m4 雖然不反對這樣做,但是它不認為這種字符是引號定界符。數字作為引號定界符,雖然可以被 m4 認可,但是當它作為一個記號本身的組成元素時,它就失去了引號定界符的身份了。 現在的 GNU m4 可以支持非 ASCII 字符,因此也可以用它們來作為引號定界符,例如: ~~~ changequote(左引號, 右引號) a 左引號quoted string右引號 # -> a quoted string define(我是宏, 我知道你是宏) 我是宏 ~~~ 但是最好不要這么干,特別是不要將它們用于宏名。因為,使用 8 位寬的字符,就已經讓 m4 行為有些怪異了。GNU m4 1.4.17 版本(本文寫作過程中所用的 m4 版本)的手冊中說:GNU m4 不理解多字節文本,它只是將文本視為以字節為單位的數據,并且支持 8 位寬的字符作為宏名與引號定界符,但?`NUL`?字符(即?`'\0'`)除外。 m4 能處理中文,這是一種巧合。這種巧合應該只發生在 UTF-8 編碼的輸入流中。因為 UTF-8 的編碼機制決定了中文字符的任何一個字節都與 ASCII 碼不同。如果是 GB2312,GB18030 這樣的字符集,或許就沒有這么好的運氣了。 ## 條件 m4 提供了兩種條件宏,`ifdef`?宏用于判斷宏是否定義,`ifelse`?宏是判斷表達式的真假。 ~~~ ifdef(`a', b) ~~~ 對于上述條件宏,如果?`a`?是已定義的宏,那么這條語句的展開結果是?`b`。 ~~~ ifdef(`a', b, c) ~~~ 對于上述條件宏,如果?`a`?是未定義的宏,這條語句的展開結果是?`c`。 被測試的宏,它的定義可以是空字串,例如: ~~~ define(`def') `def' is ifdef(`def', , not) defined. # -> def is defined. ~~~ `ifelse(a,b,c,d)`?會比較字符串?`a`?與?`b`?是否相同,如果它們相同,這條語句的展開結果是字符串?`c`,否則展開為字符串`d`。 `ifelse`?可以支持多個分支,例如: ~~~ ifelse(a,b,c,d,e,f,g) ~~~ 它等價于: ~~~ ifelse(a,b,c,ifelse(d,e,f,g)) ~~~ ## 數字 m4 只認識文本,所以在它看來,數字也是文本。不過 m4 提供了內建宏?`eval`,這個宏可以對整型數的運算表達式進行『求值』——求值結果在 m4 看來依然是文本。 例如: ~~~ define(`n', 1)dnl `n' is ifelse(eval(n < 2), 1, less than, eval(n == 2), 1, , greater than) 2 ~~~ `eval(n < 2)`?是對?`n < 2`?這個邏輯表達式進行『求值』,結果是字符串?`1`,因此?`ifelse`?的第一個參數與第二個參數相等,因此?`ifelse`?宏的展開結果是其第三個參數?`less than`,所以展開結果為: ~~~ n is less than 2 ~~~ 我覺得沒必要用 m4 來計算,因為它提供的計算功能太孱弱。可以考慮用 GNU bc 來彌補它的不足。在 m4 中,可以通過`esyscmd`?宏訪問 Shell,例如: ~~~ 2.1 ifelse(eval(esyscmd(`echo "2.1 > 2.0" | bc')), 1, `greater than', `less than') 2.0 ~~~ 展開結果為: ~~~ 2.1 greater than 2.0 ~~~ 不過,`esyscmd`?是 GNU m4 對?`syscmd`?的擴展,別的 m4 的實現可能沒有這個宏。 ## 挑戰 (1) 如果用 m4 處理 C 代碼文件,將?`#`?符號作為 m4 的行注釋符,會有哪些顯而易見的好處? (2) 借助 GNU m4 提供的?`esyscmd`?宏,結合 GNU bc,寫一個可以計算數字平方根的的宏。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看