2016-12-01 80 views
2

我想了解以下代碼示例指針程序的片段,不知道是否有可能問這些問題,如果不是,我會刪除!瞭解複雜的指針示例代碼C

void f1(char *s) { 
    char *p, *q; 
    for (p=q=s; *p != '\0'; p++) { 
     if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')) 
      *q++ = *p; 
     else if (q > s && *(q-1) != '\n') 
      *q++ = '\n'; 
    } 
    *q = '\0'; 
} 

我知道有三個指針P,S和Q,但我不知道是什麼p=q=s限嗣繼承?是否檢查指針p和q是否在char a-z之間(其中一個是小寫字母,另一個是大寫字母)並遍歷字母?

任何幫助,將不勝感激!

+0

DO(循環,這WHE這裏不做的突破時除外)你知道你使用'''而不是''來表示字符嗎? – mch

+0

是的,抱歉。那是我教授在幻燈片中的榜樣。我會改變它。 – Nuggets10

+0

你應該學會使用調試器。用幾個隨機字符串測試代碼並在運行時進行調試。這應該讓你對代碼的實際操作有所瞭解。 –

回答

0

如果我們看一下for (p=q=s; *p != '\0'; p++)這個基本意思是for循環開始之前,設置p = sq = s。在C語言中,這意味着p,q和s最初設置爲等於相同的字符串(或者更具體地說,指向相同的地址)

3

回答您的問題,如果字符不是一封信,它也將令牌集中在一起,如果它位於第一行,則不會剝離,但最後不會放到一條換行符。

評論它:

void f1(char *s) { 
    /* Two pointers, q for writing and p for reading */ 
    char *p, *q; 

    /* Initialize both at the beginning and start looping the input string */ 
    for (p=q=s; *p != '\0'; p++) { 
     /* If it is a letter, just keep it */ 
     if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')) 
      *q++ = *p; 
     /* If not, increment the write pointer only if the last 
      is not a newline with boundary check */ 
     else if (q > s && *(q-1) != '\n') 
      *q++ = '\n'; 
    } 
    *q = '\0'; 
} 

如果你輸入:

char var [] = " THIS.is a STRING\n" 
       "with two lines..."; 

這將導致:

THIS 
is 
a 
STRING 
with 
two 
lines 
/*with one newline at the end */ 
+0

嗨,感謝您編寫示例代碼來測試它!我只是使用例子blah2blah4在筆和紙上做了一些步驟,然後用它來標記等等等等(儘管這很有道理),但你的解釋要好得多!欣賞它。 :)我不確定換行符是否打算或者不是LOL。 – Nuggets10

+0

原來的代碼真的讓人困惑,呃? – bipll

+0

@bipll哈哈哈......這可以是一個無符號的長長整型討論。 –

0

使用索引來代替指針一個版本:

void f1(char *buf) { 
    size_t src, dst; 
    for (src=dst=0; buf[src]; src++) { 
     if ((buf[src] >= 'A' && buf[src] <= 'Z') || (buf[src] >= 'a' && buf[src] <= 'z')) 
      buf[dst++] = buf[src]; 
     else if (dst && buf[dst-1] != '\n') 
      buf[dst++] = '\n'; 
    } 
    *q = '\0'; 
} 

而且在Kernighan的風格相同:

void f1(char *buf) { 
    size_t src, dst; 
    for (src=dst=0; buf[dst] = buf[src]; src++) { 
     if (buf[src] >= 'A' && buf[src] <= 'Z' || buf[src] >= 'a' && buf[src] <= 'z') 
      { dst++; continue; } 
     if (dst && buf[dst-1] != '\n') 
      { buf[dst++] = '\n'; } 
    } 
} 

注:Kernighan的風格有一個很好的特性:在

for (src=dst=0; buf[dst] = buf[src]; src++) {...} 

保證 '\ 0'將被寫入循環結束後的目的地。所以,不可能忘記它。


(當然真正 Kernighan的風格將使用指針,一個字母的變量;-)