c++ code stuck on function call

Discussion in 'Mac Programming' started by nico és..., Sep 7, 2009.

  1. nico és... macrumors newbie

    Joined:
    Sep 7, 2009
    #1
    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;
    }
    
     
  2. Sander macrumors 6502

    Joined:
    Apr 24, 2008
    #2
    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
     
  3. autorelease macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #3
    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.
     
  4. nico és... thread starter macrumors newbie

    Joined:
    Sep 7, 2009
    #4
    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!
     
  5. nico és... thread starter macrumors newbie

    Joined:
    Sep 7, 2009
    #5
    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;
    }
     
  6. nico és... thread starter macrumors newbie

    Joined:
    Sep 7, 2009
    #6
    thanks

    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
     
  7. nico és... thread starter macrumors newbie

    Joined:
    Sep 7, 2009
    #7
    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?
     
  8. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #8
    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.
     
  9. nico és... thread starter macrumors newbie

    Joined:
    Sep 7, 2009
    #9
    thanks lee!

    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;
    }
    
     
  10. Sander macrumors 6502

    Joined:
    Apr 24, 2008
    #10
    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.
     
  11. nico és... thread starter macrumors newbie

    Joined:
    Sep 7, 2009
    #11
    Very nice!

    I was wondering why it never output the string before it got into the function. Thanks!
     

Share This Page