I am getting infinite loop using recursive function :(

Hello there,
Thank you for your time.
I am having a small trouble here , trying to print out an array using a recursive function, I think I solved like 90% of the problem ... (hopefully) :D
here is the question
Write a program that uses a random number generator to fill an array with 10 integers between 50 and 100 and calls a function forward that displays the content of the array recursively. The program then calls the function backward that displays the content of the array recursively but in a reverse order.


I wrote all the needed functions but I am getting a loop every time I look at the output
here is the cod I wrote:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <cstdlib>
using namespace std;
int i;
int array[10];

int forward(int array[] , int l = 0)
{

	if (l == 10)
		return array[10];

	else
	{
		cout << array[l+1];
	
	return forward(array , l);
	}
}

int backward(int array[] , int n = 10)
{
	 

	if ( n == 0)
		return array[0];

	else
		cout << array[n-1];
	return backward(array , n);
}
int main()
{
	
	for (int j = 0;j<10;j++)
	{

		i = rand() % 51 + 50;
		 array[j]=i;
	}

	forward (array,10);
	cout << endl;
	cout << endl;
	backward (array,10);
	cout << endl;
	return 0;
}
Last edited on
You're never incrementing l or n. Use the prefix operator.
Last edited on
I would prob use l+1 and n-1

1
2
3
4
5
6
7
8
9
10
11
12
13
// e.g.

int forward(int array[] , int l = 0)
{
	if (l == 10)
		return array[10]; // Edit : see whitenite's corrections below! (array ranges)
	else
	{
		cout << array[l+1]; // <= should this be just l ??
	
		return forward(array , l+1); // l+1 !!
	}
}


You don't need the increment/decrement operator as neither l nor n are reused later in the scope.

And avoiding the increment/decrement operator eliminates the danger of using l++ or n-- when you meant to use ++l and --n

Note the if you do use ++/-- it must be prefix version (pre-increment/decrement)

1
2
function(++n); // increment n to n+1 and then call function :-)
function(n++); // call function with n and then increment to n+1 :-( 


Andy

PS Running a recursive program that mis-uses post-increment, under the debugger, is a good way to find out what a stack overflow looks like!
Last edited on
You almost had it. Here is your program with the small adjustments.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// Recursive array.cpp : Defines the entry point for the console application.

#include <iostream>
#include <time.h>
#include <cstdlib>
using namespace std;
int i;
int array[10];

int forward(int array[] , int l)
{
	if (l == 9)
	{
		cout << array[9];
		return 0;
	}
	else
	{
		cout << array[l] << " ";
		forward(array , l+1);
	}
}

int backward(int array[] , int n)
{
	if ( n == 0)
	{
		cout << array[0];
		return 0;
	}
	else
	{
		cout << array[n] << " ";
		backward(array , n-1);
	}
}
int main()
{
	time_t t;
	srand((unsigned) time(&t));

	for (int j = 0;j<10;j++)
	{
		array[j] = rand()% 51 + 50;
	}
	cout << "Value in array going forward's, from array[0] to array[9]" << endl;
	forward (array,0);  // Starts the function with array[0]
	cout << endl;
	cout << endl;
	cout << "Value in array going backward's, from array[9] to array[0]" << endl;
	backward (array,9); // Starts the function at array[9]
	cout << endl << endl;
	return 0;
}
Last edited on
ascii , andywestken , whitenite1

THANK YOU GUYS VERY MUCH :)


ascii
I just noticed that .. thank you :D


andywestken
Thanks for telling me the difference between post and pre increment . I always thought they were same.


whitenite1
Thank you for the adjustments :)
closed account (zb0S216C)
Whitenite1, I've notice a few things:

Not all control paths within backward() and forward() return a value. Not only that, both routines could return void since the returned values are ignored.

As far as I can see, i was declared but remained uninitialized and unused.

whitenite1 wrote:
(unsigned) time(&t) (sic)

What wrong with static_cast? Or am I missing the point?

whitenite1 wrote:
rand()% 51 + 50 (sic)

I would've used parentheses here, like so: (rand() % 51) + 50.

I'm not knocking or anything, just highlighting the points of interest.

