Unable to fully understand application

Hello there. I have started learning C++ rather recently and I'm using the book 'C++ without fear' by Brian Overland. I have been able to do Exercise 4.3.1:

[Rewrite the main function for Example 4.3 so that it prints the
prompt message “Enter a number (0 = exit) and press ENTER.” The program
should call get_divisors to show the prime factorization and then prompt the
user again, until he or she enters 0. (Hint: If you need to, look at the code for
Example 4.2, on page 90.)]

However, I do not understand exactly how it works. Specifically, how the process runs without a particular "return;" (the one pointed out in the code below). I have tried running the program without that and it gives strange results. For example, it tells me that 4 in prime factors is 2, 24; 8 in prime factors is 2, 2, 248. My problem is not getting the code to work, but rather understanding exactly what the application is doing when I remove that "return;". I cannot make sense of why these results are produced when I run the process through in my head.

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
#include <iostream>
#include <cmath>
using namespace std;

void get_prime(int n);

int main() {
    int a;
    
    while(true) {
    
    cout << "Enter a positive integer (0 = exit) and press ENTER: ";
    cin >> a;
    
    if (a == 0) {
          return 0;
          }
    
    while (a < 0) {
          cout << "Your number was not positive, please re-enter: ";
          cin >> a;
          }
          
    get_prime(a);
    
    cout << endl << endl;
    system("PAUSE");
    cout << endl << endl;
    }
}

void get_prime(int n) {
     int i;
     double ns = sqrt(n);
     
     for (i = 2; i<=ns; i++) {
         
         if (n%i==0) {
         cout << i << ", ";
         get_prime(n/i);
         return; //Why does this return statement have to be here?
                 //I know it works wrong without it, but why?
         }
     }
     cout << n;
}


Thank you for reading.
Leaving the method at that point breaks out of that for loop and gets out of that method (which is incidentally recursive).

Have a google of 'recursive functions'.

Personally, i dont like using returns in void methods, but it can be useful at times.
Last edited on
Well, I do know how recursive functions work. My problem here is understanding how the outputs are obtained without the "return;" statement.

Put another way, how exactly does the computer obtain 24 to output "2, 24" when I enter 4 and obtain 248 to output "2, 2, 248" when I enter 8?

Thanks.
If you adjusted the indentation so that the code was properly indented it may be more clear why that return statement is required for a correct result.
I know why the "return;" statement is needed, that one I can visualise:

NOTE: This part in the braces is just me showing that I know why the "return;" statement is needed so nobody else will need to tell me why it's needed. If you don't want to see, skip it and go to the end of this post to find out what I am asking for help for.

{
The user inputs a positive integer (Let's use 100 for illustration)
> It gets stored as 'a' in the main function
> It is passed to the get_prime function and is stored as 'n' in get_prime function

First time get_prime is run
> get_prime function declares 'i' and calculates square root of 'n' and stores it as 'ns' (In this case ns == 10 as a double type variable)
> The 'for' loop initialises 'i' as 2 and then checks if 'i' is lesser than or equals to 'n'
> It is (2 < 10), so it checks if 'n' is divisible by 'i' (n%i==0)
> It is, so "2, " is printed and get_prime is run again but with 'n' set to 100/2 or 50

Second time get_prime is run
> Function does the calculation and initialising of respective variables
> The 'for' loop initialises 'i' as 2 and checks the same way.
> 2 < 50, so it checks if (50 % 2 == 0)
> It is, so "2, " is printed again and get_prime is run again but with 'n' set to 50/2 or 25

Third time get_prime is run
> Function does the usual stuff mentioned above
> This time, when it checks if (25 % 2 == 0), it is not, so 'i' becomes 3 (i++) and it checks again (25 % 3 == 0)
> It is not, so loop continues until 'i' is equal to 5
> Then "5, " is printed and get_prime is run again but with 'n' set to 25/5 or 5

Fourth time get_prime is run
> Blah blah blah
> 'i' becomes 3 then i is no longer lesser than or equals to n (5)
> 'for' loop is no longer run and fourth get_prime reaches "cout << n;"
> "5" is printed and fourth get_prime returns to third get_prime at the point where the "return;" statement is about to be executed

Back to third get_prime
> "return;" is executed going to second get_prime at point where another "return;" statement is about to be executed

And so on until "return;" in the first get_prime is executed and control is given back to main. All that has been printed so far is "2, 2, 5, 5" which is absolutely correct.

So, you can see that this program works and I know how it works.
}

What I want to know is the whole process that the computer undertakes when that "return;" statement is missing and how it comes up with numbers like 24 and 248 in the examples mentioned previously. That is the one I cannot visualise.

Thank you for reading.
I'm confused as to why you are confused?
I'm wanting to understand how the wrong code (without that "return;" statement) works to produce the wrong results mentioned above. Since the computer only follows exactly what it's been told to do, I want to know exactly what I am telling it to do when I use that wrong code. I know it sounds strange but I'm very interested in knowing why and how these incorrect results are produced.

Thanks.
Last edited on
What I mean is, you seem to be able to follow the code perfectly when that return statement is there, but as soon as that return statement is gone you are unable to follow the code and you're not explaining what has you confused.
I want to be able to follow the code without that return statement. That is all I am confused about: how it comes up with those numbers.
I suggest you remove the return in question, and step through the code in your debugger.
I do not understand how you are confused without the return statement, and despite my asking over and over you will no explain why you are confused. I cannot help you.
how it comes up with numbers like 24 and 248

There are a couple of points to note. One is that those aren't the actual numbers, they really mean 2, 4, 2, 4 and 8. The lack of whitespace means the numbers are printed immediately adjacent to one another, making them hard to read and interpret correctly.

The other point, related to the above, is that there are two places where a value is printed in the function get_prime(), one is inside the loop, the other is just before the closing brace of the function.

Perhaps things would be clearer with some additional text to make it clear which value is output from which line.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void get_prime(int n) 
{
     int i;
     double ns = sqrt(n);
     
     for (i = 2; i<=ns; i++) 
     {    
         if (n%i==0) 
         {
             cout << i << ", ";
             get_prime(n/i);
             // return; // this line deliberately disabled
         }
     }

     cout << " (" << n << ") ";
}


Enter a positive integer (0 = exit) and press ENTER: 4
2,  (2)  (4)



Enter a positive integer (0 = exit) and press ENTER: 8
2, 2,  (2)  (4)  (8)

Last edited on
Chervil wrote:
There are a couple of points to note. One is that those aren't the actual numbers, they really mean 2, 4, 2, 4 and 8. The lack of whitespace means the numbers are printed immediately adjacent to one another, making them hard to read and interpret correctly.


Ah, I see. It makes sense now. Thank you very much.

L B wrote:
I do not understand how you are confused without the return statement, and despite my asking over and over you will no explain why you are confused. I cannot help you.


Well, thanks for coming back to the post repeatedly, but I was, and still am, confused about why you were confused about what I was confused about. I am quite sure that I have explained it in previous posts.

However, thankfully, Chervil was able to understand my question and I can close this thread now.
Topic archived. No new replies allowed.