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

C 語言指針操作中 while 循環條件判斷詳解

     編輯:程式設計綜合問答

代碼上下文

char s[81], *t, *f;
gets(s);            // 讀入字符串 (注意: gets 不安全, 建議用 fgets)
t = f = s;          // t, f 都指向字符串首地址
while (*t) t++;     // 循環結束時, t 指向字符串結束符 '\0'
t--;                // t 回退一步, 指向字符串最後一個有效字符
while (*t == '*') t--; // 從後向前跳過連續的 '*'
while (*f == '*') f++; // 從前向後跳過連續的 '*'
fun(s, f, t);       // 處理去除首尾 '*' 後的子串

逐句解析

`while (*t) t++;`

  • `*t` 解引用獲取當前字符。
  • 在 C 中,字符 `'\\0'` (值 0) 為假,非零字符為真。
  • 循環將 `t` 遞增,直到指向字符串結尾的 `'\0'` 為止。**循環結束後 `t` 指向 `'\0'`**。

`t--;`

  • 將 `t` 向前移動一位,使其指向**字符串最後一個有效字符** (即 `'\0'` 之前的那個字符)。

`while (*t == '*') t--;`

  • **從字符串末尾向前掃描**,只要當前字符是 `'*'`,就繼續向前移動 `t`。
  • 循環結束時,`t` 指向**末尾連續 `'*'` 之前的第一個非 `'*'` 字符**,或者如果整串都是 `'*'`,會越界指向 `s[-1]` (邏輯漏洞,需加邊界判斷 `t >= s`)。
  • 目的:定位 **有效內容的末尾邊界** (去除尾部 `*`)。

`while (*f == '*') f++;`

  • **從字符串開頭向後掃描**,只要當前字符是 `'*'`,就繼續向後移動 `f`。
  • 循環結束時,`f` 指向**開頭連續 `'*'` 之後的第一個非 `'*'` 字符**,或者指向 `'\0'` (全是 `*`)。
  • 目的:定位 **有效內容的起始邊界** (去除頭部 `*`)。

整體功能

**去除字符串首尾連續的 `'*'` 字符**,將剩餘中間部分 (從 `f` 到 `t`,包含 `t`) 傳遞給 `fun` 處理。

例如:`s = "***hello**world***"` → `f` 指向 `h`,`t` 指向 `d` → `fun` 處理 `"hello**world"`。

潛在風險與改進

  1. `gets` 不安全:無緩衝區長度檢查,易導致棧溢出。**必須改用 `fgets(s, sizeof(s), stdin)` 並手動去除換行符**。
  2. 越界風險:若字符串全為 `'*'` 或空串,`t--` 和 `while` 會導致指針越過 `s[0]` 訪問非法內存。
    修正:`while (t >= s && *t == '*') t--;` 及 `while (f <= t && *f == '*') f++;` (假設 `f` 初始 `= s`)。
  3. 參數傳遞:`fun(s, f, t)` 傳遞的是指針值,`fun` 內部可直接修改原數組內容。

修正版核心邏輯

fgets(s, sizeof(s), stdin);
s[strcspn(s, "\n")] = 0; // 去除 fgets 讀入的換行符

char *t = s, *f = s;
// 找尾部
while (*t) t++;
if (t > s) t--; // 非空串才回退
while (t >= f && *t == '*') t--; // 含邊界檢查

// 找頭部
while (f <= t && *f == '*') f++; // 含邊界檢查

if (f <= t) {
    fun(s, f, t); // 有有效內容
} else {
    // 全是 * 或空串
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved