如何实现这个递归线来打印字符串?

时间:2017-09-06 09:52:22

标签: c recursion

很快,我需要知道这个功能是如何工作的?什么进去?传递的字符串是如何反转的?

以下是代码并提前致谢。

#include <stdio.h>
void rev (const char* const);

int main()
{
    char str [] = "Hey There";
    rev(str);

    return 0;
}

void rev(const char* const c)
{
    if(c[0]=='\0')
        return ;
    else
    {
        rev( &c[1]);
        putchar(c[0]);
    }
}

编辑:正如评论者所建议的那样,我将解释我不理解的内容。字符串不反转,但反向打印,好的。这样做的机制是什么?什么是执行顺序?

5 个答案:

答案 0 :(得分:1)

原因是代码在处理输出当前char之前指示它执行字符串的其余部分。想象一下#0&#34;

上的字符串&#34;
rev("on\0");
  ->rev("n\0");
    ->rev("\0");  
      <-return;   // hits base case
    putchar('n'); // resumes after recursive call
    <-return;     // invisible return at end of function
  putchar('o');   // resumes after recursive call
  <-return;       // invisible return at end of function

此处的每个标识代表一个嵌套调用。因此,在基本情况下,您可以同时拨打rev 3个电话,每个电话都有不同的c

了解c对于每次调用都是唯一的,这一点很重要,因为当rev的调用返回到之前的rev c时在被叫方中未更改。这使它没什么特别的,所以事实上它的工作方式与每次执行相同操作时调用不同的函数的方式相同。它在前一次调用返回后恢复。

答案 1 :(得分:0)

实际上这个递归函数并没有反转输入字符串。它只是按相反的顺序打印。 逻辑很简单 - 假设我有字符串str [4] =&#34; ABC&#34;这是C中的空终止字符串。

  • 首次致电rev(str) - str [0]是&#39; A&#39;这不是null - &gt;调用rev(str [1])并打印str [0] =&#39; A&#39;
  • 第二次调用rev() str [0]是&#39; B&#39;这不是null - &gt;调用rev(str [1])并打印str [0] =&#39; B&#39;
  • 依此类推,直到&#39; \ 0&#39;找到了。

现在在从每个函数调用返回之前,它是打印str [0] -

  • 所以对于&#39; \ 0&#39; - 它只会返回而不打印任何东西。
  • 对于&#39; C&#39;,它会打印&#39; C&#39;
  • 对于&#39; B&#39;,它会打印&#39; B&#39; 等等。

因此字符串将以相反的顺序打印。

答案 2 :(得分:0)

根据您的计划,** H e y t e e e **,在rev功能中,

  1. c [0] = H 被检查为NULL或不是==&gt; NO
  2. 传递地址&amp; c [1] =&#34; ey那里&#34; e 再次到rev功能。
  3. c [0] = e 被检查为NULL或不是==&gt; NO
  4. 传递地址&amp; c [1] =&#34; y&#34; y 开始再次转到rev功能。
  5. 这种逻辑一直持续到最后。
  6. c [0] = e 被检查为NULL或不是==&gt; NO
  7. 传递地址&amp; c [1] = \ 0 ,这是要传递给rev功能的NULL字符。
  8. 一旦确定 \ 0 ,rev函数就会开始返回。
  9. 在rev函数之后,我们有 putchar(c [0]),它将c [0]的最新值打印为&#39; e&#39; [按照第6点]。
  10. 打印继续 e h h H H /

答案 3 :(得分:0)

要使函数的操作更清晰,请按以下方式重写

String selctedItemPAV = indextostring(jComboBox1.getSelectedIndex()); 
       String selctedItemCH = jList1.getSelectedValue();
       String Query =" SELECT * FROM etudiant_pav WHERE PAVILLONS = ? AND CHAMBRE = ? " ;
       rst = theSelectQuery(Query,selctedItemPAV ,selctedItemCH); //this is the posted function 
         DefaultListModel listModel = new DefaultListModel();
         jList3.setModel(listModel);
         System.out.println (selctedItemCH + "  doppppppppp  " +selctedItemPAV + jComboBox1.getSelectedIndex());

          System.out.println ("doppppppppp222222222");
     if (rst.isBeforeFirst())
     {
          System.out.println ("ttttttttttttttttttttttttttttttttttttttttttttt");    //the excution stops here in application.....
         jList3.setEnabled(true);
         listModel.clear();
         jLabel1.setVisible(false);
        while (rst.next()) 
        {
             String aff="hhh";
             aff= rst.getString("NOM_PRENOM");
             System.out.println ("dooooooooo"+aff);
            listModel.addElement(aff);
         }
        }
     else 
     {
         jLabel1.setVisible(false);
          jList3.setEnabled(false);
        JOptionPane.showMessageDialog(null, "la chambre est vide ");
     }

     rst.close();
  }
  catch (Exception ex){
  }

因此,对于函数的第一次调用,函数将字符串的第一个字符存储在变量void rev( const char * const s ) { if ( s[0] != '\0' ) { char c = s[0]; rev( s + 1 ); putchar( c ); } } 中。

然后在第二次将指针移动到第二个字符时调用该函数。该函数再次将此字符存储在其自己的(本地)变量c中。

依此类推,直到遇到终止零。

然后,在将控件传递给调用调用之前的每个函数调用都会打印存储在变量c中的字符,并且您将获得字符串字符的相反顺序。

答案 4 :(得分:-1)

正如您所提到的,它是一个递归函数。所以执行就像这样

从main()调用rec()。控件现在进入rec()函数。在进行条件检查以检测字符串结束的位置。在检测到字符串结束之前,其他部分都会被执行。

现在让我们看看其他部分会发生什么。

else再次致电rec()。再次调用rec()直到满足字符串结尾的位置。

所以呼叫顺序就像这样 - &gt;

main()-> rec()->rec(rec(rec(... until \0..) putchar()) putchar())putchar())

因此,在上一个rec()函数的控制结束时,将执行最后putchar()。然后在最后一个开始之前继续,直到从rec()调用的第一个main()

main() - &GT; rec(H)因为它不是空的 - &gt;它再次调用rec(e)

此处控件尚未出现在rec()的第一次调用中。所以rec(H)看起来像

rec(H)
{
rec(e);
putchar(H);
}

它继续像这样