2012-09-30 52 views
0

我通常理解遞歸得很好,但因爲我是新來的C函數像strcpy和指針我無法弄清楚這個遞歸如何逆轉的字符串:這個字符串如何反向遞歸工作?

char *reverse(char *string) 
{ 
    if (strlen(string) <= 1) 
     return string; 

    else 
    { 
     char temp = *string; 

     strcpy(string, reverse(string+1)); 

     *(string+strlen(string)) = temp; 

     return string; 
    } 
} 

strcpy部分似乎有點複雜對我來說,這條線的目的是什麼:
*(string+strlen(string)) = temp;

我意識到,翻轉字符串後,你需要添加字符在開始到字符串結束,但我不知道我明白這個代碼背後的邏輯。

+0

這裏的strcpy()是危險的,因爲目標和源可以重疊。 Memmove()將是適當的。 (但很難得到正確的) – wildplasser

回答

2

此代碼是非常低效的,但它的作用是:

  1. 保存原來的第一個字符
  2. 遞歸扭轉字符串的其餘部分(string+1是指向字符串中的第二個字符)。
  3. 將剩下的(反轉)字符串複製一個字符向左。
  4. 將最初的第一個字符放在末尾(*(string+strlen(string)) = temp;)。

*(string+strlen(string)) = temp;相當於string[strlen(string)] = temp;如果這更容易理解。

我不會推薦使用這個代碼,因爲它效率極低 - 它在每次迭代中複製整個字符串(並測量其長度兩次),更不用說浪費堆棧空間了。

一個更好的實現是:

void reverse(char *s) { 
    char *e = s+strlen(s)-1; 
    while (e > s) { 
    char tmp = *s; 
    *s=*e; 
    *e=tmp; 
    s++; e--: 
    } 
} 
+0

但是,如果我發送一個指向「ABC」的指針,那麼在'string'指向「BC」之後,它將改爲CC - 「string + strlen(string)」指向零終止符,不是嗎?不應該是'string + strlen(string)-1'? – tempy

+0

是的,除了'strcpy'還複製了空終止符,將它移回到一個地方,縮短了字符串。再次,非常危險且效率低下。 – epsalon

+0

謝謝你的幫助;你添加的實現對我來說更有意義。 – tempy

0

*(string+strlen(string)) = temp是所謂的指針算術 - 該代碼相當於string[strlen(string)] = temp。因此,這將temp字符放到字符串的末尾。請注意,該字符串仍然保持零終止,因爲reverse()返回與其參數長度相同的字符串。

reverse(string+1)再次指針運算,此時相同reverse(&string[1]) - 即反向()將從第二字符起鏡像串,但隨後的strcpy()將其放置在開始時字符串,覆蓋存儲在temp temp中的第一個字符並放在字符串的末尾。

但是,整體代碼看起來不必要的複雜和低效,所以我在考慮如何從中完成任何課程之前會考慮三次。

+0

謝謝你的幫助。這令我感到意外,因爲這是來自Microsoft編寫的C編程手冊的練習。 – tempy

0

這是代碼是如何工作的。輸入字符串分爲兩部分,第一個字符爲 ,其餘部分爲。第一個字符存儲在temp, 中,其餘部分通過遞歸調用進行反轉。遞歸調用的結果放在結果的開頭,並且temp中的字符被放置在結尾。

string is [1234567890]

temp is 1, string+1 is [234567890]

reverse(string+1) is [098765432], temp is 1

strcopy線是一部分拷貝從reverse(string+1)string開始,*(string+strlen(string)) = temp結果是一部分拷貝tempstring結束。

+0

感謝您的解釋 – tempy