首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

K&R C 語言練習 2-3:註釋過濾器中 in_quote 狀態機制詳解

     編輯:程式設計綜合問答

代碼片段

if (line[t] == '"')
    in_quote = 1;

if (!in_quote) {
    // 處理註釋 /* ... */
} else {
    // 在引號內,直接輸出字符
    printf("%c", line[t]);
    t++;
}

問題

作者如何確保後續 if (!in_quote) 正確判斷當前字符是否在雙引號內?

狀態機邏輯

  1. in_quote 初始為 0(不在引號內)。
  2. 遍歷每行字符:
while (t < len) {
    if (line[t] == '"')        // 遇到雙引號
        in_quote = 1;          // 標記進入引號區域
    
    if (!in_quote) {           // 不在引號內
        // 檢測 /* 和 */ 切換 in_comment
        // 若 in_comment 輸出空格,否則輸出字符
    } else {                   // 在引號內
        // 直接輸出字符,不處理註釋符號
        printf("%c", line[t]);
    }
    t++;
}

關鍵點

  • 單字符觸發:只檢測 line[t] == '"',不區分左/右引號,假設引號成對且不嵌套(C 語言字符串字面量不允許嵌套雙引號)。
  • 狀態持久:in_quote 一旦置 1,後續所有字符進入 else 分支,直到行結束(或遇到下一個雙引號?代碼中未處理結束引號,這是簡化版缺陷)。
  • 行級重置:外層 while ((len = getline()) > 0) 每行開始前 in_quote = 0,假設字符串不跨行(K&R 練習簡化假設)。

完整邏輯流程圖

字符 '"'
    ↓
in_quote = 1
    ↓
後續字符進入 else 分支 → 直接輸出
    ↓
遇到換行/行結束 → 外層循環重置 in_quote = 0

缺陷與改進

原代碼無法處理字符串中的結束雙引號(如 "hello "world"" 或 "abc" def),實際編譯器需更複雜狀態機(轉義字符、字符常量、多行字符串)。練習旨在理解狀態變量控制處理邏輯的基本思想。

總結

in_quote 作為標誌變量,在遇到 " 時置 1,標記後續字符處於「字符串字面量」上下文中,從而跳過註釋檢測邏輯。這是編譯器詞法分析中「狀態機」的最簡雛形。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved