编写一个以数组和数组大小为参数的递归函数,打印该数组,不返回任何内容 [英] Writing a recursive function that takes an array and the size of the array as arguments, prints the array, and returns nothing

查看:52
本文介绍了编写一个以数组和数组大小为参数的递归函数,打印该数组,不返回任何内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对编程非常陌生(自8月以来),而递归是我的致命弱点.问题是这样的:编写一个递归函数 printArray(),该函数将一个数组和该数组的大小作为参数,打印该数组,但不返回任何内容.该函数应停止处理并在收到大小为零的数组时返回.

那么仅此功能就是这样吗?:

  void printArray(int arr [],int SIZE){int计数器= 0;如果(SIZE == 0){返回-1;}否则(SIZE> 0){printf(%d",arr [counter]);计数器++;printArray(arr,SIZE-1);}puts(");} 

老实说,我在这里抓稻草,所以请原谅我可能会遇到的手掌,因为我正在查看无数的代码,然后尝试将其中的一些代码拼凑起来,看看它是否可以以任何方式帮助我.当将其实现为 main()时,是否应该初始化其他变量?主要是一个新数组,我在函数参数中的 arr [] 中放置的任何内容都超出了范围.

解决方案

尽管递归调用"wind-in" 来跟踪程序的执行路径,但递归函数还是需要一些思考,然后在递归被破坏并且每个递归函数调用完成后展开" .例如,以以下简单情况为例:

  void prnarray(int * arr,int nelem){如果(--nelem> 0)/*缠绕(两次)直到nelem == 0 */prnarray(arr,nelem);printf(%d \ n",arr [nelem]);/*展开输出元素*/} 

(其中 nelem 是数组中的元素数,从技术上讲不是其大小" [除非它是 char 的数组)]

了解使用以下函数调用该函数会发生什么情况:

  int main(void){int arr [] = {1,2,3},nelem = sizeof arr/sizeof * arr;prnarray(arr,nelem);} 

最简单的方法就是用 nelem 的值创建一个表.例如:

卷入

  • nelem == 3 :

来自 main()

的初始调用

  prnarray(arr,nelem); 

然后在第一个函数调用中,-nelem nelem 的值减小 1 ,然后再由 if求值.().

  • nelem == 2 :

if()语句之后,执行路径为:

 如果(--nelem> 0)/*缠绕(两次)直到nelem == 0 */prnarray(arr,nelem); 

  • nelem == 1 :

然后在-nelem nelem == 1 之后的下一个调用中:

 如果(--nelem> 0)/*缠绕(两次)直到nelem == 0 */prnarray(arr,nelem); 

  • nelem == 0

然后在下一个调用(最后一个递归调用)中命中基本情况,因为在-nelem nelem == 0 之后,测试条件失败,并且执行路径继续:

  printf(%d \ n",arr [nelem]);/*展开输出元素*/ 

(此处打印第一个元素"1")

放卷

现在会发生什么??我们已经到达函数的末尾了?

执行将在导致这一点的函数调用之后执行.那是什么?导致这一点的函数调用是对 prnarray()的递归调用,这导致我们进入了此函数的主体.

(每个函数调用在后台将基本指针地址保存在函数堆栈中,因此当函数执行完成时,它知道在调用函数中从何处恢复执行.)

  • nelem == 1

因此,当执行 nelem == 0 的函数的执行结束时,我们将从函数调用中 nelem == 1 结束的地方开始-从先前对 prnarray()的调用返回如果我们查看整个函数,其中函数入口上的 nelem == 1 ( nelem == 2 ),我们在上一次调用 prnarray()后在接收区中接听了

  void prnarray(int * arr,int nelem){如果(--nelem> 0)/*缠绕(两次)直到nelem == 0 */+< ----- prnarray(arr,nelem);|+-> printf(%d \ n",arr [nelem]);/*展开输出元素*/} 

(此处显示值为 2 的第二个元素)

因此,在先前的 prnarray()展开后,执行路径中剩下的唯一命令是 printf()和第二个元素 2 将被打印,函数结束并再次展开,结果相同:

  • nelem == 2

(在该函数进入时为 3 )执行路径为 printf()函数

  printf(%d \ n",arr [nelem]);/*展开输出元素*/ 

(第三个也是最后一个值为 3 的元素在这里打印)

  • nelem == 3

是从 main()进行的原始函数调用,因此现在展开已完成,并且在调用以下代码后,程序在 main()中执行:

  prnarray(arr,nelem); 

程序结束....

仔细研究递归函数程序的执行路径并创建表是一种熟悉递归函数调用的好方法.(即使您对它们感到满意,当您使用函数在函数主体中进行两个或多个递归调用时,您也将回到创建表并跟踪执行路径的方式).程序执行路径中的分支带有多个递归调用,这些递归调用分别递归函数,这些分支似乎将以指数复杂度扩展.

有了这些信息,您现在应该可以调整功能并知道在哪里寻找结果.如果您还有其他问题,请告诉我.

I'm very new to programming (since August) and recursion is my Achilles heel. The question is this: Write a recursive function printArray() that takes an array and the size of the array as arguments, prints the array, and returns nothing. The function should stop processing and return when it receives an array of size zero.

So the function alone would be something like this?:

void printArray(int arr[], int SIZE) {
 
  int counter = 0;

  if (SIZE == 0) {
    return -1;
  }
  else if (SIZE > 0) {
      printf("%d", arr[counter]);
      counter++;
      printArray(arr, SIZE - 1);
  }
  puts("");
}

I'm honestly grasping at straws here so excuse the facepalms I may cause as I am looking at countless of codes and trying to piece some of them together and see if it can help me in any way. And when implementing it into main(), should I initialize additional variables? Mainly a new array seeing as anything I place in arr[] within the function parameter is out of scope.

解决方案

Recursive functions take a bit of thinking though to trace the program execution-path as the recursive calls "wind-in", and then "unwinds" after the recursion is broken and each recursive function call completes. For example take the simple case of:

void prnarray (int *arr, int nelem)
{
    if (--nelem > 0)                    /* wind-in (twice) until nelem == 0 */
        prnarray (arr, nelem);
    
    printf ("%d\n", arr[nelem]);        /* unwind outputting elements */
}

(where nelem is the number-of-elements in the array, technically not its "size" [unless it is an array of char])

Trace what happens if that function was called with:

int main (void) {
    
    int arr[] = { 1, 2, 3 },
        nelem = sizeof arr/sizeof *arr;
    
    prnarray (arr, nelem);
}

The easiest way is just make a table with the value of nelem. For example:

Winding-In

  • nelem == 3:

initial call from main()

    prnarray (arr, nelem);

then in the first function call, --nelem reduces the value of nelem by 1 before being evaluated by the if().

  • nelem == 2:

following the if() statement, the execution path is:

    if (--nelem > 0)                    /* wind-in (twice) until nelem == 0 */
        prnarray (arr, nelem);

  • nelem == 1:

then in the next call after --nelem, nelem == 1:

    if (--nelem > 0)                    /* wind-in (twice) until nelem == 0 */
        prnarray (arr, nelem);

  • nelem == 0

then in the next call, the last recursive call, the base case is hit because after --nelem, nelem == 0 so the test condition fails and the execution-path continues with:

    printf ("%d\n", arr[nelem]);        /* unwind outputting elements */

(the first element '1' is printed here)

Unwinding

What happens now?? We have reached the end of the function??

Execution will pick up after the function call that lead to this point. Where is that? The function call that lead to this point is the recursive call to prnarray() that lead to us being in the body of this function.

(under the hood each function call saves the base-pointer address on the function stack so when the function execution is done it knows where to resume execution in the calling function.)

  • nelem == 1

So when execution of the function where nelem == 0 ends, we pick up where we left off in the function call where nelem == 1 -- which is returning from the prior call to prnarray() If we look at the whole function where nelem == 1 (nelem == 2 on function entry) we pick up after the previous call to prnarray() one-level up in the recusrion:

void prnarray (int *arr, int nelem)
{
    if (--nelem > 0)                    /* wind-in (twice) until nelem == 0 */
+<----- prnarray (arr, nelem);
|   
+-->printf ("%d\n", arr[nelem]);        /* unwind outputting elements */
}

(the second element with value 2 is printed here)

So after the prior prnarray() unwinds, the only command left in the execution-path is printf() and the second element 2 is printed and the function ends and unwinds again with the same result:

  • nelem == 2

(3 on entry into the function) the execution-path is the printf() function

    printf ("%d\n", arr[nelem]);        /* unwind outputting elements */

(the third and final element with value 3 is printed here)

  • nelem == 3

was the original function call from main(), so now unwinding is complete and program execution picks up in main() after the call to:

    prnarray (arr, nelem);

and the program ends....

Thinking through the recursive function program execution-path and making a table is a good way to become comfortable with recursive function calls. (even if you are comfortable with them, when you get to functions making two or more recursive calls within the body of the function -- you will be right back to making a table and tracing the execution path). The branches in the program execution-path with multiple recursive calls to separate recursive functions will seem to expand with exponential complexity.

With this information, you should now be able to tweak your function and know where to look for the result to take place. Let me know if you have further questions.

这篇关于编写一个以数组和数组大小为参数的递归函数,打印该数组,不返回任何内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