簡體   English   中英

在嵌套的 while 循環中重新測試 while 循環條件

[英]Retesting while loop condition inside a nested while loop

在這個程序中我真的不明白為什么我們在嵌套的 while 循環中測試第一個 while 循環的條件 1

該程序是說一個字符串中有多少個單詞,單詞之間用空格分隔

這是代碼:

int count_words(char *ch){
    int c = 0;
    while(*ch!='\0'){
        if(*ch==' '){
            ch++;
            continue;
        }
        c++;
        while(*ch && *ch !=' '){
            ch++;
        }
    }
    return c;
}

我不明白的是為什么條件 1 是: (*ch.='\0') 在第一個 while 循環中在第二個 while 循環中再次測試。

我是否總是必須在嵌套的 while 循環中測試返回條件? 還是有什么地方我沒有把握好?

謝謝

第一個測試是跳過單詞之間的所有空格。 它在到達第一個非空格時停止,即單詞的開頭

內部 while 循環用於跳過字符,直到我們到達下一個空格,因此它找到了該單詞的結尾

請注意,這兩個條件是相反的。 第一個是*ch == ' ' ,第二個是*ch != ' '

*ch != '\0'*ch &&用於在我們到達字符串末尾時停止(C 字符串以零字節結尾)。 在遍歷字符串的任何循環中都需要這樣做,這樣它就不會超出結尾 go 。

我不明白的是為什么條件 1 是: (*ch.='\0') 在第一個 while 循環中在第二個 while 循環中再次測試。

我將在這里重點介紹一些重要的細節:

while(*ch!='\0') {
    if(*ch==' ') {
        ch++;                  // 1.
        continue;
    }
    c++;
    while(*ch && *ch !=' ') {
        ch++;                  // 2.
    }
}

12中, char* ch增加 1,這使得ch指向一個新地址——內容未知。

當再次到達while循環的開始時,它會測試ch指向的內容是否包含表示字符串結尾的空終止符。 如果是,則循環結束——因為隨后將對字符串進行全面檢查。

因此, while(*ch!='\0')不會一遍又一遍地測試同一件事。 ch在每次循環后指向一個新的char

您在內循環中進行了相同的測試:

    while(*ch && *ch !=' '){    // <-here
        ch++;
    }

在這里, *ch正在做同樣的測試, *ch != '\0' ,但沒有那么多單詞。

  • \0是空終止符的正確字符文字。
  • 空終止符的實際值為0
  • 在 boolean 上下文中, 0的計算結果為false ,其他所有內容的計算結果為true
  • 因此, *ch等於*ch != '\0'在 boolean 上下文中

這個問題說明了為什么在我看來,將事物分解成具有有意義名稱的函數如此重要。

比方說,我們想要將字符串推進到前導空白字符之后。 我們可以創建一個 function ,它接受一個字符串 ( char * ),創建一個指向它開頭的指針,遞增該指針直到它遇到一個不是空格、制表符或換行符的字符,然后返回該指針。

char * first_nonspace(char * s) {
    char * iter = s;

    for (; *iter && (*iter == ' ' || *iter == '\t' || *iter == '\n'); 
           iter++);

    return iter;
}

以同樣的方式,可以使 function 跳到下一個空白字符。

char * first_space(char * s) {
    char * iter = s;

    for (; *iter && !(*iter == ' ' || *iter == '\t' || *iter == '\n'); 
           iter++);

    return iter;
}

現在計算單詞就簡單多了。 我們的 for 循環甚至不需要主體。 它以iter開始,指向字符串的第一個字符,並將count設置為零。 當我們沒有遇到 null 字符,並且第一個非空格字符不是 null 時,它會繼續。

每次我們通過獲取第一個非空格字符進行更新,然后從該指針前進到第一個空格。 這有效地迭代了一個“詞”。 同時,我們通過將計數遞增 1 來更新計數。

int main() {
    char * test = "     hello world foo bar      ";
    char * iter;
    int count;

    for (iter = test, count = 0; 
         *iter && *first_nonspace(iter); 
         iter = first_space(first_nonspace(iter)), count++);
    
    printf("Found %d words.\n", count);
} 

將大問題分解成小問題非常有助於理解正在發生的事情。 我所描述的是在您的程序中發生的相同邏輯(盡管我添加了處理制表符和換行符)但是在具有更有用名稱的可管理塊中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM