-1

Working through some exercise, and this loop behaviour is not as I expected:

void primeFunc(int &number){
    
    bool prime_check = false;

    for( int control = number; control > 1; --control){

        printf("\tcontrol = %d\n", control);

        for( int sub_control = control-1; sub_control > 1; --sub_control){

            printf("\t\tsub_control = %d\n", sub_control);

            if(control % sub_control == 0){
                prime_check = false;
                break;
            }
            else prime_check = true;
            // printf("\nPrime: div/quo :: %d/%d", control, sub_control);

        }
        if(prime_check == true){
            printf("\n%d", control);
        }
    }
}
// function call
int num = 5;
primeFunc(num); //<- clearly showing how parameter is passed to func argument ->

The output of the snippet above:

5       control = 4
                sub_control = 3
                sub_control = 2
        control = 3
                sub_control = 2

3       control = 2

2

How is 2 evaluating successfully here.

  • I exaplained it as control = 2; the outer for loop starts (control decrements to 1);
  • print(control=2) runs;
  • sub_control evaluates to 1; inner for loop exits

In this case, the outer for loop isnt even entered print(control=2) doesnt execute.

edit:

The question really is understanding how the number 2 evaluates with prime_check = true.

  • the for loop is not entered at all, looking at the output
emag_mI
  • 5
  • 2
  • You can't pass an rvalue to an lvalue-reference. How does that even compile? And why do you use printf for C++? – Eldinur the Kolibri Jun 29 '23 at 04:06
  • - `You can't pass an rvalue to an lvalue-reference` int &alias = (int) some_rval wont work? - using `printf`? for better readability - editing the question with how the function is called for better readability as well – emag_mI Jun 29 '23 at 04:17
  • Your edit makes it a whole different story. And no, I disagree. `printf` doesn't enhance readability at all. It's part of the C standard library and shouldn't be used in C++. I think `std::cout` is even more type-safe. It doesn't really matter, but I wouldn't use `printf`, even though it's valid. Your choice. I don't understand your question though. What did you not expect? – Eldinur the Kolibri Jun 29 '23 at 04:25
  • 1
    It is unclear what you don't like. Please show output you are expecting. – n. m. could be an AI Jun 29 '23 at 04:34
  • @Eldinur the Kolibri, n. m. will see y'all on Reddit - I have updated the question. Do have look, thanks – emag_mI Jun 29 '23 at 05:06
  • 1
    I still do not understand what you don't like. Can you *show* what output you expected? – n. m. could be an AI Jun 29 '23 at 05:18
  • With `printf("\tcontrol = %d\n", control);` the shown code cannot generate the shown output, with a blank `5` at the start of first line and no "control" nearby. Please provide a [mre], along with the output you expect in contrast to the actual output that code generates unexpectedly. – Yunnosch Jun 29 '23 at 05:29
  • [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – 463035818_is_not_an_ai Jun 29 '23 at 07:48

2 Answers2

1

The question really is understanding how the number 2 evaluates with prime_check = true.

the for loop is not entered at all, looking at the output

This is likely because we start the loop where control==2 with prime_check as still true from the previous loop execution where control==3. Because subcontrol = 2-1, and therefore sub_control > 1 fails, we never go into the sub_control loop at all... and execute printf("\n%d", control);.

jkerian
  • 16,497
  • 3
  • 46
  • 59
  • thanks @jkerian, this is my reasoning for how 3 checks out. `3 -> control-- => 2 -> sub_control = control-1 -> sub_control = 1 -> exit loop` I am still unclear on how 2 checks after this – emag_mI Jun 29 '23 at 05:23
  • The reason you see the print from prime_check on control:2 is that prime_check was never reset at the start of the control loop. It's STILL true from control:3. – jkerian Jun 29 '23 at 05:34
-2

--control decrememts control before you compare it to ">1",

I would use control--.

the same goes for how you are decrementing sub_control.

mgillett
  • 74
  • 8
  • 1
    What difference does that make for the output? – Eldinur the Kolibri Jun 29 '23 at 04:14
  • @emag_mI What do you even mean by that? "Execution logic for passed parameter 5 instead of 2". Can you include this in your question with what you expect to happen when parameter 5 is passed or when parameter 2 is passed? – Eldinur the Kolibri Jun 29 '23 at 04:42
  • thanks @mgillett, post-decrement didnt chnge loop control logic, no. a slightly less efficient control; outer-loop `for( int control = 2; control < number; control++){}` and inner-loop `for( int sub_control = 2; sub_control < control; sub_control++){}` now didn't print the execution logic for passed parameter `5` instead of `2`. Probably missing something on the nose, someone will call our attention to. – emag_mI Jun 29 '23 at 04:55
  • No, that' s not how a `for` loop works. Pre-increment or post-increment affects what the result of the expression is, but the `for` loop doesn't use that result. All that it cares about is the **value** of `control` when it evaluates `control > 1`; at that point the decrement has already been done, and the result is the same either way. `control--; std::cout << control << '\n'` and `--control; std::cout << control << '\n';` will do exactly the same thing. `std::cout << --control << '\n'; and `std::cout << control-- << `'\n'`;` will show different values. – Pete Becker Jun 29 '23 at 12:07