Wazzak
Last edited on
@Framework
Because it's recursive, the calling section in the function, going back to the function, doesn't return anything, so it throws a warning, that I think, can be ignored. The program doesn't know that it's recursive, just that it's leaving the function without a return. Concerning the srand((unsigned) time(&t));, I use that to seed the random number generator with each run. I've never used static_cast. Does that randomize numbers? Oh, sorry about not removing the 'int i;' in the code. I forgot to do it. The 'i' wasn't needed, because it just made it easier, to me, to see the random number being inserted into array[j]. Yes, you could write that with the parenthesis, and, of course, you may if you choose. You could also use array[j] = 50 + rand()% 51; with or without parenthesis. Your choice. All correct.
Don't worry, I do not feel you were knocking anything. You were just wondering why some programmers do things this way or another. Healthy attitude.
Not to show my ignorance or anything, but what does the
Wazzak
mean?
Why is it exactly that you dislike the post and prefix operators? I understand your point that in this case you don't actually need to change the value of l and n, but I don't see how they make things more confusing.

@whitenite, try not to post the answer for the OP, then they don't learn anything :/
The confusion I was referring to was the confusion between between ++i and i++, which is a common mistake for beginners. And one even experienced programmers are prone to fall foul to if they pick up the bad habit of using the i++ form regularly.

I don't dislike increment operators; but I do think they should be used when you're coding loops, etc. In recursion, I want to call the same function with i + 1, which is clearer to me if I code it as i + 1 rather than ++i.

Note that I also almost always use the ++i form.

As a rule, i++ should be avoided unles you really need post-increment behaviour. To avoid problems like those mentioned above. And post-increment operators can be less efficient than their pre-increment counterpart, for abstract data types, due to the way they're implemented.

The majority of coding standard I've read and worked to all make this same point: point 28 in Sutter and Alexandescu's book "C++ Coding Standards" is: "Prefer the canonical form of ++ and --. Prefer calling the prefix forms". Meyers makes the same point. As do many other people, e.g.

C++: Pre-increment v. Post-increment
Point: Favor Pre-increment over post-increment whenever possible.
http://syamsulhasran.blogspot.com/2008/12/c-pre-increment-v-post-increment.html

Some people say the choice or i++ versus ++i is just a matter of style. But it is not. It is a matter of safety, efficiency and consistency.

I find there is far, far too much use of the post-increment forms in the posts on this forum!!

Andy
Last edited on
closed account (zb0S216C)
whitenite1 wrote:
Wazzak
"mean?"

My nickname. It appears on the bottom of all of my posts. A signature, really.

Wazzak
Last edited on
closed account (1vRz3TCk)
Framework,

Every time I see Wazzak, my brain reminds me of the word wazzock[1], which was used widely in my youth.

[1] http://en.wiktionary.org/wiki/wazzock
Fair point, I've pretty much always used the prefix form just because that was how I learned it, but I hadn't realized that it was actually more efficient :o

As far as working with abstract data types, if you meant classes you'll usually be overloading the ++ and -- operators most of the time anyways, so how efficiently they're implemented is up to the coder, isn't it?
Last edited on
Implementing the post-increment forms require you to copy the current object, so you can return a copy of it in its current state, and then perform the increment. So you incur an extra copy.

The pre-increment form does not require the copy. You just act on the current instance.

In a lot of cases the cost of the copy will be small. But it does mean that the post-increment operator will always at keast a little bit less efficient than the pre-increment equivalent. Sometimes much less efficient. And never more efficient!
Last edited on
Okay, but a lot of times you'll just be incrementing a variable so you can make the body of the function look like this:
1
2
++(this->length);
return (this->length)-1;

I see your point in more complicated situations however.
The final part of argument is consistency.

It's better to do things in the same way, it at all possible. So even though post-increment is often no less efficient than pre-increment, it's better to get into the habit of using the pre-increment form so you don't suffer on the occasions when it does matter. I find the times I actually need post-increment are pretty infrequent.

Note that the post-increment operator returns a new instance of the class, so you'll be firing a constructor. Your code fragment only make sense it there is a constructor which takes an int and length is the only member variable.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Example
{
private:
    int m_len;

public:
    Example():: m_len(0) {}
    Example(int len):: m_len(len) {}
    ...

    Example operator++(int); // post-increment
    Example& operator++(); // pre-increment

    ...
};

...

// post-increment must return a new instance
Example Example::operator++(int)
{
    ++m_len; // could use post-increment here, with no effect
    return Example(m_len - 1);
}

// pre-increment works directly on the instance
Example& Example::operator++()
{
    ++m_len; // could use post-increment here, with no effect
    return *this;
}

Last edited on
Argh! Guess I wasn't paying enough attention to remember I need to actually return an object :/ Any how, I always use pre-increment anyways, so no harm done :) Good explanation anyways.
Topic archived. No new replies allowed.