Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

nico és...

macrumors newbie
Original poster
Sep 7, 2009
9
0
I'm not sure why, but this code compiles fine and runs until it reaches my function call (array_change). After debugging I noticed if I comment it out, the rest of the code runs. Why is this function call not able to initiate? Can anyone pls help?

Code:
Header File: recursion.h

#ifndef RECURSION_H
#define RECURSION_H

#include <iostream>
#include <string>
using namespace std;

const int SIZE = 10;
int array[SIZE][SIZE];

void array_change(int row, int col)
{
	if(row > 9)
		return;
	if(col > 9)
		row++;
	
	while(col > 0 && row < 9)
	{
		array[row][col] = array[row-1][col] + array[row-1][col-1];
		array_change(row,col+1);
	}
}

#endif


Main File: main.cpp

#include "recursion.h"

int main ()
{
	void array_change(int row, int col);		// function prototype
	
	for(int i=0 ; i < SIZE ; i++)
	{
		for(int j=0 ; j < SIZE ; j++)
		{
			array[i][j] = 1;
			cout << " " << array[i][j];
		}
		cout << endl;
	}
	
	cout << "recursion!";
	
	int row=1,col=1;
	array_change(row,col);
	
	for(int i=0 ; i < SIZE ; i++)
	{
		for(int j=0 ; j < SIZE ; j++)
		{
			cout << " " << array[i][j];
		}
		cout << endl;
	}
	
	cout << "the end!";
	return 0;
}
 
Why would your while() loop (in the array_change() function) terminate..?

Also, think what needs to happen if col > 9, besides increasing row.

Good luck,
Sander
 
A couple things, style-wise:
1. Remove the function prototype from main. Technically it works, but function prototypes should (for the most part) only go in header (.h) files.
2. No functions should ever be written in a .h file. I would recommend you move the code for array_change() into main.cpp or a second .cpp file. Header files should only contain function prototypes and other declarations that aren't code.

If you're just learning, I'd recommend putting array_change() in main.cpp, above main(). It's tricky to share a global 2-dimensional array between files and requires the use of 'extern' declarations, as well as pointers.

3. Your program is looping forever in array_change(). It's not clear what the intended purpose is, but you should rethink it.
 
Why would your while() loop (in the array_change() function) terminate..?

Also, think what needs to happen if col > 9, besides increasing row.

Good luck,
Sander

Thank you for the reply, I apologize bc I posted version 1.0! I have updated to 2.0 now. It still hangs up before it enters the function though. It never prints out "Recursion!" unless I delete the function call. I added some endl before the "recursion" output and it prints them, just not the string. I am a beginner and it is above me. Thanks for the help!
 
version 2.0

Code:
Task: Write a recursive function that changes the contents of a 2D array.
 The main routine creates the array and fills it with 1's.
 Rules:
 1st row - do nothing
 2nd and subsequent rows
 1st column - do nothing
 2nd and subsequent columns - replace existing value with value of element above + value
 of element of above and one position to the left
 Hint:
 I used two recursive cases – one for the end of a row, one for the middle of a row
 If the row or column is 0, call the function with 1, 1 for the row and column
 --------------------------------------------------------------------------*/

// recursion.h

#ifndef RECURSION_H
#define RECURSION_H

#include <iostream>
#include <string>
using namespace std;

const int SIZE = 10;
int array[SIZE][SIZE];

void array_change(int row, int col);	// function prototype

#endif


// main.cpp

#include "recursion.h"

void array_change(int row, int col)
{
	if(row > 9)
		return;
	if(col > 9)
	{	
		row++;
		col = 1;
	}
	
	while(col > 0 && row < 9)
	{
		array[row][col] = array[row-1][col] + array[row-1][col-1];
		array_change(row,col+1);
	}
}


int main()
{
	int row=1,col=1;
	
	for(int i=0 ; i < SIZE ; i++)
	{
		for(int j=0 ; j < SIZE ; j++)
		{
			array[i][j] = 1;
			cout << " " << array[i][j];
		}
		cout << endl;
	}
	
	cout << "recursion!";
	
	array_change(row,col);
	
	for(int i=0 ; i < SIZE ; i++)
	{
		for(int j=0 ; j < SIZE ; j++)
		{
			cout << " " << array[i][j];
		}
		cout << endl;
	}
	
	cout << "the end!";
	return 0;
}
 
thanks

A couple things, style-wise:
1. Remove the function prototype from main. Technically it works, but function prototypes should (for the most part) only go in header (.h) files.
2. No functions should ever be written in a .h file. I would recommend you move the code for array_change() into main.cpp or a second .cpp file. Header files should only contain function prototypes and other declarations that aren't code.

If you're just learning, I'd recommend putting array_change() in main.cpp, above main(). It's tricky to share a global 2-dimensional array between files and requires the use of 'extern' declarations, as well as pointers.

3. Your program is looping forever in array_change(). It's not clear what the intended purpose is, but you should rethink it.

thank you for the advice! I am fairly new to c++, and kindof understand global variables from a visual basic course. I thought maybe the function should be in the main file, but outside of it ;) thanks for confirming some standards
 
Think?

