簡體   English   中英

C中strcat函數的遞歸實現

[英]Recursive implementation of strcat function in C

我正在執行中 在C. strcat的功能,我無法理解他們是如何與指針一起使用遞歸

以下是該來源的代碼段。

char dest[100] = "I love";
char *src = "food";`

/* my_strcat(dest, src) copies data of src to dest. */
void my_strcat(char *dest, char *src)
{
  (*dest)? my_strcat(++dest, src): (*dest++ = *src++)? my_strcat(dest, src): 0 ;
}

分成幾部分:

(*dest) /* Is *dest different than '\0' ? */
   ? my_strcat(++dest, src) /* *dest is different than '\0', so increment dest pointer so it'll point to the next character and call my_strcat() again. Here we're searching for the end of the string dest. */

   : (*dest++ = *src++) /* *dest is equal to '\0', so we're at the end of *dest... We start to assign *src to *dest and increment both pointers to point to the next character. The lvalue of this assignment is also a comparison (is it different than '\0' ?). */

     ? my_strcat(dest, src) /* The previous comparison is different than '\0', so we'll call my_strcat() again (pointers have already been incremented and they now point to the next character) */

     : 0; /* The previous comparison is '\0', so we've reached the end of the src, so we're done. */

用if / else代替三元運算符:

/* Is *dest different than '\0' ? */
if (*dest != '\0') {
  /* *dest is different than '\0', so increment dest pointer so it'll point to the next character and call my_strcat() again. Here we're searching for the end of the string dest. */
  my_strcat(++dest, src);
} else {
  /* *dest is equal to '\0', so we're at the end of *dest... We start to assign *src to *dest and increment both pointers to point to the next character. The lvalue of this assignment is also a comparison (is it different than '\0' ?). */
  if ((*dest = *src) != '\0') {
    /* The previous comparison is different than '\0', so we'll call my_strcat() again (pointers have already been incremented and they now point to the next character) */
    my_strcat(++ dest, ++ src); /* Moved increments down for readability */
  } else {
     /* The previous comparison is '\0', so we've reached the end of the src, so we're done. */
    return; 
  }
}

如果/沒有其他注釋(也許更具可讀性):

if (*dest != '\0') {
  my_strcat(++dest, src);
} else {
  if ((*dest = *src) != '\0') {
    my_strcat(++ dest, ++ src);
  } else {
    return; 
  }
}

這是一個很差的實現,但是我想它確實起作用。 第一個?:測試目標字符串是否在結尾。 如果不是,它將碰撞目標指針,然后遞歸調用自身。 如果目標已經在末尾,則它將復制一個字符,同時碰觸兩個指針並測試零。 如果那不是來自src的尾隨NUL ,則它將使用更新的指針遞歸調用自身。

哦,等等,有一個錯誤(或者可能是一個“功能”)。 假定dest末尾的所有字符最初都用NUL填充。 我猜您實際上可以利用這一點,如果您可以繼續依賴該實現並擁有一個dest字符串,該字符串的文本中插入NUL字符,那么它將一次用一個字符填充src中的NUL

更不用說過度使用遞歸了,這意味着堆棧中的調用框架與結果字符串中包含的字符一樣多。 您從哪里獲得了這種愚蠢的strcat實現? 當然,沒有真正的庫會使用此實現,迭代變體既易於理解,又快得多。

暫無
暫無

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

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