在c++中通过递归打印数组

Printing an array by recursion in C++

本文关键字:递归 打印 数组 c++      更新时间:2023-10-16

我想写一个递归打印数组的函数。

我写了三个函数,但它们在原理上似乎是一样的。

void printArray0( int theArray[], int theSize, int theIndex = 0 )
{
    cout << theArray[theIndex] << ' ';
    if ( ++theIndex != theSize ) printArray0( theArray, theSize, theIndex );
    else cout << endl;
}
void printArray1( int theArray[], int theElementLeft )
{
    cout << *theArray << ' ';
    if ( theElementLeft != 1 ) printArray1( theArray+1, theElementLeft-1 );
    else cout << endl;
}
void printArray2( int theArray[], int theSize )
{
    static int myIndex = 0;
    cout << theArray[myIndex] << ' ';
    if ( ++myIndex != theSize ) printArray2( theArray, theSize );
    else cout << endl;
}

那么它们之间有显著差异吗?

如果有,哪个函数是最快的,哪个是最安全的?

我希望我能学习别人的经验:)

第三个不等同于前两个,因为它使用静态变量来保持当前状态。这是一件糟糕的事情(想象一下在多个线程中并发地运行这个函数,看看为什么)。这种方法之所以有效,是因为每次调用函数都不会有一个以上的递归调用。例如,试图在二叉树的递归遍历中保持静态状态将会失败得很惨。这就是为什么当前状态应该通过参数传递给递归函数,而不使用静态或成员上下文。

前两个版本之间应该没有性能差异,因为它们的时间将由数据输出支配。

我会像这样改变第二个函数的签名

void printArray1( int *theArray, int theElementLeft )

,因为您从未将theArray用作数组,而仅用作指针。从技术上讲,这并不重要,因为数组无论如何都会"衰减"为指针,但我认为这将略微提高可读性。

函数0和1同样安全1

函数2在多线程环境中是不安全的,因为它使用了静态变量。此外,对该函数的后续调用将从上次调用"停止"的地方开始,因为myIndex永远不会在任何地方重新初始化为零。


1我个人更喜欢函数1的风格而不是函数0。函数0在使用预增量(if ( ++theIndex != theSize ))方面很聪明,在我看来,这种聪明会妨碍未来的维护。有副作用的情况,我建议你尽量避免。

它们都没有多大意义,没有理由为什么有人会使用递归来实现这一点。第一个版本可能是最不糟糕的,因为它最容易阅读。

static版本是最危险的,因为它不是线程安全的。使用静态使得整个递归(甚至更)没有意义。

一般来说,很少有情况下递归是有意义的,这不是其中之一。这三个版本都是危险的,因为不能保证在参数不正确时递归会停止。这三种版本都将比普通循环消耗更多的RAM内存,并且它们将执行得更慢,同时也使程序的可读性大大降低。您的程序很容易发生堆栈溢出。

编译器通常不会有效地优化递归。它们是否这样做可能取决于你是否使用"尾部递归"。

作为旁注,你的编码&缩进样式不可读且不安全。在if/else语句后面的每一行都使用一个新行,并且始终对每个if/else语句使用{}