WShe'Shen I reach array[9][9] I want to return to main, so I think my problem is when I call return at my base case, it just returns me to it's call (not main but within my while loop). How can I return to main at that point? If I return array[1][1] will it see that it was that main was the first function call and return there?
 
before you're even worrying about recursion, you need to write down on paper how this algorithm should work. If you're adding values from the previous row and current column, and the previous row and previous column, you need to ensure that both the row and the column are 1 or greater. You also need to make sure they are less than or equal to 9.

Once you have an idea of how to handle checking these things, then start worrying about the recursion.

First, write out your base cases. When does recursion stop, and what will be returned when it does? (In this case there's no return... so... you need to do something else). What is your recursive case(s)? How will the parameters be modified before/at the time of making the recursive call?

You are passing row and col to array_change by value. You're needing to alter the state inside array change. This isn't going to work. You'll need to pass a pointer or pass by reference so these can be modified in array_change, and this change can be passed back to the calling stack frame.

Right now, the best thing to do is erase array_change completely, write everything down on paper, then start writing it again.

-Lee

EDIT: Scratch the bit about passing my reference. Looking more closely the while is totally unnecessary. The state of the recursion can be held in the arguments, and they can be passed by value.

EDIT 2: array_change should be pretty simple. However, as i said before, delete everything you have now (the one line that sets array[row][col] you can keep a copy of, that's the only thing that survived my rewrite). I make no guarantees, but this was the output i got:
Code:
   1   1   1   1   1   1   1   1   1   1
   1   2   2   2   2   2   2   2   2   2
   1   3   4   4   4   4   4   4   4   4
   1   4   7   8   8   8   8   8   8   8
   1   5  11  15  16  16  16  16  16  16
   1   6  16  26  31  32  32  32  32  32
   1   7  22  42  57  63  64  64  64  64
   1   8  29  64  99 120 127 128 128 128
   1   9  37  93 163 219 247 255 256 256
   1  10  46 130 256 382 466 502 511 512

My implementation of array_change is about 10 lines long, and most of them are checking the base cases.
 
thanks lee!

before you're even worrying about recursion, you need to write down on paper how this algorithm should work. If you're adding values from the previous row and current column, and the previous row and previous column, you need to ensure that both the row and the column are 1 or greater. You also need to make sure they are less than or equal to 9.

Once you have an idea of how to handle checking these things, then start worrying about the recursion.

First, write out your base cases. When does recursion stop, and what will be returned when it does? (In this case there's no return... so... you need to do something else). What is your recursive case(s)? How will the parameters be modified before/at the time of making the recursive call?

You are passing row and col to array_change by value. You're needing to alter the state inside array change. This isn't going to work. You'll need to pass a pointer or pass by reference so these can be modified in array_change, and this change can be passed back to the calling stack frame.

Right now, the best thing to do is erase array_change completely, write everything down on paper, then start writing it again.

-Lee

EDIT: Scratch the bit about passing my reference. Looking more closely the while is totally unnecessary. The state of the recursion can be held in the arguments, and they can be passed by value.

EDIT 2: array_change should be pretty simple. However, as i said before, delete everything you have now (the one line that sets array[row][col] you can keep a copy of, that's the only thing that survived my rewrite). I make no guarantees, but this was the output i got:
Code:
   1   1   1   1   1   1   1   1   1   1
   1   2   2   2   2   2   2   2   2   2
   1   3   4   4   4   4   4   4   4   4
   1   4   7   8   8   8   8   8   8   8
   1   5  11  15  16  16  16  16  16  16
   1   6  16  26  31  32  32  32  32  32
   1   7  22  42  57  63  64  64  64  64
   1   8  29  64  99 120 127 128 128 128
   1   9  37  93 163 219 247 255 256 256
   1  10  46 130 256 382 466 502 511 512

My implementation of array_change is about 10 lines long, and most of them are checking the base cases.

Yeah, I totally see that the while is ridiculous and pointless. Idk why it slipped my sight for so long. I took it out and modified a few other things and got it working smoothly. Thanks for the help with spotting it! I start working with pointers this week, I hear they can be complex. We'll see ;)

Here is my changed function:
Code:
int array_change(int row, int col)
{
	if(row == 9 && col == 10)
		return 0;
	else if(col > 9)
	{	
		row++;
		col = 1;
	}
	
	if(col > 0 && row < 10)
	{
		array[row][col] = array[row-1][col] + array[row-1][col-1];
		array_change(row,col+1);
	}
	return 0;
}
 
By the way, don't get fooled by the "recursion" string not being printed. That's probably because the output was "buffered" (for performance reasons, the system doesn't immediately print out each character but collects them to be printed in "bursts"). Had you put an endl after it, that would have forced "flushing" the buffer.

In other words, what was going on is that the string "recursion" was queued to be written to the screen, but your program got stuck before it ever got a chance to be written out.
 
Very nice!

By the way, don't get fooled by the "recursion" string not being printed. That's probably because the output was "buffered" (for performance reasons, the system doesn't immediately print out each character but collects them to be printed in "bursts"). Had you put an endl after it, that would have forced "flushing" the buffer.

In other words, what was going on is that the string "recursion" was queued to be written to the screen, but your program got stuck before it ever got a chance to be written out.

I was wondering why it never output the string before it got into the function. Thanks!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.